Filling the objects found by canny edge

16 ビュー (過去 30 日間)
Kasia
Kasia 2011 年 12 月 8 日
Hi, I am trying to find object on the image. I applied some morphological processing and then canny edge function to find the object. However the edge function can only find the boundaries. The probles is how to fill the found objects? Another problem: some object are not fully closed, thus how to close the gaps? Possibly this question has already been answered but I searched the forum and help and I couldnt find solution. To see the image use this link: http://www.uploadup.com/di-HQA6.jpg
I would be grateful for any clues.

採用された回答

Sven
Sven 2011 年 12 月 9 日
Kasia, I wrote the following, which does what (I think) you're looking for:
I = imread('di-HQA6.jpg');
BW = bwareaopen(all(I>220,3),10);
cc = bwconncomp(BW);
% As you can see, some connected components are not *closed*:
figure, imagesc(imfill(labelmatrix(cc),'holes')), drawnow
% So, let's try closing them by iterative dilations
BWblank = false(cc.ImageSize);
stats = regionprops(cc,'ConvexImage','EulerNumber');
for i = find([stats.EulerNumber]>0)
distIm = bwdist(~stats(i).ConvexImage);
maxClose = ceil(max(distIm(:)));
BWslice = BWblank;
BWslice(cc.PixelIdxList{i}) = true;
if isinf(maxClose), continue; end;
for dilSz = 2:maxClose
BWnew = imdilate(BWslice,ones(dilSz));
statsNew = regionprops(BWnew,'EulerNumber');
if statsNew.EulerNumber<=0
BWnew = imerode(imfill(BWnew,'holes'),ones(dilSz));
cc.PixelIdxList{i} = find(BWnew);
end
end
end
figure, imagesc(imfill(labelmatrix(cc),'holes')), drawnow
% That got almost all of them. Some are left over where the dilation itself
% filled everything so the euler number stayed at 1. Let's just replace
% those with their convex hull
stats = regionprops(cc,'ConvexImage','EulerNumber','BoundingBox');
for i = find([stats.EulerNumber]>0)
maxClose = ceil(max(distIm(:)));
BWslice = BWblank;
BWslice(cc.PixelIdxList{i}) = true;
distIm = bwdist(~BWslice);
if ~any(distIm(:)>1)
BWnew = BWslice;
bb = ceil(stats(i).BoundingBox);
BWnew((1:bb(4))+bb(2)-1,(1:bb(3))+bb(1)-1) = stats(i).ConvexImage;
cc.PixelIdxList{i} = find(BWnew);
end
end
L = imfill(labelmatrix(cc),'holes');
figure, imagesc(L)
% Now we know that any blobs surrounded by other blobs are actually holes
indsOfHoles = find(arrayfun(@(i)mode(double(L(bwmorph(L==i,'dilate',1)&~(L==i)))),1:cc.NumObjects));
L(ismember(L,indsOfHoles)) = 0;
figure, imagesc(L)
The last variable L is what you're looking for. Luckily components get numbered from the outside in, so an "interior blob" will always have a higher number than it surrounding blob, meaning the imfill commands to the label matrix above don't paint over holes.
  1 件のコメント
Kasia
Kasia 2011 年 12 月 10 日
thank you

サインインしてコメントする。

その他の回答 (2 件)

Image Analyst
Image Analyst 2011 年 12 月 9 日
filledImage = imfill(binaryImage, 'holes');
  3 件のコメント
Image Analyst
Image Analyst 2011 年 12 月 9 日
So do it twice. The first time will fill the donut and leave the interior hole, and the second time will fill the interior hole.
Image Analyst
Image Analyst 2011 年 12 月 9 日
Are you talking about having problem with the blobs that are chopped off by the edge of the image? Is the boundary open at the edge?

サインインしてコメントする。


Marlene
Marlene 2011 年 12 月 27 日
Hello Sven,
You can explain to me what exactly does the line of code bwareaopen BW = (all (I> 220,3), 10)? I did not realize this part all(I> 220,3).
Thank's
  1 件のコメント
Walter Roberson
Walter Roberson 2011 年 12 月 27 日
http://www.mathworks.com/help/techdoc/ref/all.html

サインインしてコメントする。

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by