-
-
Save DongHeZheng/b6e164908732e21c9e50d04e5b46e371 to your computer and use it in GitHub Desktop.
One method of scaling, rotating and cropping image by using OpenCV
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void imageScaleAndRotate(const cv::Mat &src, cv::Mat &out, double scale, double roll) { | |
// scaling | |
cv::Mat imSmall; | |
cv::resize(src, imSmall, cv::Size(), scale, scale); | |
// prepare for rotating | |
int width = imSmall.cols, height = imSmall.rows; | |
int diagonal = int(sqrt(height * height + width * width)); | |
int offsetX = (diagonal - width) / 2, offsetY = (diagonal - height) / 2; | |
cv::Mat tmp(diagonal, diagonal, imSmall.type(), cv::Scalar(0, 0, 0, 0)); | |
imSmall.copyTo(tmp.rowRange(offsetY, offsetY + height).colRange(offsetX, offsetX + width)); | |
// rotating | |
cv::Mat rotated; | |
cv::Point2f center(diagonal / 2.0f, diagonal / 2.0f); | |
cv::Mat rot_mat = cv::getRotationMatrix2D(center, roll, 1.0f); | |
cv::warpAffine(tmp, rotated, rot_mat, tmp.size()); | |
// cropping | |
cv::RotatedRect rc(cv::Point2f(width / 2, height / 2), cv::Size2f(width, height), -roll); | |
cv::Rect_<float> rcBound = rc.boundingRect2f(); | |
out = rotated(cv::Rect2f(cv::Point2f(center.x - rcBound.width / 2, center.y - rcBound.height / 2), cv::Size(rcBound.width, rcBound.height))); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I use this function quite a lot. So I want to share this function with everyone.
Rotation direction is counter-clock wise(CCW).
Note that warpAffine's rotation direction is CCW and RotatedRect's one is clock-wise(CW).
I think there is no inconvenience in using.