7

I've got a question regarding the following scenario. As I post-process an image, I gained a contour, which is unfortunately twice connected as you can see at the bottom line. To make it obvious what I want is just the outter line. Therefore I zoomed in and marked the line, i want of the large image.

What I want from this selection is only the outter part, which I've marked as green in the next picture. Sorry for my bad drawing skills. ;)

I am using MatLab with the IPT. So I also tried to make out with bwmorph and the hbreak option, but it threw an error.

How do I solve that problem? If you were successful could you please tell me a bit more about it? Thank you in advance!

Sincerely

mchlfchr
  • 3,998
  • 4
  • 26
  • 35

2 Answers2

2

It seems your input image is a bit different than the one you posted, since I couldn't directly collect the branch points (there were too many of them). So, to start handling your problem I considering a thinning followed by branch point detection. I also dilate them and remove from the thinned image, this guarantees that in fact there is no connection (4 or 8) between the different segments in the initial image.

f = im2bw(imread('http://i.imgur.com/yeFyF.png'), 0);
g = bwmorph(f, 'thin', 'Inf');
h = g & ~bwmorph(bwmorph(g, 'branchpoints'), 'dilate');

Since h holds disconnected segments, the following operation collects the end points of all the segments:

u = bwmorph(h, 'endpoints');

Now to actually solve your problem I did some quick analysis on what you want to discard. Consider two distinct segments, a and b, in h. We say a and b overlap if the end points of one is contained in the other. By contained I simply mean if the starting x point of one is smaller or equal to the other, and the ending x point is greater or equal too. In your case, the "mountain" overlaps with the segment that you wish to remove. To determine each of them you remove, consider their area. But, since these are segments, area is a meaningless term. To handle that, I connected the end points of a segment, and used as area simply the interior points. As you can clearly notice, the area of the overlapped segment at bottom is very small, so we say it is basically a line and discard it while keeping the "mountain" segment. To do this step the image u is of fundamental importance, since with it you have a clear indication of where to start and stop tracking a contour. If you used the image has is , you would have trouble determining where to start and stop collecting the points of a contour (i.e., the raster order would give you incorrect overlapping indication).

To reconstruct the segment as a single one (currently you have three of them), consider the points you discarded from g in h, and use those that doesn't belong to the now removed bottom segment.

mmgp
  • 18,901
  • 3
  • 53
  • 80
1

I'd also use bwmorph

%# find the branch point
branchImg = bwmorph(img,'branchpoints');

%# grow the pixel to 3x3
branchImg = imdilate(branchImg,ones(3));

%# hide the branch point
noBranchImg = img & ~branchImg;

%# label the three lines
lblImg = bwlabel(noBranchImg);

%# in the original image, mask label #3
%# note that it may not always be #3 that you want to mask
finalImg = img;
finalImg(lblImg==3) = 0;

%# show the result
imshow(finalImg)
Jonas
  • 74,690
  • 10
  • 137
  • 177
  • you mentioned that it can not always be 3... what is the reason behind this? for my understanding it's always a 1px widthened line/contour, which fits that pattern (of 3).. ? – mchlfchr Nov 28 '12 at 09:44
  • @mchlfchr: in the `bwlabel` step, the three disconnected lines get assigned the labels 1,2, and 3, respectively. It may not always be the part labeled 3 that you want to remove. – Jonas Nov 28 '12 at 11:50
  • so isn't it possible to select the "outter" line for any case? As I understood the `hbreak` way, it separates such triple connected structures? In the next step I would have selected that outter label, but that option `hbreak` is not working for what reason. – mchlfchr Nov 28 '12 at 12:14
  • @mchlfchr: to select the right-most line, if you know that it and only it touches the right border of the image, you can use `label2delete = max(img(:,end));` – Jonas Nov 28 '12 at 13:06