图像的几何变换是图像处理中常见的操作,包括缩放、旋转、平移和翻转。
一、图像缩放
图像缩放可以通过 cv::resize()
函数实现。可以指定缩放后的图像尺寸或缩放比例。
void resize(InputArray src, OutputArray dst, Size dsize, double fx=0, double fy=0, int interpolation=INTER_LINEAR)
src
,dst
:分别为原图像和扩展缩放后的图像。dsize
:为缩放后图像的大小fx
,fy
:分别为X和Y方向的缩放因子,dszie
和fx
,fy
不能同时为 0interpolation
:插值方法,有以下几种:INTER_NEAREST
- 最近邻插值INTER_LINEAR
- 线性插值(默认)INTER_AREA
- 区域插值INTER_CUBIC
- 三次样条插值INTER_LANCZOS4
-Lanczos
插值
示例如下:
#include <QApplication>
#include <QDebug>// 添加相关头文件和包
#include <opencv2/opencv.hpp>
using namespace cv;int main(int argc, char *argv[])
{QApplication a(argc, argv);// 读取图像cv::Mat src = cv::imread("./test.jpg");if (src.empty()) {qDebug() << "Could not read the image.";return -1;}// 显示原图像cv::imshow("Origin Image", src);// 设置目标图像的尺寸cv::Mat dst;cv::Size newSize(800, 600); // 新的宽度和高度cv::resize(src, dst, newSize);// 显示缩放后的图像cv::imshow("Resized Image", dst);// 等待用户按键后退出cv::waitKey(0);cv::destroyAllWindows();return a.exec();
}
原图和缩放后的图像如下所示:
二、图像平移
图像平移可以通过 cv::warpAffine
函数实现。需要指定平移矩阵。
void warpAffine(InputArray src, OutputArray dst, InputArray M, Size dsize, int flags=INTER_LINEAR, int borderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar())
src
,dst
:分别为输入图像和输出图像M
:仿射矩阵,后面会给出计算方法dst_sz
:输出图像的大小flags
:变换后的要用到的插值方式
另外还需要用到:cv::getAffineTransform
Mat getAffineTransform( InputArray src, InputArray dst )
这个函数可以得到平移、旋转、缩放、投射等一系列操作,实际上是通过前后四个点的位置变化来控制。
src
:输入的 4 个点位dst
:想要仿射变换变成的 4 个位置
示例如下:
#include <QApplication>
#include <QDebug>// 添加相关头文件和包
#include <opencv2/opencv.hpp>
using namespace cv;int main(int argc, char *argv[])
{QApplication a(argc, argv);// 读取图像cv::Mat src = cv::imread("./test.jpg");if (src.empty()) {qDebug() << "Could not read the image.";return 1;}// 显示原始图像cv::imshow("Original Image", src);// 平移和翻转int m = 200; // 左右移动int n = 200; // 上下移动Point2f srcPoints[3], dstPoints[3];srcPoints[0] = Point2f(0, 0); // 左上/原点srcPoints[1] = Point2f(0, src.rows); // 左下角srcPoints[2] = Point2f(src.cols, 0); // 右上角// 平移使用以下3行:dstPoints[0] = Point2f(0 + m, 0 + n);dstPoints[1] = Point2f(0 + m, src.rows + n);dstPoints[2] = Point2f(src.cols + m, 0 + n);// 平移Mat dst;Size dst_sz(src.cols, src.rows);Mat M1 = getAffineTransform(srcPoints, dstPoints); // 创建仿射变换需要的变换矩阵warpAffine(src, dst, M1, dst_sz, 1, 0, Scalar(255, 255, 255));// 显示平移后的图像cv::imshow("Translated Image", dst);// 等待用户按键后退出cv::waitKey(0);cv::destroyAllWindows();return a.exec();
}
原图和平移后的图像如下所示:
三、图像旋转
图像旋转可以通过 cv2.getRotationMatrix2D()
和 cv2.warpAffine()
函数实现。需要指定旋转中心和旋转角度。
Mat getRotationMatrix2D(Point2f center, double angle, double scale)
center
: 旋转中心angle
:旋转弧度,注意要将角度转换成弧度scale
: 缩放比例
示例如下:
#include <QApplication>
#include <QDebug>// 添加相关头文件和包
#include <opencv2/opencv.hpp>
using namespace cv;int main(int argc, char *argv[])
{QApplication a(argc, argv);// 读取图像cv::Mat src = cv::imread("./test.jpg");if (src.empty()) {qDebug() << "Could not read the image.";return -1;}// 显示原图像cv::imshow("Src Image", src);// 旋转中心点,这里是图像中心cv::Point2f center(src.cols / 2.0, src.rows / 2.0);// 旋转角度,这里是45度double angle = 45.0;// 缩放因子,这里是1.0(不缩放)double scale = 1.0;// 获取旋转矩阵cv::Mat rot_mat = cv::getRotationMatrix2D(center, angle, scale);// 计算输出图像的尺寸(可选)cv::Rect bbox = cv::RotatedRect(center, src.size(), angle).boundingRect();cv::Mat rot_dst = cv::Mat(bbox.height, bbox.width, src.type());// 执行旋转操作cv::warpAffine(src, rot_dst, rot_mat, rot_dst.size());// 显示翻转后的图像cv::imshow("Rotated Image", rot_dst);// 等待用户按键后退出cv::waitKey(0);cv::destroyAllWindows();return a.exec();
}
原图和旋转后的图像如下所示:
四、图像翻转
图像翻转可以通过 cv2.flip()
函数实现。可以指定翻转方向(水平、垂直或两者)。
void flip(InputArray src,OutputArray dst,int flipCode
);
参数说明
src
:输入图像,可以是任意类型的单通道或多通道图像。dst
:翻转后的输出图像,将与输入图像具有相同的类型和大小。flipCode
:指定翻转的方式:flipCode > 0
:沿y轴翻转(水平翻转)。flipCode == 0
:沿x轴翻转(垂直翻转)。flipCode < 0
:沿中心翻转(同时沿 x 轴和 y 轴翻转)。
示例如下:
#include <QApplication>
#include <QDebug>// 添加相关头文件和包
#include <opencv2/opencv.hpp>
using namespace cv;int main(int argc, char *argv[])
{QApplication a(argc, argv);// 读取图像cv::Mat img = cv::imread("./test.jpg");if (img.empty()) {qDebug() << "Could not read the image.";return 1;}// 初始化输出矩阵Mat flipped_horizontal, flipped_vertical, flipped_center;// 水平翻转flip(img, flipped_horizontal, 1);// 垂直翻转flip(img, flipped_vertical, 0);// 中心翻转flip(img, flipped_center, -1);// 显示结果imshow("Original Image", img);imshow("Flipped Horizontally", flipped_horizontal);imshow("Flipped Vertically", flipped_vertical);imshow("Flipped Center", flipped_center);// 等待用户按键后退出cv::waitKey(0);cv::destroyAllWindows();return a.exec();
}
原图和翻转后的图像如下所示: