如何在MATLAB中丢弃图像中的非矩形闭区域?
我想用像这样的图像提取类似矩形的形状(一些可能在一边有三角形延伸)如何在MATLAB中丢弃图像中的非矩形闭区域?
我在MATLAB中所做的是;
BW=imread('Capture2.JPG');
BW=~im2bw(BW);
SE = strel('rectangle',[1 6]);
BW = ~imclose(BW,SE);
BW2 = imfill(~BW,'holes');
figure
imshow(~BW)
figure
imshow(BW2);
s = regionprops(BW,'BoundingBox','Area','PixelIdxList');
s = s(2:end);
[lab, numberOfClosedRegions] = bwlabel(BW);
figure
imshow(BW)
for i=1:numel(s)
rec = s(i);
ratio = rec.BoundingBox(4)/rec.BoundingBox(3);%height/width
% ratio > 0.3 && ratio < 51.6 && rec.Area > 1100 && rec.Area < 22500
% if ratio > 0.16
rectangle('Position',s(i).BoundingBox,'EdgeColor','r','LineWidth',2);
text(rec.BoundingBox(1),rec.BoundingBox(2),num2str(i),'fontsize',16);
% end
end
我得出的是;
正如所看到的,有区域找到作为文本中的一部分,形状的块(索引= 3)和非块区域(指数= 11)的内部。我需要丢弃内部区域和非阻塞区域。
另一个问题是,因为区域由白色区域定义,我需要获取块的黑色边框,以便我可以捕获块本身,而不是内部白色区域。我如何解决这些问题?
我都尝试颠倒图像和使用方法,但没有成功。
EDIT:代码改进&附加图像
其中一个图像可以是这样的,包括非矩形但兴趣形状的物体(最左边)。
另一个问题,如果图像不如它应该是有的,视为开放特别是对角线和1px的宽的人行导致regionprops想念他们。
代码改进;
close all;
image=imread('Capture1.JPG');
BW = image;
BW = ~im2bw(BW);
SE = strel('rectangle',[3 6]);
BW = ~imclose(BW,SE); % closes some caps to be closed region
r = regionprops(BW,'PixelIdxList');
BW(r(1).PixelIdxList) = 0; %removes outermost white space allowing to connection lines disapear
se = strel('rectangle',[6 1]);
BW = imclose(BW,se);% closes some caps to be closed region
BW = imfill(BW,'holes');
s = regionprops(BW,{'Area', 'ConvexArea', 'BoundingBox','ConvexHull','PixelIdxList'});
%mostly the area and convex area are similar but if convex area is much greater than the area itself it is a complex shape like concave intermediate sections then remove
noidx = [];
for i=1:numel(s)
rec = s(i);
if rec.Area*1.5 < rec.ConvexArea
BW(rec.PixelIdxList) = 0;
noidx(end+1)=i;
end
end
s(noidx)=[];
%为剩余区域 图 imshow(BW)
for i=1:numel(s)
rec = s(i);
ratio = rec.BoundingBox(4)/rec.BoundingBox(3);%height/width
% ratio > 0.3 && ratio < 51.6 && rec.Area > 1100 && rec.Area < 22500
% if ratio > 0.16
rectangle('Position',s(i).BoundingBox,'EdgeColor','r','LineWidth',2);
text(rec.BoundingBox(1),rec.BoundingBox(2),num2str(i),'fontsize',16,'color','red');
% end
end
结果为否的条件;
优点是所有剩余的区域是区域如果兴趣也不例外和面积约束等,因为图像尺寸可以是不同的因而区域没有条件。
但即使这不适用于第二个图像。由于块下面的文本(始终是这种情况 - >第一个图像被清除为上传),最左边块的对角线顶端被认为是开放线。
如何丢弃非矩形区域?那么我相信你可以想出一些矩形非常独特的数学属性。
该区域是宽度和高度的乘积。
周长是宽度和高度之和的两倍。
它显然有4个矩形的角落。
我想第一个属性是足够的,你可以想出更多的规则,如果你需要。
您可以摆脱不需要的矩形和其他小东西的最小尺寸约束或检查它们是否被矩形包围。
这应该是非常简单的。
通过增加两个条件,我得到了一些不错的成绩:
- 矩形需要完全关闭
- 面积必须大于x像素大(1100在这种情况下)
为了检查矩形是否关闭,我为每个多边形创建了一个索引。这些索引具有与矩形相同的形状。所以如果sum(~BW(index)) == sum(index(:))
这意味着该多边形是封闭的。
更新的代码:
warning off
BW=imread('test.jpg');
BW=~im2bw(BW);
SE = strel('rectangle',[1 6]);
BW = ~imclose(BW,SE);
BW2 = imfill(~BW,'holes');
s = regionprops(BW,'BoundingBox','Area','PixelIdxList');
s = s(2:end);
[lab, numberOfClosedRegions] = bwlabel(BW);
figure
imshow(imread('test.jpg'))
inc = 1;
for i=1:numel(s)
rec = s(i);
s(i).BoundingBox = floor(s(i).BoundingBox + [-1,-1,2,2]);
%Creation of the index
clear ind
ind = zeros(size(BW));
y = s(i).BoundingBox(1);
x = s(i).BoundingBox(2);
h = s(i).BoundingBox(3);
w = s(i).BoundingBox(4);
ind(x:x+w,[y,y+h]) = 1;
ind([x,x+w],y:y+h) = 1;
ind = logical(ind);
if sum(~BW(ind)) == sum(ind(:)) && rec.Area > 1100
rectangle('Position',s(i).BoundingBox,'EdgeColor','r','LineWidth',1);
text(rec.BoundingBox(1),rec.BoundingBox(2),num2str(inc),'fontsize',16);
inc = inc + 1;
end
end
结果
这是一个有价值的答案,但并没有解决我的问题。我将相应地编辑我的问题。 – freezer
难道矩形可以有比噪声较粗的线? –
不要以为。这个图像不是我的创作。我需要为此努力。所以它就是这样。 :/ – freezer
部分解决方案是迭代检查中心是否在另一个盒子内。 – m7913d