5

我的矩阵中有一个 0 和 1 的逻辑圆形掩码,如下所示。

面具

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

本质上,如果行中有重复的 1,我必须扫描每行左侧的第一个 1 和右侧的第一个 1(最上面和最下面的点只有一个 1)....有人可以帮我吗找到一个快速的方法来做到这一点?

4

3 回答 3

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');
于 2012-11-06T00:02:10.583 回答
4

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

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

bwmorph 后的图像 编辑:正如我在评论中提到的,为了放大圆圈,以便将原始圆圈蒙版之外的 0 像素设置为 1,其他所有内容设置为 0,您可以反转原始蒙版,然后使用 bwmorph :

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。

于 2012-11-06T00:39:55.267 回答
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
于 2012-11-06T00:26:31.707 回答