Question

I want to crop the bounding box of a currency note. I have the following code which draws the bounding boxes for the contours in the image. With the drawn rectangles, I want to crop the largest rectangle. Could somebody point me how I could do that.

The code I have is as follows.

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>

using namespace cv;
using namespace std;

Mat src; Mat src_gray;
int thresh = 100;
int max_thresh = 255;
RNG rng(12345);

/// Function header
void thresh_callback(int, void* );

/**
 * @function main
 */
int main( int, char** argv )
{
  /// Load source image and convert it to gray
  src = imread( "image_of_the_currency_note.jpg", 1 );

  /// Convert image to gray and blur it
  cvtColor( src, src_gray, COLOR_BGR2GRAY );
  blur( src_gray, src_gray, Size(3,3) );

  /// Create Window
  const char* source_window = "Source";
  namedWindow( source_window, WINDOW_AUTOSIZE );
  imshow( source_window, src );

  createTrackbar( " Threshold:", "Source", &thresh, max_thresh, thresh_callback );
  thresh_callback( 0, 0 );

  waitKey(0);
  return(0);
}

/**
 * @function thresh_callback
 */
void thresh_callback(int, void* )
{
  Mat threshold_output;
  vector<vector<Point> > contours;
  vector<Vec4i> hierarchy;

  /// Detect edges using Threshold
  threshold( src_gray, threshold_output, thresh, 255, THRESH_BINARY );
  /// Find contours
  findContours( threshold_output, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0) );

  /// Approximate contours to polygons + get bounding rects
  vector<vector<Point> > contours_poly( contours.size() );
  vector<Rect> boundRect( contours.size() );
  //vector<Point2f>center( contours.size() );
  //vector<float>radius( contours.size() );

  for( size_t i = 0; i < contours.size(); i++ )
     { approxPolyDP( Mat(contours[i]), contours_poly[i], 3, true );
       boundRect[i] = boundingRect( Mat(contours_poly[i]) );
     }


  /// Draw polygonal contour + bonding rects
  Mat drawing = Mat::zeros( threshold_output.size(), CV_8UC3 );
  for( size_t i = 0; i< contours.size(); i++ )
     {
       Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
       drawContours( drawing, contours_poly, (int)i, color, 1, 8, vector<Vec4i>(), 0, Point() );
       rectangle( drawing, boundRect[i].tl(), boundRect[i].br(), color, 2, 8, 0 );
     }

  /// Show in a window
  namedWindow( "Contours", WINDOW_AUTOSIZE );
  imshow( "Contours", drawing );
}

The images are attached here. "image_of_the_currency_note" is the original image and "bounding_box_drawn_for_the_contours_in_the_currency_note" shows the bounding boxes drawn for the original image. I want to get the largest bounding box in the image to a opencv Mat object.

http://oi57.tinypic.com/wjcade.jpg - image_of_the_currency_note

http://oi57.tinypic.com/2cqzbsh.jpg - bounding_box_drawn_for_the_contours_in_the_currency_note

If somebody could show me how to do that it would be a great help.

Thanks.

Was it helpful?

Solution

Just check that boundRect[i].width > threshold && boundRect[i].height > threshold. The threshold could be one-third of image size. So, if the boundRect[i] passes the condition then keep it else discard it. In this way, you would be able to get the largest rectangle.

Another Method

Your each contour consists of four points(e.g. A,B,C,D) of the rectangle. You just have to extract the x and y coordinates values of each point of a contour.

After extracting the x and y values of each point, you just need to set a condition that if ( distance between two subsequent points > certain value ) then keep that contour otherwise discard it.

For example: just check whether ( B.x - A.x > 100) then if true..keep the contour.

image

OTHER TIPS

I found the contourArea() function in opencv and decided to use that to get the largest contour and drew the bounding box of that largest contour.

  int largest_area=0;
  int largest_contour_index=0;
  Rect bounding_rect;

  for( size_t i = 0; i < contours.size(); i++ ) { 
      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
        bounding_rect=boundingRect(contours[i]); // Find the bounding rectangle for biggest contour
      }

  }

  Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
  //drawContours( src, contours,largest_contour_index, color, CV_FILLED, 8, hierarchy ); // Draw the largest contour using previously stored index.
  rectangle(src, bounding_rect,  Scalar(0,255,0),1, 8,0);  
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top