Ask Your Question

Revision history [back]

Once you have your contour, you could apply the following steps

  • Find the bounding rotated rectangle of the contour
  • Use the angle parameter to warp back the image

Some code that could do this

/// Get the RotatedRect associated with the contour
RotatedRect rect = minAreaRect(contour);
/// Also select the corner points for rotating back
Point2f pts[4]; rect.points(pts);
/// Define the angle of rotation and rotate the selection to an upright position
double angle = 0.0;
if((int)rect.angle < -45){
   angle = fmod((rect.angle + 90), 90);
}else{
   angle = (int)rect.angle;
}
/// Warp back based on the angle
Mat r = getRotationMatrix2D(Point2f(img.cols/2, image.rows/2), angle, 1.0);
warpAffine(image.clone(), image, r, cv::Size(image.cols, image.rows));
// Finally warp the corner points from the original image using same matrix to obtain the mask to be cut out
Mat coordinates = (Mat_<double>(3,4) << pts_original[0].x, pts_original[1].x, pts_original[2].x, pts_original[3].x ,\
                            pts_original[0].y, pts_original[1].y, pts_original[2].y, pts_original[3].y,\
                            1   , 1  ,  1   , 1    );
Mat result = r * coordinates;
Point p1_back, p2_back, p3_back, p4_back;
vector<Point> collection;
p1_back.x=(int)result.at<double>(0,0); p1_back.y=(int)result.at<double>(1,0);
p2_back.x=(int)result.at<double>(0,1); p2_back.y=(int)result.at<double>(1,1);
p3_back.x=(int)result.at<double>(0,2); p3_back.y=(int)result.at<double>(1,2);
p4_back.x=(int)result.at<double>(0,3); p4_back.y=(int)result.at<double>(1,3);

This above code in snipped from some larger code and might need some adaptations (larger final canvas). But I will not do all the work for you :D

Once you have your contour, you could apply the following steps

  • Find the bounding rotated rectangle of the contour
  • Use the angle parameter to warp back the image

Some code that could do this

/// Get the RotatedRect associated with the contour
RotatedRect rect = minAreaRect(contour);
/// Also select the corner points for rotating back
Point2f pts[4]; rect.points(pts);
/// Define the angle of rotation and rotate the selection to an upright position
double angle = 0.0;
if((int)rect.angle < -45){
   angle = fmod((rect.angle + 90), 90);
}else{
   angle = (int)rect.angle;
}
/// Warp back based on the angle
Mat r = getRotationMatrix2D(Point2f(img.cols/2, image.rows/2), angle, 1.0);
warpAffine(image.clone(), image, r, cv::Size(image.cols, image.rows));
// Finally warp the corner points from the original image using same matrix to obtain the mask to be cut out
Mat coordinates = (Mat_<double>(3,4) << pts_original[0].x, pts_original[1].x, pts_original[2].x, pts_original[3].x ,\
                            pts_original[0].y, ,pts_original[0].y, pts_original[1].y, pts_original[2].y, pts_original[3].y,\
                            pts_original[3].y, 1   , 1  ,  1   , 1    );
Mat result = r * coordinates;
Point p1_back, p2_back, p3_back, p4_back;
vector<Point> collection;
p1_back.x=(int)result.at<double>(0,0); p1_back.y=(int)result.at<double>(1,0);
p2_back.x=(int)result.at<double>(0,1); p2_back.y=(int)result.at<double>(1,1);
p3_back.x=(int)result.at<double>(0,2); p3_back.y=(int)result.at<double>(1,2);
p4_back.x=(int)result.at<double>(0,3); p4_back.y=(int)result.at<double>(1,3);

This above code in snipped from some larger code and might need some adaptations (larger final canvas). But I will not do all the work for you :D