# How to Erode the border and get rectangel shape?

Hi All,

Does anyone give me some suggestions? This is my image,Sample.bmp, I want to remove some unwanted part from border and get the corrected rectangle shape. So, how should I do? Currently, I am using "Blob Analysis". So, the result always include the unwanted region. But, I don't know how to remove it not effect the rectangle shape.

Another sample image, sample2.bmp

Regards, zawpai

edit retag close merge delete

( 2013-11-22 04:43:24 -0600 )edit

( 2013-11-25 22:19:31 -0600 )edit

Hi Haris,

May I ask you one thing. My image has 4 borders. So, should I need to iterate 4 times?

( 2013-11-26 03:19:39 -0600 )edit

I didn’t get your point exactly, and may depend on your algorithm.

( 2013-11-26 03:32:04 -0600 )edit

Could you please take a look my new image, "sample2.bmp"? According to this image, I need to remove both Left and Right portions. So, I may need to remove 4 sides to get the rectangle. Do you have any better ideal?

( 2013-11-26 18:27:43 -0600 )edit

Sort by » oldest newest most voted

You can solve it out by either of the two method explained below.

First method.

• Convert to Gray.

• Threshold the image.

• Find the biggest contour in the threshold image, which will represent boundary of your object.

• Find the convexHull of the biggest contour.

• Compute the largest rectangle inside the convex polygon. See a good explanation here

Second method.

This one is relatively simple compared to above.

• Convert to Gray.
• Threshold the image
• Find biggest contour to segment object region and draw contour to new Mat.
• Apply morphologyEx, here we use morphological Opening . And another thing is that we will use larger kernel size along one direction(x or y) to remove unwanted boarder in your image.

• After morphology apply findcontours() and boundingRect() for final segmentation.

Source code

#include <iostream>
#include "opencv2/opencv.hpp"

using namespace std;
using namespace cv;

int main(){

//Load image convert to gray scale and threshold
Mat tmp,thr;
blur( src, src, Size( 7, 7 ), Point(-1,-1) );
cvtColor(src,tmp,CV_BGR2GRAY);
threshold(tmp,thr,180,255,THRESH_BINARY);
imshow("thr",thr);

//Find biggest contour to segment exact object
vector< vector <Point> > contours; // Vector for storing contour
vector< Vec4i > hierarchy;
int largest_contour_index=0;
int largest_area=0;
Mat dst(src.rows,src.cols,CV_8UC1,Scalar::all(0)); //create destination image

findContours( thr, contours, hierarchy,CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE ); // Find the contours in the image
for( int i = 0; i< contours.size(); i++ ) // iterate through each contour.
{
double a=contourArea( contours[i],false);  //  Find the area of contour
if(a>largest_area){
largest_area=a;
largest_contour_index=i;                //Store the index of largest contour
}
}

drawContours( dst,contours, largest_contour_index, Scalar(255,255,255),CV_FILLED, 8, hierarchy ); // Draw the largest contour using previously stored index.
imshow("contour",dst);

//Apply morphological opening operation to eliminate unwanted region.
Size kernalSize (7,100); //kernal size may change for differnt image
Mat element = getStructuringElement (MORPH_RECT, kernalSize, Point(1,1)  );
morphologyEx( dst, dst, MORPH_OPEN, element );

//find bounding box after morphology.
findContours( dst, contours, hierarchy,CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE ); // Find the contours in the image always only one contour
Rect rect=boundingRect(contours[0]);

//Crop the rsult
Mat crop=src(rect);
imshow("Cropped",crop);
rectangle( src, rect, Scalar(0,0,255), 1, 8, 0 );
imshow("src",src);
waitKey();

}


Result for sample2.bmp

Size kernalSize (7,100);


Source image

Largest contour

After morphology

Result

And for your first image Sample.bmp you need to change the kernel like

Size kernalSize (100,7);


And here is the result I got with the above kernel

more

Hi Haris, thanks for your sample code. It is working fine. May I ask you one question. How could I choose the corrected "kernalSize" based on these tow images?

( 2013-11-27 22:49:14 -0600 )edit

That may depend on your input image. Suppose if you have to remove the region in four side then you may need to use the kernalSize (100,100);

( 2013-11-27 23:00:16 -0600 )edit

Hi Haris, Thanks for your help. Now, everything is working fine.

( 2013-11-28 00:55:45 -0600 )edit

You are welcome.

( 2013-11-28 01:23:20 -0600 )edit

Official site

GitHub

Wiki

Documentation