dfj328
dfj328

Reputation: 367

Best way to isolate rectangular object

I have the following image and I would like to segment the rectangular object in the middle. I implemented the following code to segment but I cannot isolate the object. What functions or approaches can I take to isolate the rectangular object in the image?

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

Upvotes: 2

Views: 105

Answers (1)

ibezito
ibezito

Reputation: 5822

In this example, you can leverage the fact that the rectangle contains blue in all of its corners in order to build a good initial mask.

  1. Use threshold in order to locate the blue locations in the image and create an initial mask.
  2. Given this initial mask, find its corners using min and max operations.
  3. Connect between the corners with lines in order to receive a rectangle.
  4. Fill the rectangle using imfill.

Code example:

% 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: final result

Intermediate results (1-after threshold taking, 2-after adding lines): enter image description here

*drawline function is taken from drawline webpage

Upvotes: 4

Related Questions