隔离矩形物体的最佳方法

Best way to isolate rectangular object

我有下面的图像,我想分割中间的矩形对象。我实现了以下代码来分段,但无法隔离对象。可以采取什么函数或方法来隔离图像中的矩形对象?

im = imread('image.jpg');

% convert image to grayscale,
imHSV = rgb2hsv(im);
imGray = rgb2gray(im);
imSat = imHSV(:,:,2);
imHue = imHSV(:,:,1);
imVal = imHSV(:,:,3);

background = imopen(im,strel('disk',15));

I2 = im - background;

% detect edge using sobel algorithm
[~, threshold] = edge(imGray, 'sobel');
fudgeFactor = .5;
imEdge = edge(imGray,'sobel', threshold * fudgeFactor);
%figure, imshow(imEdge);

% split image into colour channels
redIM   = im(:,:,1);
greenIM = im(:,:,2);
blueIM  = im(:,:,3);

% convert image to binary image (using thresholding)
imBlobs = and((imSat < 0.6),(imHue < 0.6));
imBlobs = and(imBlobs, ((redIM + greenIM + blueIM) > 150));
imBlobs = imfill(~imBlobs,4);
imBlobs = bwareaopen(imBlobs,50);

figure,imshow(imBlobs);

在此示例中,您可以利用矩形的所有角都包含蓝色这一事实来构建良好的初始蒙版。

  1. 使用阈值定位图像中的蓝色位置并创建初始蒙版。
  2. 给定这个初始掩码,使用最小和最大操作找到它的角。
  3. 用线连接角之间以接收矩形。
  4. 使用 imfill 填充矩形。

代码示例:

% convert image to binary image (using thresholding)
redIM   = im(:,:,1);
greenIM = im(:,:,2);
blueIM  = im(:,:,3);
mask = blueIM > redIM*2 & blueIM > greenIM*2; 
%noise cleaning
mask = imopen(mask,strel('disk',3));

%find the corners of the rectangle
[Y, X] = ind2sub(size(mask),find(mask));
minYCoords = find(Y==min(Y));
maxYCoords = find(Y==max(Y));
minXCoords = find(X==min(X)); 
maxXCoords = find(X==max(X));
%top corners
topRightInd = find(X(minYCoords)==max(X(minYCoords)),1,'last');
topLeftInd = find(Y(minXCoords)==min(Y(minXCoords)),1,'last');
p1 = [Y(minYCoords(topRightInd)) X((minYCoords(topRightInd)))];
p2 = [Y(minXCoords(topLeftInd)) X((minXCoords(topLeftInd)))];
%bottom corners
bottomRightInd = find(Y(maxXCoords)==max(Y(maxXCoords)),1,'last'); 
bottomLeftInd = find(X(minYCoords)==min(X(minYCoords)),1,'last');
p3 = [Y(maxXCoords(bottomRightInd)) X((maxXCoords(bottomRightInd)))];
p4 = [Y(maxYCoords(bottomLeftInd)) X((maxYCoords(bottomLeftInd)))]; 

%connect between the corners with lines
l1Inds = drawline(p1,p2,size(mask));
l2Inds = drawline(p3,p4,size(mask));
maskOut = mask;
maskOut([l1Inds,l2Inds]) = 1;

%fill the rectangle which was created
midP = ceil((p1+p2+p3+p4)./4);
maskOut = imfill(maskOut,midP);

%present the final result
figure,imshow(maskOut);

最终结果:

中间结果(1-取阈值后,2-添加行后):

*画线函数取自drawline webpage