在 C++ 中的 OpenCV 中旋转图像而不裁剪

2021-12-10 00:00:00 opencv c++

我想旋转图像,但我无法在不裁剪的情况下获得旋转的图像

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

我的原图:

现在我使用这个代码:

#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;
}

并获得以下图像:

但我想得到这个:

推荐答案

我的回答受到以下帖子/博客条目的启发:

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

  • 使用 cv 旋转 cv::Mat::warpAffine 偏移目标图像
  • http://john.freml.in/opencv-rotation

主要思想:

  • 通过向新图像中心添加平移来调整旋转矩阵
  • 使用cv::RotatedRect尽可能依赖现有的opencv功能
  • 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

使用 opencv 3.4.1 测试的代码:

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;
}

相关文章