It is known that EdgeDetect can find image edges in an image. Suppose the image edges consists of sets of lines. Can the detected edge line near the mouse pointer be highlighted as spline/bezier when mouse moves over, so that i can change the bezier shape by drag the mouse?

(manually highlighting is time-consuming and not accurate, so I want to automatically highlight some part of the edges first, then I can manually change it.)

Update 2014/10/15:

bobthechemist's answer solve part of the question for contour image. Can that be possible when mouse click some position of the grayscale image or true color image?

enter image description here

Here is my code learning from bobthechemist, but it doesn't work. why?

i = ExampleData[{"TestImage", "Lena"}];
ia = ImageData[i, Interleaving -> False][[2]];
im = EdgeDetect[i, 5];
imm = MorphologicalComponents[im];
{n, m} = Dimensions@imm;
trans[{x_, y_}] := {Max[1, Min[n, Floor[n - y] + 1]], Max[1, Min[m, Floor@x + 1]]};

    ImageCompose[Image[ia], Graphics[ListLinePlot[ncurve]]], 
    {"MouseClicked" :> 
      (ncurve = Position[imm, imm[[##]] & @@ trans@(MousePosition[] /. None -> {0, 0})])}]]

There must be some grammar issue for the last line as it raised two error information:

Union::normal: Nonatomic expression expected at position 1 in Union[ncurve$3420].

ListLinePlot::lpn: ncurve$3420 is not a list of numbers or pairs of numbers.

The result is expected that when mouse click at the grayscale image, the corresponding edge found by MorphologicalComponents at the position should be highlighted or plotted.


1 Answer 1


I think you are asking for a rather sophisticated project in this question, and it is probably too broad. However, here's one way to approach the highlighting of lines.

im = EdgeDetect[ExampleData[{"TestImage", "Lena"}], 5];
imm = MorphologicalComponents[im];
trans[{x_, y_}] := {Max[1, Min[n, Floor[n - y] + 1]], 
   Max[1, Min[m, Floor@x + 1]]};
rep[mat_, val_Integer] := If[val == 0, mat, mat /. {val -> 1000}];
{n, m} = Dimensions@imm;
  rep[imm, imm[[##]] & @@ 
    trans@(MousePosition["Graphics"] /. None -> {0, 0})], 
  Frame -> False, ImageSize -> 800]

enter image description here

Don't expect high response times from this code, especially if your images are large. What I've done here is use MorphologicalComponents to create a matrix of connections. Then I stole copiously from this answer to convert a Dynamic@MousePosition@"Graphics" into a number that corresponds to the lines in the image. (Note, there are Union@Flatten@imm lines or connections in the image.) rep is there just to avoid the screen wonking out when it tries to replace all the zero values with my highlighter color.

It should be possible to alter rep to remove the MatrixPlot artistic shading of Lena; however, that would come with a decent performance hit with the code as written. Extracting an interpolating BSpline from the highlighted portion of the image will have to wait until after lunch.

Lunch is over - now get the points for each of the lines found from MorphologicalComponents. I'm also converting from Image coordinates to plotting coordinates:

lenapts = {#[[1]], m - #[[2]]} & /@ (Reverse /@ Position[imm, #]) & /@
ListPlot[lenapts, AspectRatio -> 1]

Mathematica graphics

Last, we can turn each of these (213 in my case) lines into BSpline to do whatever it is you want to do. Warning, though, some of them are funky as shown below.

Graphics@(BSplineCurve /@ lenapts)

Mathematica graphics

  • $\begingroup$ Thank you, bobthechemmist. You really give me very useful hints. $\endgroup$
    – xibinke
    Oct 14, 2014 at 14:31
  • $\begingroup$ @xibinke glad I could help. If this answer addresses the main points of your question, please consider accepting my answer. $\endgroup$ Oct 14, 2014 at 14:48
  • 1
    $\begingroup$ I've voted your post. But I don't know how to accept it. Though it's an inspiring answer, but still not a perfect one. $\endgroup$
    – xibinke
    Oct 15, 2014 at 14:15
  • $\begingroup$ Gotcha. Can you help me to solve the updated question? $\endgroup$
    – xibinke
    Oct 15, 2014 at 15:17
  • $\begingroup$ @xibinke I am going to take a shot at it, but I need to wait until I have some free time. Sadly, my employer doesn't pay me to hand out here (wish they did...) $\endgroup$ Oct 15, 2014 at 15:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.