Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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
1  
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? –  rm -rf Apr 4 '13 at 21:13
    
@BoLe Yeah that works! I ended up using ImageMultiple to obtain the desired image with no lines. Thanks! –  Tinza123 Apr 4 '13 at 21:14
    
@DanielLichtblau In most cases the shape is irregular, so the polygonalization may be quite slow? –  Tinza123 Apr 4 '13 at 21:15
show 2 more comments

4 Answers

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@"http://i.stack.imgur.com/Pq6JZ.png";
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
add comment

Also,

The standard setup:

im = Import["http://i.stack.imgur.com/Pq6JZ.png"];
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
1  
Again, short and sweet. That gets my vote. –  Daniel Lichtblau Apr 5 '13 at 14:06
add comment

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["http://i.stack.imgur.com/Pq6JZ.png"];
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] –  rm -rf Apr 5 '13 at 13:50
add comment

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

m = Import["http://i.stack.imgur.com/Pq6JZ.png"];
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}}}; –  rm -rf Apr 5 '13 at 13:59
add comment

Your Answer

 
discard

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.