I'd like to rotate an image, but I can't obtain the rotated image without cropping
My original image:
Now I use this code:
#include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> // Compile with g++ code.cpp -lopencv_core -lopencv_highgui -lopencv_imgproc int main() { cv::Mat src = cv::imread("im.png", CV_LOAD_IMAGE_UNCHANGED); cv::Mat dst; cv::Point2f pc(src.cols/2., src.rows/2.); cv::Mat r = cv::getRotationMatrix2D(pc, -45, 1.0); cv::warpAffine(src, dst, r, src.size()); // what size I should use? cv::imwrite("rotated_im.png", dst); return 0; }
And obtain the following image:
But I'd like to obtain this:
You'll see the fruits of its labor when you use the rotate tool in the new Photos app. Tap "Edit," then tap the cropping tool. Finally, move the slider along the bottom of the display. Instead of cropping your image to fit the new dimensions, your iPhone will simply take the extra data to fill in the gaps.
My answer is inspired by the following posts / blog entries:
Main ideas:
cv::RotatedRect
to rely on existing opencv functionality as much as possible Code tested with opencv 3.4.1:
#include "opencv2/opencv.hpp" int main() { cv::Mat src = cv::imread("im.png", CV_LOAD_IMAGE_UNCHANGED); double angle = -45; // get rotation matrix for rotating the image around its center in pixel coordinates cv::Point2f center((src.cols-1)/2.0, (src.rows-1)/2.0); cv::Mat rot = cv::getRotationMatrix2D(center, angle, 1.0); // determine bounding rectangle, center not relevant cv::Rect2f bbox = cv::RotatedRect(cv::Point2f(), src.size(), angle).boundingRect2f(); // adjust transformation matrix rot.at<double>(0,2) += bbox.width/2.0 - src.cols/2.0; rot.at<double>(1,2) += bbox.height/2.0 - src.rows/2.0; cv::Mat dst; cv::warpAffine(src, dst, rot, bbox.size()); cv::imwrite("rotated_im.png", dst); return 0; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With