目录
[1. 图像缩放](#1. 图像缩放)
[2. 图像旋转](#2. 图像旋转)
[3. 图像平移](#3. 图像平移)
[1. 缩放效果对比](#1. 缩放效果对比)
[2. 旋转效果](#2. 旋转效果)
[3. 平移效果](#3. 平移效果)
[1. 图像缩放](#1. 图像缩放)
[2. 图像旋转](#2. 图像旋转)
[3. 图像平移](#3. 图像平移)
[1. 性能考虑:](#1. 性能考虑:)
[2. 图像质量:](#2. 图像质量:)
[3. 边界处理:](#3. 边界处理:)
一、引言
几何变换是图像处理中最基础也是最常用的技术之一,它通过对图像进行空间变换来改变图像的几何形态。OpenCV提供了丰富的几何变换函数,本文将详细介绍三种最基本的几何变换:缩放、旋转与平移。
二、核心概念讲解
1. 图像缩放
图像缩放是指按比例放大或缩小图像的尺寸,OpenCV中使用`resize()`函数实现。
插值方法:
`cv2.INTER_NEAREST`:最近邻插值,速度最快但质量较差
`cv2.INTER_LINEAR`:双线性插值,默认方法,质量较好
`cv2.INTER_CUBIC`:双三次插值,质量最好但速度较慢
`cv2.INTER_LANCZOS4`:Lanczos插值,适合放大图像
2. 图像旋转
图像旋转是指将图像围绕某一点旋转一定角度,OpenCV中常用两种方法:
简单旋转:使用`cv2.rotate()`函数,支持90°、180°、270°旋转
任意角度旋转:使用`cv2.getRotationMatrix2D()`获取旋转矩阵,再通过`cv2.warpAffine()`实现
3. 图像平移
图像平移是指将图像沿x轴和y轴方向移动一定距离,需要先构造平移矩阵,再通过`cv2.warpAffine()`实现。
三、代码实现
//python实现
python
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 读取图像
img = cv2.imread('lena.jpg')
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# 1. 图像缩放
# 方法1:指定输出尺寸
resized = cv2.resize(img_rgb, (300, 300), interpolation=cv2.INTER_LINEAR)
# 方法2:指定缩放比例
scaled = cv2.resize(img_rgb, None, fx=1.5, fy=1.5, interpolation=cv2.INTER_CUBIC)
# 2. 图像旋转
# 方法1:简单旋转
rotated_90 = cv2.rotate(img_rgb, cv2.ROTATE_90_CLOCKWISE)
rotated_180 = cv2.rotate(img_rgb, cv2.ROTATE_180)
# 方法2:任意角度旋转
rows, cols, _ = img_rgb.shape
# 构造旋转矩阵:参数(中心坐标, 旋转角度, 缩放比例)
M_rotate = cv2.getRotationMatrix2D((cols/2, rows/2), 45, 1)
rotated_45 = cv2.warpAffine(img_rgb, M_rotate, (cols, rows))
# 3. 图像平移
# 构造平移矩阵:[[1,0,dx],[0,1,dy]]
dx, dy = 50, 50
M_translate = np.float32([[1, 0, dx], [0, 1, dy]])
translated = cv2.warpAffine(img_rgb, M_translate, (cols, rows))
# 显示结果
plt.figure(figsize=(12, 10))
titles = ['Original', 'Resized (300x300)', 'Scaled (1.5x)',
'Rotated 90°', 'Rotated 180°', 'Rotated 45°', 'Translated']
images = [img_rgb, resized, scaled, rotated_90, rotated_180, rotated_45, translated]
for i in range(7):
plt.subplot(3, 3, i+1)
plt.imshow(images[i])
plt.title(titles[i])
plt.axis('off')
plt.tight_layout()
plt.show()
//C++实现
cpp
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main() {
// 读取图像
Mat img = imread("lena.jpg");
if (img.empty()) {
cout << "无法读取图像文件" << endl;
return -1;
}
Mat img_rgb;
cvtColor(img, img_rgb, COLOR_BGR2RGB); // 转换为RGB格式用于显示
// 1. 图像缩放
// 方法1:指定输出尺寸
Mat resized;
resize(img, resized, Size(300, 300), 0, 0, INTER_LINEAR);
// 方法2:指定缩放比例
Mat scaled;
resize(img, scaled, Size(), 1.5, 1.5, INTER_CUBIC);
// 2. 图像旋转
// 方法1:简单旋转
Mat rotated_90, rotated_180;
rotate(img, rotated_90, ROTATE_90_CLOCKWISE);
rotate(img, rotated_180, ROTATE_180);
// 方法2:任意角度旋转
int rows = img.rows;
int cols = img.cols;
// 构造旋转矩阵:参数(中心坐标, 旋转角度, 缩放比例)
Point2f center(cols / 2.0, rows / 2.0);
Mat M_rotate = getRotationMatrix2D(center, 45, 1.0);
Mat rotated_45;
warpAffine(img, rotated_45, M_rotate, Size(cols, rows));
// 3. 图像平移
// 构造平移矩阵:[[1,0,dx],[0,1,dy]]
int dx = 50, dy = 50;
Mat M_translate = (Mat_<float>(2, 3) << 1, 0, dx, 0, 1, dy);
Mat translated;
warpAffine(img, translated, M_translate, Size(cols, rows));
// 显示结果
namedWindow("Original", WINDOW_NORMAL);
namedWindow("Resized (300x300)", WINDOW_NORMAL);
namedWindow("Scaled (1.5x)", WINDOW_NORMAL);
namedWindow("Rotated 90°", WINDOW_NORMAL);
namedWindow("Rotated 180°", WINDOW_NORMAL);
namedWindow("Rotated 45°", WINDOW_NORMAL);
namedWindow("Translated", WINDOW_NORMAL);
imshow("Original", img);
imshow("Resized (300x300)", resized);
imshow("Scaled (1.5x)", scaled);
imshow("Rotated 90°", rotated_90);
imshow("Rotated 180°", rotated_180);
imshow("Rotated 45°", rotated_45);
imshow("Translated", translated);
waitKey(0);
destroyAllWindows();
return 0;
}
四、示例演示
1. 缩放效果对比
最近邻插值:边缘会出现锯齿状
双线性插值:边缘平滑,适合大多数场景
双三次插值:细节保留最好,适合高质量图像处理
2. 旋转效果
90°/180°旋转:计算效率高,无失真
任意角度旋转:可能会产生空白区域,需要根据实际需求调整输出尺寸
3. 平移效果
平移距离可以为正(向右/向下)或负(向左/向上)
平移后超出原图像范围的部分会被裁剪
五、应用场景
1. 图像缩放
调整图像尺寸以适应不同显示设备
图像金字塔构建
目标检测中的多尺度分析
2. 图像旋转
校正倾斜的文档或图像
全景图像拼接
增强数据多样性(数据增强)
3. 图像平移
图像对齐
视频稳定化
物体跟踪
六、注意事项
1. 性能考虑:
大尺寸图像的缩放和旋转可能比较耗时,建议根据实际需求选择合适的插值方法
对于实时应用,优先使用`cv2.INTER_LINEAR`或`cv2.INTER_NEAREST`
2. 图像质量:
放大图像时,使用`cv2.INTER_CUBIC`或`cv2.INTER_LANCZOS4`可获得更好的质量
缩小图像时,`cv2.INTER_AREA`通常能获得较好的结果
3. 边界处理:
旋转和倾斜变换可能会产生空白区域,可以使用`borderMode`参数设置边界填充方式
常用的边界填充方式有`cv2.BORDER_CONSTANT`(常量填充)和`cv2.BORDER_REPLICATE`(复制边界像素)
七、总结
本文详细介绍了OpenCV中三种基本的几何变换:缩放、旋转与平移。通过掌握这些基础技术,可以为更复杂的图像处理任务打下坚实的基础。在实际应用中,需要根据具体需求选择合适的变换方法和参数,以达到最佳的处理效果。
下一篇文章将介绍OpenCV中的仿射变换与透视变换,敬请期待!