如何在MATLAB中丢弃图像中的非矩形闭区域?

问题描述:

我想用像这样的图像提取类似矩形的形状(一些可能在一边有三角形延伸)如何在MATLAB中丢弃图像中的非矩形闭区域?

enter image description here

我在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 

我得出的是;

enter image description here

正如所看到的,有区域找到作为文本中的一部分,形状的块(索引= 3)和非块区域(指数= 11)的内部。我需要丢弃内部区域和非阻塞区域。

另一个问题是,因为区域由白色区域定义,我需要获取块的黑色边框,以便我可以捕获块本身,而不是内部白色区域。我如何解决这些问题?

我都尝试颠倒图像和使用方法,但没有成功。

EDIT:代码改进&附加图像

其中一个图像可以是这样的,包括非矩形但兴趣形状的物体(最左边)。

enter image description here

另一个问题,如果图像不如它应该是有的,视为开放特别是对角线和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 

结果为否的条件;

enter image description here

优点是所有剩余的区域是区域如果兴趣也不例外和面积约束等,因为图像尺寸可以是不同的因而区域没有条件。

但即使这不适用于第二个图像。由于块下面的文本(始终是这种情况 - >第一个图像被清除为上传),最左边块的对角线顶端被认为是开放线。

+0

难道矩形可以有比噪声较粗的线? –

+0

不要以为。这个图像不是我的创作。我需要为此努力。所以它就是这样。 :/ – freezer

+1

部分解决方案是迭代检查中心是否在另一个盒子内。 – m7913d

如何丢弃非矩形区域?那么我相信你可以想出一些矩形非常独特的数学属性。

  • 该区域是宽度和高度的乘积。

  • 周长是宽度和高度之和的两倍。

  • 它显然有4个矩形的角落。

我想第一个属性是足够的,你可以想出更多的规则,如果你需要。

您可以摆脱不需要的矩形和其他小东西的最小尺寸约束或检查它们是否被矩形包围。

这应该是非常简单的。

+0

您指出了非常明显的属性,这绝对是正确的。他们可以使用。仍然不知道如何丢弃区域(索引= 11),并且某些形状(此处未显示)具有非矩形但凸形的形状,如矩形顶端的三角形,如书签形状。 – freezer

+0

@freezer我不明白你想要什么。你描述的形状不是矩形。因此他们不能满足我提到的限制。面积=宽度*高度本身足以摆脱它们。 – Piglet

+0

你是对的我可能写错了题目的标题。但是,我不止一次提到过这种情况。有可能是非矩形形状,也有兴趣。要丢弃的部分是连接线之间的区域。可能有很多变化,但我猜他们是非凸面区域。 – freezer

通过增加两个条件,我得到了一些不错的成绩:

  • 矩形需要完全关闭
  • 面积必须大于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 

结果

enter image description here

+0

这是一个有价值的答案,但并没有解决我的问题。我将相应地编辑我的问题。 – freezer