前言
越来越多的开发人员选择基于开源的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函数实现图像旋转的演示。其中图像旋转后适配之前图像帧的问题未进行优化。
其中疑问或错误,欢迎联系交流