Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rotate an image without cropping in OpenCV in C++

Tags:

c++

opencv

I'd like to rotate an image, but I can't obtain the rotated image without cropping

My original image:

enter image description here

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:

enter image description here

But I'd like to obtain this:

enter image description here

like image 735
Manuel Ignacio López Quintero Avatar asked Feb 26 '14 12:02

Manuel Ignacio López Quintero


People also ask

How do I rotate a picture without cropping it?

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.


1 Answers

My answer is inspired by the following posts / blog entries:

  • Rotate cv::Mat using cv::warpAffine offsets destination image
  • http://john.freml.in/opencv-rotation

Main ideas:

  • Adjusting the rotation matrix by adding a translation to the new image center
  • Using 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; } 
like image 151
Lars Schillingmann Avatar answered Sep 20 '22 14:09

Lars Schillingmann