Bootstrap

【Qt&OpenCV 图像旋转getRotationMatrix2D】


前言

越来越多的开发人员选择基于开源的Qt框架与OpenCV来实现界面和算法,其原因不单单是无版权问题,更多是两个社区的发展蓬勃,可用来学习的资料与例程特别丰富。以下是关于图像旋转的介绍,主要函数:getRotationMatrix2D 和 warpAffine。
软件版本:Qt-5.12.0/OpenCV-4.5.3
平台:Windows10/11–64


一、函数介绍

1、getRotationMatrix2D

函数原型:
cv::getRotationMatrix2D(Point2f center, double angle, double scale);
参数解释:
center:源图像的旋转中心;
angle:旋转角度,正值表示逆时针;
scale:各向同性比例因子;

2、warpAffine

函数原型:
cv::warpAffine(InputArray src, OutputArray dst, InputArray M, Size dsize, int flags=INTER_LINEAR, int borderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar())
参数解释:
src:输入图像;
dst:输出图像,尺寸由dsize指定,图像类型与原图像一致;
M:2*3的变换矩阵;;
dsize:制定图像输出尺寸;
flags:插值算法标识符,有默认值INTER_LINEAR;
borderMode:边界像素模式,有默认值BORDER_CONSTANT;
borderValue:边界取值,有默认值Scalar()即0;

二、演示

1、Qt构建GUI

在这里插入图片描述
如上图创建Rotate的功能按钮QPushButton, QSpinBox用来输入旋转角度;

2、实现代码

rotateBtn按钮的clicked()槽函数:

void MainWindow::on_rotateBtn_clicked()
{
    std::size_t numView = ui->tabWidget->currentIndex() % 4; 	// 获取当前窗口号
    int degree = ui->rotateSpin->value();		// 读取旋转角度值
    if (degree != 0 && !dispMat[numView]->empty())
    {
        // double radian = degree / 180.0 * CV_PI;

        //填充图像
        /*
        int maxBorder = static_cast<int>((cv::max(dispMat[numView]->cols,\
                              dispMat[numView]->rows)*1.414));
        int dx = (maxBorder - dispMat[numView]->cols)/2;
        int dy = (maxBorder - dispMat[numView]->rows)/2;
        cv::copyMakeBorder(*dispMat[numView], *dispMat[numView],
                   dy, dy, dx, dx, cv::BORDER_CONSTANT);
        */

        //旋转
        cv::Point2f center(dispMat[numView]->cols/2, \
                   dispMat[numView]->rows/2);
        cv::Mat affine_matrix = cv::getRotationMatrix2D(center, degree, 1.0);		// 计算旋转矩阵
        cv::warpAffine(*dispMat[numView], *dispMat[numView], \							// 仿射变换
               affine_matrix, dispMat[numView]->size());

        //计算图像旋转后包含图像的最大矩形
        /*
        double sinVal = std::abs(std::sin(radian));
        double cosVal = std::abs(std::cos(radian));
        cv::Size targetSize(static_cast<int>(dispMat[numView]->cols * cosVal +\
                         dispMat[numView]->rows *sinVal),
                static_cast<int>(dispMat[numView]->cols * sinVal +\
                         dispMat[numView]->rows * cosVal));
        */
        //剪掉多余边框
        /*
        int x = std::abs((dispMat[numView]->cols - targetSize.width)) / 2;
        int y = std::abs((dispMat[numView]->rows - targetSize.height)) / 2;
        cv::Rect rect(x, y, targetSize.width, targetSize.height);
        *dispMat[numView] = cv::Mat(*dispMat[numView], rect); // something wrong
        */

        cvtMatPixmap(dispMat, dispPixmap, numView);
        outputInfo(1, tr("Rotate Action Done."));
    }
    else
    {
        outputInfo(2, tr("Please check the Degree or Mat Exist!"));
    }

}


总结

以上是关于利用Qt构建按GUI,利用OpenCV的getRotationMatrix2D和warpAffine函数实现图像旋转的演示。其中图像旋转后适配之前图像帧的问题未进行优化。
参考:
链接: 往期/前文
其中疑问或错误,欢迎联系交流

;