Skip to content

Instantly share code, notes, and snippets.

@DongHeZheng
Last active May 6, 2024 12:45
Show Gist options
  • Save DongHeZheng/b6e164908732e21c9e50d04e5b46e371 to your computer and use it in GitHub Desktop.
Save DongHeZheng/b6e164908732e21c9e50d04e5b46e371 to your computer and use it in GitHub Desktop.
One method of scaling, rotating and cropping image by using OpenCV
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)));
}
@DongHeZheng
Copy link
Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment