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