Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

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;
Mat src=imread("test.bmp",1);
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

image description


Largest contour

image description


After morphology

image description


Result

image description


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

image description

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;
Mat src=imread("test.bmp",1);
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

image description


Largest contour

image description


After morphology

image description


Result

image description


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

image description

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;
Mat src=imread("test.bmp",1);
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

image description


Largest contour

image description


After morphology

image description


Result

image description


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

image description