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

时间:2017-07-26 14:37:42

标签: matlab image-processing image-segmentation regions

我想用这样的图像提取矩形形状(有些可能在一侧有三角形延伸);

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

如图所示,有些区域作为文本的一部分发现,形状在块内(index = 3)和非块区域(index = 11)。我需要丢弃内部区域和非区域区域。

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

我都试图反转图像并使用方法但没有成功。

编辑:代码改进&amp;附加图片

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

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

优点是所有剩余的区域都是区域,如果兴趣没有异常,也没有区域约束等条件,因为图像大小可以因此而区域。

但即使这对第二张图像也不起作用。由于块下方的文本(总是如此 - &gt;第一张图像被清除以便上传)并且最左边的块的对角线提示被视为开放线。

2 个答案:

答案 0 :(得分:1)

通过添加两个条件我得到了一些好的结果:

  • 矩形需要完全关闭
  • 该区域需要大于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

<强> RESULT

enter image description here

答案 1 :(得分:0)

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

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

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

  • 它显然有4个矩形角。

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

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

这应该是非常直接的。