Rotated rectangle extraction

asked 2019-04-22 11:55:47 -0500

remoss gravatar image

updated 2019-04-24 13:12:46 -0500

I am new to opencv and image processing in general. I would like to cop a rotated rectangle with unknown angle from a grayscale bitmap file. In the image below there are overlapping tickets. I would like to extract the top slip. I used the minimum rectangle examples, and I found it could not detect the top rectangle from the image after looping through the contours in the debugger. I Is it possible to detect the top ticket? My code for now tries to level the top rectangle based on the smaller black rectangle angle. It is not quite accurate. Could someone please help me figure out how to rotate the image correctly. I have the crop functions working, the image is just not aligned properly before the crop.

image description

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

Mat rotated;

Mat threshold_output;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
bool StraightenImage( char* chName );

int main()
{
    StraightenImage("rawimage.bmp");

    waitKey(0);
   return 0;
}



bool StraightenImage( char* chName )
{
    /// Load source image and convert it to gray
    src = imread( chName, 1 );

  const char* source_window = "Source Image";
  namedWindow( source_window, WINDOW_AUTOSIZE );
  imshow( source_window, src );

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


  bool bRotated = true;
  /// Detect edges using Threshold
  threshold( src_gray, threshold_output, 48, 255, THRESH_BINARY );
  imwrite("threshoutput.bmp", threshold_output);
  /// Find contours
  findContours( threshold_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0)   );

  /// Find the rotated rectangles and ellipses for each contour
  vector<RotatedRect> minRect( contours.size() );

 size_t i;
 for( i = 0; i < contours.size(); i++ )
 { 
      minRect[i] = minAreaRect( Mat(contours[i]) );

      // find smaller rectangle
      if(minRect[i].size.width > 69 && minRect[i].size.width < 80 && minRect[i].size.height > 390 && minRect[i].size.height < 415 )
      {
          bRotated = false;
          break;
      }
      if(minRect[i].size.height > 69 && minRect[i].size.height < 80 && minRect[i].size.width > 390 && minRect[i].size.width < 415 )
      {
          bRotated = true;
          break;
      }
 }

if(i == contours.size())
    return false;  // nothing found

// rect is the RotatedRect (I got it from a contour...)
//RotatedRect rect;
// matrices we'll use
Mat M, cropped;
// get angle of smaller rectangle
double angle = minRect[i].angle;

// set size back to src image size 1280x800
minRect[i].size.width = 1280;
minRect[i].size.height = 800;
minRect[i].center.x = 1280/2;
minRect[i].center.y = 800/2;

Size rect_size = minRect[i].size;

if (angle < -45.) {
    angle += 90.0;

minRect[i].size.width = 800;
minRect[i].size.height = 1280;
minRect[i].center.x = 800/2;
minRect[i].center.y = 1280/2;

swap(minRect[i].size.width, minRect[i].size.height);
}

// get the rotation matrix
M = getRotationMatrix2D(minRect[i].center, angle, 1.0);
// perform the affine transformation on whole image 1280x800
warpAffine(src, rotated, M, src.size(), INTER_LINEAR);

// save file to disk
imwrite("rotated.bmp", rotated);

/// Create Window 224, 206 ...
(more)
edit retag flag offensive close merge delete