My Images;
Requirement:
I am not able to understand how axis is decided to make the image always horizontal.
Algorithm:
- Read the image
- Find external contour
- Draw the contours
- Use the external contour to detect minArearect (bounding box will not help for me)
- get the rotation matrix and rotate the image
- Extract the required patch from the rotated image
My code:
//read the image
img = imread("90.jpeg")
cv::Mat contourOutput = img.clone();
// detect external contour(images will have noise, although example images doesn't have)
std::vector<std::vector<cv::Point> > contours;
cv::findContours(contourOutput, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
int largest_area = 0;
int largest_contour_index = 0;
for (size_t i = 0; i < contours.size(); i++) {
double area = contourArea(contours[i]);
// copy the largest contour index
if (area > largest_area) {
largest_area = area;
largest_contour_index = i;
}
}
//draw contours
drawContours(img, contours, largest_contour_index, Scalar(255, 0, 0),
2);
// detect minimum area rect to get the angle and centre
cv::RotatedRect box = cv::minAreaRect(cv::Mat(contours[largest_contour_index]));
// take the box angle
double angle = box.angle;
if (angle < -45) {
box.angle += 90;
}
angle = box.angle;
// create rotation matrix
cv::Mat rot_mat = cv::getRotationMatrix2D(box.center, angle, 1);
// Apply the transformation
cv::Mat rotated;
cv::warpAffine(img, rotated, rot_mat, img.size(), cv::INTER_CUBIC);
cv::Size box_size = box.size;
if (box.angle < -45.)
std::swap(box_size.width, box_size.height);
// get the cropped image
cv::Mat cropped;
cv::getRectSubPix(rotated, box_size, box.center, cropped);
// Display the image
namedWindow("image2", WINDOW_NORMAL);
imshow("image2", cropped);
waitKey(0);