|  | 
 
| OpenCV图像旋转 
 图像旋转是指图像按照某个位置转动一定角度的过程,旋转中图像仍保持这原始尺寸。图像旋转后图像的水平对称轴、垂直对称轴及中心坐标原点都可能会发生变换,因此需要对图像旋转中的坐标进行相应转换。 如下图: 
OpenCV图像旋转   
OpenCV图像旋转   
 同时我们要修正原点的位置,因为图像中的坐标原点在图像的左上角,经过旋转后图像的大小会有所变化,原点也需要修正。实现代码如下: 测试代码:复制代码#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
#include <string>
#include <cmath>
using namespace cv;
Mat imgRotate(Mat matSrc, float angle, bool direction)
{
        float theta = angle * CV_PI / 180.0;
        int nRowsSrc = matSrc.rows;
        int nColsSrc = matSrc.cols;
        // 如果是顺时针旋转
        if (!direction)
                theta = 2 * CV_PI - theta;
        // 全部以逆时针旋转来计算
        // 逆时针旋转矩阵
        float matRotate[3][3]{
                {std::cos(theta), -std::sin(theta), 0},
                {std::sin(theta), std::cos(theta), 0 },
                {0, 0, 1}
        };
        float pt[3][2]{
                { 0, nRowsSrc },
                {nColsSrc, nRowsSrc},
                {nColsSrc, 0}
        };
        for (int i = 0; i < 3; i++)
        {
                float x = pt[i][0] * matRotate[0][0] + pt[i][1] * matRotate[1][0];
                float y = pt[i][0] * matRotate[0][1] + pt[i][1] * matRotate[1][1];
                pt[i][0] = x;
                pt[i][1] = y;
        }
        // 计算出旋转后图像的极值点和尺寸
        float fMin_x = min(min(min(pt[0][0], pt[1][0]), pt[2][0]), (float)0.0);
        float fMin_y = min(min(min(pt[0][1], pt[1][1]), pt[2][1]), (float)0.0);
        float fMax_x = max(max(max(pt[0][0], pt[1][0]), pt[2][0]), (float)0.0);
        float fMax_y = max(max(max(pt[0][1], pt[1][1]), pt[2][1]), (float)0.0);
        int nRows = cvRound(fMax_y - fMin_y + 0.5) + 1;
        int nCols = cvRound(fMax_x - fMin_x + 0.5) + 1;
        int nMin_x = cvRound(fMin_x + 0.5);
        int nMin_y = cvRound(fMin_y + 0.5);
        // 拷贝输出图像
        Mat matRet(nRows, nCols, matSrc.type(), Scalar(0));
        for (int j = 0; j < nRows; j++)
        {
                for (int i = 0; i < nCols; i++)
                {
                        // 计算出输出图像在原图像中的对应点的坐标,然后复制该坐标的灰度值
                        // 因为是逆时针转换,所以这里映射到原图像的时候可以看成是,输出图像
                        // 到顺时针旋转到原图像的,而顺时针旋转矩阵刚好是逆时针旋转矩阵的转置
                        // 同时还要考虑到要把旋转后的图像的左上角移动到坐标原点。
                        int x = (i + nMin_x) * matRotate[0][0] + (j + nMin_y) * matRotate[0][1];
                        int y = (i + nMin_x) * matRotate[1][0] + (j + nMin_y) * matRotate[1][1];
                        if (x >= 0 && x < nColsSrc && y >= 0 && y < nRowsSrc)
                        {
                                matRet.at<Vec3b>(j, i) = matSrc.at<Vec3b>(y, x);
                        }
                }
        }
        return matRet;
}
 复制代码 int main()
 {
         std::string strPath = "D:\\MyDocuments\\My Pictures\\OpenCV\";
         Mat matSrc = imread(strPath + "panda.jpg");
         if (matSrc.empty())
                 return 1;
         float angle = 30;
         Mat matRet = imgRotate(matSrc, angle, true);
         imshow("src", matSrc);
         imshow("rotate", matRet);
         // 保存图像
         imwrite(strPath + "rotate_panda.jpg", matRet);
         waitKey();
         return 0;
 }
OpenCV图像旋转   
 | 
 |