我的矩阵中有一个 0 和 1 的逻辑圆形掩码,如下所示。
在另一个矩阵中获得外边界的最快方法是什么?
本质上,如果行中有重复的 1,我必须扫描每行左侧的第一个 1 和右侧的第一个 1(最上面和最下面的点只有一个 1)....有人可以帮我吗找到一个快速的方法来做到这一点?
我的矩阵中有一个 0 和 1 的逻辑圆形掩码,如下所示。
在另一个矩阵中获得外边界的最快方法是什么?
本质上,如果行中有重复的 1,我必须扫描每行左侧的第一个 1 和右侧的第一个 1(最上面和最下面的点只有一个 1)....有人可以帮我吗找到一个快速的方法来做到这一点?
您可以为此使用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');
其他答案对于在图像中查找一般圆圈很有用,但是由于您知道您正在寻找二进制掩码中的圆圈,因此 bwmorph 可能是您最好的选择。
I=imread('0ateM.png');
BW=im2bw(I);
BW2=bwmorph(BW,'endpoints');
编辑:正如我在评论中提到的,为了放大圆圈,以便将原始圆圈蒙版之外的 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。
蛮力与图像的大小成线性关系,并且由于您需要复制图像,因此我认为通过改进方法无法获得太多收益。尽管如此,它应该很快,并且适用于图像上的任意数量的圆圈。
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