【问题标题】:Rotate back an image in opencv c++在opencv c ++中旋转图像
【发布时间】:2017-05-17 11:34:22
【问题描述】:

我使用此代码在 OpenCV 中旋转我的图像:

// get rotation matrix for rotating the image around its center
Point2f center22(RGBsrc.cols/2.0, RGBsrc.rows/2.0);
Mat rot = getRotationMatrix2D(center22, Angle, 1.0);
// determine bounding rectangle
Rect bbox = RotatedRect(center22,RGBsrc.size(),Angle).boundingRect();
// adjust transformation matrix
rot.at<double>(0,2) += bbox.width/2.0 - center22.x;
rot.at<double>(1,2) += bbox.height/2.0 - center22.y;
Mat dst;
warpAffine(RGBsrc, dst, rot, bbox.size());
imshow("rotated_im", dst);

它工作正常。现在我想将该图像旋转回原始图像。当我使用下面的代码时,我看到图像中对象的位置与原始图像中的位置不同。为什么会这样?如何将图像旋转回来?

Point2f center22(RGBsrc.cols/2.0, RGBsrc.rows/2.0);
Mat rot2 = getRotationMatrix2D(center22, -Angle, 1.0);
Rect bbox2 = RotatedRect(center22,RGBsrc.size(), -Angle).boundingRect();
rot2.at<double>(0,2) += bbox2.width/2.0 - center22.x;
rot2.at<double>(1,2) += bbox2.height/2.0 - center22.y;
Mat Rotatedback;
warpAffine(RotatedRGB, Rotatedback, rot2, bbox2.size());

【问题讨论】:

    标签: c++ image opencv image-rotation


    【解决方案1】:

    与其重新计算变换矩阵,不如简单地取它的逆矩阵?

    // Invert the affine transformation
    Mat rotInv;
    cv::invertAffineTransform(rot, rotInv);
    

    加载图片后:

    您可以像现在一样旋转它:

    // get rotation matrix for rotating the image around its center
    Point2f center22(RGBsrc.cols / 2.0, RGBsrc.rows / 2.0);
    Mat rot = getRotationMatrix2D(center22, Angle, 1.0);
    
    // determine bounding rectangle
    Rect bbox = RotatedRect(center22, RGBsrc.size(), Angle).boundingRect();
    
    // adjust transformation matrix
    rot.at<double>(0, 2) += bbox.width / 2.0 - center22.x;
    rot.at<double>(1, 2) += bbox.height / 2.0 - center22.y;
    Mat RotatedRGB;
    warpAffine(RGBsrc, RotatedRGB, rot, bbox.size());
    

    然后计算逆变换矩阵并回退:

    // Invert the affine transformation
    Mat rotInv;
    cv::invertAffineTransform(rot, rotInv);
    
    // Get back the original image
    Mat Rotatedback;
    warpAffine(RotatedRGB, Rotatedback, rotInv, Size(RGBsrc.cols, RGBsrc.rows));
    

    完整代码供参考:

    #include <opencv2\opencv.hpp>
    using namespace cv;
    
    int main()
    {
        Mat3b RGBsrc = imread("path_to_image");
        double Angle = 30.0;
    
        // get rotation matrix for rotating the image around its center
        Point2f center22(RGBsrc.cols / 2.0, RGBsrc.rows / 2.0);
        Mat rot = getRotationMatrix2D(center22, Angle, 1.0);
    
        // determine bounding rectangle
        Rect bbox = RotatedRect(center22, RGBsrc.size(), Angle).boundingRect();
    
        // adjust transformation matrix
        rot.at<double>(0, 2) += bbox.width / 2.0 - center22.x;
        rot.at<double>(1, 2) += bbox.height / 2.0 - center22.y;
        Mat RotatedRGB;
        warpAffine(RGBsrc, RotatedRGB, rot, bbox.size());
    
        // Invert the affine transformation
        Mat rotInv;
        cv::invertAffineTransform(rot, rotInv);
    
        // Get back the original image
        Mat Rotatedback;
        warpAffine(RotatedRGB, Rotatedback, rotInv, Size(RGBsrc.cols, RGBsrc.rows));
    
        imshow("Original", RGBsrc);
        imshow("Rotated", RotatedRGB);
        imshow("Rotated Back", Rotatedback);
        waitKey();
    
        return 0;
    }
    

    【讨论】:

      【解决方案2】:

      如果您在调用warpAffine() 时添加WARP_INVERSE_MAP 标志,它将应用逆变换矩阵,让您回到原始图像。例如,您应该能够将问题中的最后一行代码替换为以下内容:

      warpAffine(RotatedRGB, Rotatedback, rot, RGBsrc.size(), INTER_LINEAR|WARP_INVERSE_MAP);
      

      注意:我还没有测试过这段代码,但是我用WARP_INVERSE_MAPwarpPerspective() 做了同样的事情,而且效果很好。

      文档: https://docs.opencv.org/3.4/da/d54/group__imgproc__transform.html#ga0203d9ee5fcd28d40dbc4a1ea4451983

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-12-03
        • 1970-01-01
        • 2015-02-03
        • 2020-03-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-15
        相关资源
        最近更新 更多