我有一个带有两个不同半径圆的二进制图像,需要使用imopen
或imclose
操作删除其中一个圆圈。我使用的结构元素的直径大于较小的圆但小于较大的圆,但它似乎不适用于任何一种操作。
我的形象:
我的代码:
c=imread('image.png');
se2=strel('disk',25);
c=imopen(c,se2);
figure, imshow(c,[]), title('new image');
答案 0 :(得分:2)
我可以看到三个会导致此算法无法运行预期结果的事情:
disk
结构元素太小,无法删除任何圆圈。你需要提高你的半径,以便它更多。我做了一些测试,为了摆脱较小的圆圈,我不得不将半径提高到45。disk
结构元素不是完美圈。事实上,这将是一个轻微的钻石形状。如果您想获得一个完美的圆圈,则需要使用strel
参数指定disk
的附加参数,该参数在半径(0
)之上为45
。完成此操作后,将图像反转回原来的位置,因为对象是黑色而不是白色。 因此,您的代码应如下所示:
%// Modified to read from StackOverflow
c = im2bw(imread('http://i.stack.imgur.com/7Hd0y.png'));
se = strel('disk', 45, 0); %// Change radius to 45 + add additional parameter of 0
c2 = imopen(~c, se); %// Invert the image before opening
c2 = ~c2; %// Invert back because original image was this way
imshow(c2); title('New Image');
这是我得到的图像:
答案 1 :(得分:2)
bwlabel
+ bsxfun
的解决方案如果您关心效果,请让我建议一种基于bwlabel
的方法和功能强大的矢量化工具bsxfun
,它可能比使用image morphological operations
更好。现在,你的问题基本上是一个最大的blob发现问题,这里是代码 -
c = im2bw(imread('http://i.stack.imgur.com/7Hd0y.png'));
[L,num] = bwlabel( ~c );
counts = sum(bsxfun(@eq,L(:),1:num));
[~,ind] = max(counts);
c = ~(L==ind);
根据基于imopen
的方法建议here -
c = im2bw(imread('http://i.stack.imgur.com/7Hd0y.png'));
disp('----------------------------------- With IMOPEN')
tic
se = strel('disk', 45, 0); %// Change radius to 45 + add additional parameter of 0
c2 = imopen(~c, se); %// Invert the image before opening
c2 = ~c2; %// Invert back because original image was this way
toc
disp('----------------------------------- With BWLABEL + BSXFUN')
tic
[L,num] = bwlabel( ~c );
counts = sum(bsxfun(@eq,L(:),1:num));
[~,ind] = max(counts);
out = ~(L==ind);
toc
结果 -
----------------------------------- With IMOPEN
Elapsed time is 0.195290 seconds.
----------------------------------- With BWLABEL + BSXFUN
Elapsed time is 0.020950 seconds.
您可能想要取消形态学操作的另一个原因是imopen
会改变边缘周围的斑点。如果在输入和输出图像之间执行绝对差异,则可以将其可视化。所以,如果你做figure,imshow(imabsdiff(c,c2))
,你会得到这个 -
正如你所看到的那样,更大的斑点在它的边缘发生了变化。在完全保留的情况下,只有较小的斑点必须在那里。