白色显示它们的值等于的1
像素,黑色显示它们的值等于的像素0
,
我想得到vertical only lines
。这意味着应删除水平线,如下图所示:
我也想得到horizontal only lines
. 这意味着应删除垂直线,如下图所示:
我该怎么做Matlab
?我更喜欢形态学操作。
白色显示它们的值等于的1
像素,黑色显示它们的值等于的像素0
,
我想得到vertical only lines
。这意味着应删除水平线,如下图所示:
我也想得到horizontal only lines
. 这意味着应删除垂直线,如下图所示:
我该怎么做Matlab
?我更喜欢形态学操作。
假设您的图像BW
如下:
% detecting all connected regions:
B = bwboundaries(BW,4);
这会产生一个单元数组B
,其中包含所有“补丁”,这些“补丁”是通过将相邻单元格与1
从 4 个边之一连接的值连接起来的,即不是对角线。
B =
[11x2 double]
[ 2x2 double]
[ 3x2 double]
[ 3x2 double]
[ 2x2 double]
[ 3x2 double]
[ 2x2 double]
[ 2x2 double]
[ 3x2 double]
[ 3x2 double]
[ 2x2 double]
[11x2 double]
例如:
>> B{6}
ans =
3 7
3 8
3 7
每行是一个单元格坐标。第一列是它的行,第二列是它的列,第一个和最后一个单元格总是相同的。
现在我们需要遍历 中的单元格B
,找出其中哪些是线,水平或垂直,并将它们保存到新矩阵中。
% matrices for horizontal and vertical lines:
BWh = zeros(size(BW)); % horizontal lines
BWv = zeros(size(BW)); % vertical lines
for k = 1:numel(B)
% if the coordinates changes ONLY vertically:
% a vertical line is where all the coulmn indecies are the same
% and there are different row indices
if all(B{k}(1,2)==B{k}(:,2)) && B{k}(1,1)~=B{k}(2,1)
BWv(sub2ind(size(BW),B{k}(:,1),B{k}(:,2))) = 1;
end
% if the coordinates changes ONLY horizontaly:
% a vertical line is where all the row indecies are the same
% and there are different column indices
if all(B{k}(1,1)==B{k}(:,1)) && B{k}(1,2)~=B{k}(2,2)
BWh(sub2ind(size(BW),B{k}(:,1),B{k}(:,2))) = 1;
end
end
subplot 131
imagesc(BWh)
title('Horizontal lines')
subplot 132
imagesc(BWv)
title('Vertical lines')
“对角边缘”是我们排除线条后留下的,所以我们可以寻找到目前为止我们没有找到的东西:
subplot 133
imagesc(BW & ~BWv & ~BWh)
title('Diagonal edges')
colormap 'gray'
此方法将忽略任何不是单格粗线的内容,例如,下图中中间的正方形将仅以对角线边缘模式显示:
有趣的问题,因为有很多方法可以做到这一点。本质上,您需要取出特定尺寸的连续像素。我认为解决此问题的一种方法是与 a [1 1]
or[1 1]'
向量进行卷积,然后取出您获得值 2 的所有元素。
bw(conv2(bw,[1 1],'same')==2)=0;
这仍然会留下您可以轻松取出的单个像素
bw = bwareaopen(bw,2) ;
这只是主要思想,您可能需要在边缘更加小心,或者用零填充以避免conv2可能产生的边缘伪影)......
另一个想法,使用霍夫变换来检测线条并只保留那些 theta=0 或 90 度...