2017-07-26 232 views
2

我想用像這樣的圖像提取類似矩形的形狀(一些可能在一邊有三角形延伸)如何在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

回答

0

如何丟棄非矩形區域?那麼我相信你可以想出一些矩形非常獨特的數學屬性。

  • 該區域是寬度和高度的乘積。

  • 周長是寬度和高度之和的兩倍。

  • 它顯然有4個矩形的角落。

我想第一個屬性是足夠的,你可以想出更多的規則,如果你需要。

您可以擺脫不需要的矩形和其他小東西的最小尺寸約束或檢查它們是否被矩形包圍。

這應該是非常簡單的。

+0

您指出了非常明顯的屬性,這絕對是正確的。他們可以使用。仍然不知道如何丟棄區域(索引= 11),並且某些形狀(此處未顯示)具有非矩形但凸形的形狀,如矩形頂端的三角形,如書籤形狀。 – freezer

+0

@freezer我不明白你想要什麼。你描述的形狀不是矩形。因此他們不能滿足我提到的限制。面積=寬度*高度本身足以擺脫它們。 – Piglet

+0

你是對的我可能寫錯了題目的標題。但是,我不止一次提到過這種情況。有可能是非矩形形狀,也有興趣。要丟棄的部分是連接線之間的區域。可能有很多變化,但我猜他們是非凸面區域。 – freezer

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 

結果

enter image description here

+0

這是一個有價值的答案,但並沒有解決我的問題。我將相應地編輯我的問題。 – freezer