Mathematica Stack Exchange is a question and answer site for users of Mathematica. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have an image with several disconnected components, and I want to find all the components which have intersections with some designated lines which I generated previously. The image: enter image description here

And the line is

{{{37.7754, 1001.}, {38.862, 0.}}, {{0., 442.679}, {832., 437.26}}}

The combined image looks like this:

enter image description here

share|improve this question
DeleteSmallComponents (try 10, then 100, or more) would take care of it here, since the bigger components are connected anyway. – BoLe Apr 4 '13 at 19:50
If you can polygonalize the image components then it should be straightforward to test for line-intersect-polygon (I think those are called "stabbing queries", but the kind that do not involve police investigations). – Daniel Lichtblau Apr 4 '13 at 20:04
How do the coordinates of the line correspond to the pixels? – R. M. Apr 4 '13 at 21:13
@BoLe Yeah that works! I ended up using ImageMultiple to obtain the desired image with no lines. Thanks! – zhengbli Apr 4 '13 at 21:14
@DanielLichtblau In most cases the shape is irregular, so the polygonalization may be quite slow? – zhengbli Apr 4 '13 at 21:15

You can get the labels for the individual components using MophologicalComponents and simply multiply by the binarized line plot to get the labels of the components that intersect:

im = Import@"";
pts = {{{37.7754, 1001.}, {38.862, 0.}}, {{0., 442.679}, {832., 437.26}}};
line = Binarize@Graphics[{White, Line /@ pts}, Background -> Black, ImageSize -> (ImageDimensions@im)];

labels = MorphologicalComponents[im];
intersect = Rest@Union@Flatten[labels ImageData@line]
(* {4, 5} *)

You can plot only the intersecting components and overlay the lines with:

blobs = Colorize[labels, ColorRules -> (Map[# -> ColorData[31]@# &, intersect] ~Join~ {_ -> Black})];
ImageAdd[blobs, line]

enter image description here

share|improve this answer


The standard setup:

im = Import[""];
pts = {{{37.7754, 1001.}, {38.862, 0.}}, {{0., 442.679}, {832., 37.26}}}; 
line = Binarize@Graphics[{White, Line /@ pts}, Background -> Black, 
                                                          ImageSize -> (ImageDimensions@im)];

and then just:

Rest@Union@Flatten@Pick[MorphologicalComponents@im, ImageData@line, 1]

(*{4, 5}*) 
share|improve this answer
Again, short and sweet. That gets my vote. – Daniel Lichtblau Apr 5 '13 at 14:06

This borrows heavily from @rm -rf at least for the start. Also it is not as clean. It might still be of interest in terms of determining and selecting specific image components.

im = Import[""];
pts = {{{37.7754, 1001.}, {38.862, 0.}}, {{0., 442.679}, {832., 
    437.26}}}; line = 
 Binarize@Graphics[{White, Line /@ pts}, Background -> Black, 
   ImageSize -> (ImageDimensions@im)];

Now remove filled in areas of the components.

im2 = EdgeDetect[im];

Next create an averaged image of this and the lines (I'm sure there is a Cleaner way to do this part).

im2 = EdgeDetect[im];
data = ImageData[im2];
ldata = ImageData[line];
datasum = (data + ldata)/2;
totalImage = Image[datasum];

The point is that we now have large values exactly at the crossings of those lines with image components. We can extract those as below.

mb = MorphologicalBinarize[totalImage, {.9, .99}];

We now get the components of both the original image and this very sparse one comprised only of the intersection points.

m1 = MorphologicalComponents[im];
m2 = MorphologicalComponents[mb];

We can use the second one to tell us which components from im are of interest (that is, intersect the lines).

intersectedComps = 
 Union[Select[Flatten[m1*Unitize[m2]], # >= .99 &]]

(* Out[129]= {4, 5} *)

Now we show the image with only these components 9again, there must be a better way...)

Image[Map[KroneckerDelta[4 - #] + KroneckerDelta[5 - #] &, m1, {2}]]

enter image description here

share|improve this answer
You can replace the averaging step and the MorphologicalBinarize step with just ImageMultiply[im2, line] – R. M. Apr 5 '13 at 13:50

Thanks guys. This is my solution inspired by @BoLe:

m = Import[""];
lines = {{{37.7754, 1001.}, {38.862, 0.}}, {{0., 442.679}, {832.,437.26}}};
deleted = DeleteSmallComponents[Show[m, Graphics[{White, Thick, Line /@ lines}]]];
m = ImageMultiply[m, deleted]
share|improve this answer
This is not a good or robust solution because you lose control with DeleteSmallComponents. To see what I mean, look at what result you get with this if your line was instead lines = {{{37.7754, 1001.}, {38.862, 0.}}, {{0., 490.679}, {832., 490.26}}}; – R. M. Apr 5 '13 at 13:59

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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