我有一个二进制矩阵,比如说:
matrix=double(rand(100,100)>0.7);
我想在这个矩阵中找到长度为2或更多元素的1(从左下到右上)的所有“对角线”,并将所有其他1设置为0,这样我得到另一个只有那些对角线的矩阵
我想对垂直线做同样的事情。
有一种简单的方法吗?
答案 0 :(得分:2)
您可以使用conv2
来检测这些行:
% your data
M=double(rand(100,100)>0.7);
%length you want to detect
n=2;
kernel=eye(n);
%detect diagonal ones from top left to bottom right
lines=conv2(M,eye(n),'same')==sum(kernel(:));
对于朝向另一个方向的对角线,请使用kernel=fliplr(eye(n));
代替kernel=eye(n);
对于垂直和水平线,请使用kernel=ones(n,1);
或kernel=ones(1,n);
内核是包含您要检测的内容的矩阵:
>> kernel=eye(n)
kernel =
1 0
0 1
>> kernel=fliplr(eye(n))
kernel =
0 1
1 0
>> kernel=ones(n,1)
kernel =
1
1
>> kernel=ones(1,n)
kernel =
1 1
请注意,对于第二个对角线,标记位置可能有点混乱,因为卷积适用于矩形。输入
[0 0 0;
0 1 0;
1 0 0]
它将返回:
[0 0 0;
1 0 0;
0 0 0]
标记找到对角线的矩形的左上角。现在有了识别对角线的代码,再次卷积可以用来创建预期的矩阵:
M=(conv2(double(conv2(M,kernel,'valid')==sum(kernel(:))),kernel,'full'))>0
答案 1 :(得分:1)
您可以使用2D卷积结合一些花哨的内核来检测这一点。基本思想是制作一个看起来像你试图检测的功能的内核。
首先,要检测两种类型的对角线:
我们可以设计一个内核来检测第一种类型:
kernel = [1 0 0;
0 1 0;
0 0 1];
这只是单位矩阵(eye(3)
),如果我们用你的输入来搞这个。
conv2(matrix, eye(3), 'same');
如果我们将这样做作为测试的单位矩阵,我们可以看到卷积的结果
您可以清楚地看到作为对角线一部分的像素具有值>然后,我们可以将其转换为二进制矩阵,指示像素是否沿着对角线。您还需要确保当前像素也 1。
is_top_left_to_bottom_right = conv2(matrix, eye(3), 'same') > 1 & logical(matrix);
以类似的方式,我们可以翻转内核来检测其他方向的对角线。
is_top_right_to_bottom_left = conv2(matrix, fliplr(eye(3)), 'same') > 1 & logical(matrix);
然后您可以单独查看,也可以使用逻辑or
is_diagonal = is_top_left_to_bottom_right | is_top_right_to_bottom_left;
对于水平和垂直线,您可以使用以下类似的方式使用以下内核(请记住,我在开始时说过,您希望内核看起来像您尝试检测的功能!)。
horizontal = [0 0 0
1 1 1
0 0 0];
vertical = [0 1 0
0 1 0
0 1 0];