目录

前言

4.1 本章学习目标

4.2 基础概念

4.3 图像缩放 cv2.resize ()

4.4 图像镜像翻转 cv2.flip ()

4.5 图像平移(warpAffine)

4.6 图像旋转

4.7 通用:仿射变换

4.8 本章小结


前言

承接第 3 章色彩空间。本章对图像做空间位置变换:放大缩小、移位、旋转、翻转,理解仿射变换矩阵,全部搭配可运行代码,专栏风格统一。

4.1 本章学习目标

  1. 理解图像几何变换本质:矩阵运算,像素坐标发生改变
  2. 掌握缩放、翻转、平移、旋转 API 使用
  3. 弄懂变换矩阵 M 的作用
  4. 理解仿射变换概念,学会warpAffine通用接口
  5. 区分插值方式,搞懂缩放时插值参数选择

4.2 基础概念

图像几何变换:不修改像素颜色值,只改变每个像素的坐标位置。
OpenCV 绝大多数几何变换底层依靠变换矩阵 M,配合cv2.warpAffine()完成。

注意:图像矩阵坐标规则:左上角为原点(0,0),x 向右增大,y 向下增大。

4.3 图像缩放 cv2.resize ()

缩放改变图像宽高,是最常用操作。

cv2.resize(src, dsize, fx, fy, interpolation)
  • src:输入图像
  • dsize:输出尺寸 (宽度,高度),注意顺序:(width, height),和img.shape(H,W,C)相反!
  • fx:x 方向缩放系数;fy:y 方向缩放系数
  • interpolation 插值算法
  • 什么是插值:

    放大图片:需要补像素,双线性插值画质最柔和、效果最优

    缩小图片:用 INTER_AREA 防模糊失真

常用插值:

INTER_NEAREST(最近邻):直接抄临近像素,放大全是马赛克

INTER_LINEAR(双线性):平滑插值补像素,放大画质清晰自然(默认首选)

INTER_AREA(区域插值):适合缩小图片,抗锯齿

示例代码

import cv2

img = cv2.imread(r"D:\pythoncode2\bigdata_ai40\Image\qie.png")
if img is None:
    print("读取失败")
else:
    h,w = img.shape[:2]
    # 方式1:直接指定输出宽高,主要
    img_resize1 = cv2.resize(img, (400,300))
    # 方式2:按比例缩放,宽高变为原来0.5倍
    img_resize2 = cv2.resize(img, None, fx=0.5, fy=0.5, interpolation=cv2.INTER_AREA)

    cv2.imshow("origin",img)
    cv2.imshow("resize2",img_resize2)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

高频坑:resize(dsize=(w,h)),先宽后高;shape返回(h,w),顺序相反,很容易写反。

4.4 图像镜像翻转 cv2.flip ()

python
cv2.flip(src, flipCode)

  • flipCode = 0:上下翻转
  • flipCode > 0:左右翻转
  • flipCode < 0:同时上下 + 左右翻转
import cv2

img = cv2.imread(r"D:\pythoncode2\bigdata_ai40\Image\qie.png")
img_flip_lr = cv2.flip(img,1)   #左右翻转
img_flip_ud = cv2.flip(img,0)   #上下翻转

cv2.imshow("lr",img_flip_lr)
cv2.imshow("ud",img_flip_ud)
cv2.waitKey(0)
cv2.destroyAllWindows()

实战用途:数据集增强,扩充样本数量。

4.5 图像平移(warpAffine)

图像平移是指在不改变图像大小、角度、形态的前提下,将整张图像沿 X、Y 坐标轴做位置偏移,是最简单的仿射变换。平移操作的核心本质是像素坐标矩阵运算,通过固定的平移变换矩阵,批量修改图像所有像素的坐标位置。平移变换矩阵公式如下:

 
M=\left[\begin{matrix} 1 & 0 & t_x \\ 0 & 1 & t_y \end{matrix}\right]

公式中:t_x 为 X 轴偏移量(正数图像向右偏移,负数向左偏移); t_y  为 Y 轴偏移量(正数图像向下偏移,负数向上偏移)。

import cv2
import numpy as np

img = cv2.imread(r"D:\pythoncode2\bigdata_ai40\Image\qie.png")
h,w = img.shape[:2]

# x向右移50,y向下移30
M = np.float32([[1,0,50],
                [0,1,30]])

img_shift = cv2.warpAffine(img, M, (w, h))

cv2.imshow("shift",img_shift)
cv2.waitKey(0)
cv2.destroyAllWindows()

移出画面的部分直接丢失,空白区域填充黑色。

4.6 图像旋转

cv2.getRotationMatrix2D(center, angle, scale)

  • center:旋转中心点 (x,y)
  • angle:旋转角度,正数逆时针,负数顺时针
  • scale:缩放系数

得到旋转矩阵 M 之后,依然交给warpAffine执行变换。

import cv2
import numpy as np

img = cv2.imread(r"D:\pythoncode2\bigdata_ai40\Image\qie.png")
h,w = img.shape[:2]
# 旋转中心:图片中心点
center = (w//2, h//2)
# 逆时针旋转45度,缩放1倍
M = cv2.getRotationMatrix2D(center, 45, 1)
img_rot = cv2.warpAffine(img, M, (w, h))

cv2.imshow("rot",img_rot)
cv2.waitKey(0)
cv2.destroyAllWindows()

注意:直接旋转后,边角会被裁切;想要完整显示旋转后的图像,需要手动计算新画布尺寸。

4.7 通用:仿射变换

平移、旋转、缩放、剪切均属于仿射变换,底层均为矩阵运算,核心特性:图像直线不变形、平行关系始终保持

cv2.getAffineTransform() 核心作用:无需手动推导变换矩阵,只需输入原图3个不共线关键点变换后对应的3个目标点,即可自动求解出唯一仿射变换矩阵 M,搭配 warpAffine 即可完成全图变换。

核心原理:仿射变换矩阵为 2×3 结构,共6个未知参数;每组对应点可提供2组坐标方程,3组点刚好凑齐6个方程,求解出唯一矩阵。注意:三点不可共线,否则求解失效

常用实战场景

  1. 图像矫正:矫正倾斜文档、工件,通过三点映射拉直图像;
  2. 自定义形变:快速实现图像倾斜、拉伸、剪切,无需手动计算角度、偏移参数;
  3. 数据增强:对图像做随机仿射畸变,扩充深度学习训练样本。
python
import cv2
import numpy as np

img = cv2.imread(r"D:\pythoncode2\bigdata_ai40\Image\qie.png")
h,w = img.shape[:2]

# 原图三个点
src = np.float32([[50,50],[200,50],[50,200]])
# 变换后对应三个点
dst = np.float32([[10,100],[200,50],[100,250]])

M = cv2.getAffineTransform(src, dst)
img_aff = cv2.warpAffine(img, M, (w, h))

cv2.imshow("affine", img_aff)
cv2.waitKey(0)
cv2.destroyAllWindows()

4.8 本章小结

  1. resize缩放、flip翻转是高频简单接口。
  2. 平移、旋转、仿射变换,都生成变换矩阵M,统一交给warpAffine执行。
  3. 仿射变换保证直线、平行关系不变;只要 3 组对应点就可以求解变换矩阵。
  4. 时刻分清:(h,w)来自 shape;接口 dsize 参数是(w,h)

更多推荐