1 | initial version |
Can I assume you can detect the edges of the paper? Yes? Good, otherwise you have more trouble than the rotation.
Since it's only up to 5 degrees, you know which edge is the top edge. You know the length of the top and bottom edge, which for now call width. You know the length of the left and right edges, which for now call height. You need to find the transform that makes this into a width by height rectangle. Fortunately, OpenCV provides a function for calculating the transform from one set of points to another: estimateRigidTransform. Finally, de-rotate it by calling warpAffine, which does the actual transforming of the image.
As always with my code, I may have swapped an x and y or width and height somewhere here, so don't just blindly copy.
std::vector<cv::Point2f> paperCorners; //Fill with the corners of the paper, in order TL, TR, BL, BR
std::vector<cv::Point2f> correctedCorners;
correctedCorners.push_back(cv::Point2f(0,0));//TL
correctedCorners.push_back(cv::Point2f(width,0));//TR
correctedCorners.push_back(cv::Point2f(0,height));//BL
correctedCorners.push_back(cv::Point2f(width, height));//BR
cv::Mat affine = cv::estimateRigidTransform(paperCorners, correctedCorners, true);
//Setting true also corrects skew, which might be necessary.
cv::warpAffine(warpedScan, correctedScan, affine, cv::Size(width, height));