OpenCV几何变换详解:缩放、旋转与平移

目录

一、引言

二、核心概念讲解

[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中的仿射变换与透视变换,敬请期待!

相关推荐
小毅&Nora2 小时前
【AI微服务】【Spring AI Alibaba】 ④ 深度实战:从零构建通义千问聊天服务(2025 最新版)
人工智能·微服务·spring ai
糖葫芦君2 小时前
Lora模型微调
人工智能·算法
gallonyin2 小时前
【AI智能体】Cline核心文件编辑工具分析(replace_in_file)
人工智能·架构·智能体
roamingcode2 小时前
IncSpec 面向 AI 编程助手的增量规范驱动开发工具
人工智能·agent·claude·cursor·fe·规范驱动开发
此处不留情2 小时前
从零构建智能水果识别系统:数据模块深度解析
人工智能·pytorch
YJlio2 小时前
2025 我用 Sysinternals 打通 Windows 排障“证据链”:开机慢 / 安装失败 / 磁盘暴涨(三个真实案例复盘)
人工智能·windows·笔记
Felaim2 小时前
【自动驾驶】SparseWorld-TC 论文总结(理想)
人工智能·机器学习·自动驾驶
2401_841495642 小时前
【自然语言处理】自然语言理解的 “问题识别之术”
人工智能·自然语言处理·情感分类·决策·自动问答·自然语言理解·多源信息
Coder_Boy_2 小时前
【人工智能应用技术】-基础实战-小程序应用(基于springAI+百度语音技术)智能语音开关
人工智能·百度·小程序