获得圆圈边界

时间:2012-11-05 23:52:23

标签: matlab

我的矩阵中有一个0和1的逻辑圆形掩码,它看起来如下。

Mask

在另一个矩阵中获得外边界的最快方法是什么?

基本上我必须从左边开始扫描第一个1,如果行中有重复的1个,则必须从右边开始扫描第一个1(在最顶部,最底部的点中只有一个)....有人可以帮助我找到一个快速的方法来做到这一点?

3 个答案:

答案 0 :(得分:6)

您可以使用regionprops,以下是一些标识圈子的示例:

或者如果您确定只有一个圆圈且没有噪音,我认为您可以找到底部/顶部/左/右边缘并从中起作用:

m = loadcirclefunction();
pix_left  = find(any(m,1),1,'first');
pix_right = find(any(m,1),1,'last');
pix_top   = find(any(m,2),1,'first');
pix_bottom= find(any(m,2),1,'last');

答案 1 :(得分:4)

其他答案适合在图像中查找一般圆圈,但由于您知道要在二进制掩码中寻找圆圈,因此bwmorph可能是您最好的选择。

I=imread('0ateM.png');
BW=im2bw(I);
BW2=bwmorph(BW,'endpoints');

image after bwmorph 编辑: 正如我在评论中提到的那样,为了放大圆圈以便你将原始圆形遮罩外的0像素设置为1而其他所有设置为0,你可以反转原始遮罩然后使用bwmorph:< / p>

WB=-(BW-1);
WB2=bwmorph(WB,'endpoints');

这有一个令人遗憾的副作用,即图像的边框变为1。当然你可以轻松改变这一点。对于mxn图像:

WB2(1,:)=0; WB2(:,1)=0; WB2(:,n)=0; WB2(m,:)=0;

另一种方法是直接在原始图像上使用过滤器:

f=[1 1 1; 1 -9 1; 1 1 1];
G=filter2(f,BW);
BW2=im2bw(G);

这将获得与上述WB2相同的结果,没有白边问题。需要im2bw调用,因为在过滤器之后,值不再仅为0或1,它们的范围介于-8和8之间,我们希望负值为0,正值为1。

答案 2 :(得分:0)

蛮力与图像大小呈线性关系,因为您需要复制图像,我认为通过改进方法无法获得更多收益。尽管如此,它应该非常快,并且适用于图像上的任意数量的圆圈。

function bound = find_bound(circle)

[sy sx] = size(circle);
bound = circle;

for i = 2:sy-1
    for j = 2:sx-1
        if (~circle(i,j))
            bound(i,j) = any((circle(i-1:i+1,j-1:j+1)-circle(i,j))(:));
        end
    end
end