隔离矩形物体的最佳方法

时间:2016-04-09 14:33:24

标签: matlab image-processing image-segmentation

我有以下图像,我想在中间分割矩形对象。我实现了以下代码来分段,但我无法隔离对象。我可以采取哪些功能或方法来隔离图像中的矩形对象?

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);

enter image description here enter image description here

1 个答案:

答案 0 :(得分:4)

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

  1. 使用阈值来定位图像中的蓝色位置并创建初始遮罩。
  2. 鉴于此初始遮罩,使用最小和最大操作找到它的角落。
  3. 在角落之间用线条连接以接收矩形。
  4. 使用imfill填充矩形。
  5. 代码示例:

    % 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);
    

    最终结果: final result

    中间结果(阈值取1次后,加入线后2次): enter image description here

    * drawline函数取自drawline webpage