在对图像进行操作的过程中,经常会遇到要将图像进行平移或旋转的情况。使用 OpenCV 提供的 cv2.warpAffine()函数实现图像的仿射操作,从而进一步通过仿射实现图像的平移、旋转等操作。
原始图像:

代码-1:(图像的平移)
python
import cv2
import numpy as np
original = cv2.imread('images/original.jpg')
rows ,cols = original.shape[:2]
# 设置平移位置: 向下100像素,向右200像素
M = np.float32([[1,0,100],[0,1,200]])
# 仿射变换
rst = cv2.warpAffine(original,M,(cols,rows))
cv2.imshow('original', original)
cv2.imshow('rst', rst)
cv2.waitKey(0)
cv2.destroyAllWindows()
执行结果:

代码解读:
将原始图像src向右移动100个像素,向下移动200个像素,则对应的关系为dst(x,y)=src(x+100,y+200)
语法格式:
dst(x,y) = src(1x+0 y+100,0x+1 y+200)
根据上述表达式,可以确定对应的转换矩阵M中各个元素的值为:
M=[[1,0,100],[0,1,200]]
将 M 代入到 cv2.warpAffine( src, M, dsize) 函数中,就可以实现图像的平移
代码-2:(图像的旋转)
python
import cv2
original = cv2.imread('images/original.jpg')
rows ,cols = original.shape[:2]
# 获取旋转矩阵:参数1:旋转中心,参数2:旋转角度,参数3:缩放比例
M = cv2.getRotationMatrix2D((cols/2,rows/2),45,0.5)
# 仿射变换
rst = cv2.warpAffine(original,M,(cols,rows))
cv2.imshow('original', original)
cv2.imshow('rst', rst)
cv2.waitKey(0)
cv2.destroyAllWindows()
执行结果:

在使用函数 cv2.warpAffine()对图像进行旋转时,可以通过函数cv2.getRotationMatrix2D()获取转换矩阵。
语法结构:
retval=cv2.getRotationMatrix2D(center, angle, scale)
- center 为旋转的中心点
- angle 为旋转角度,正数表示逆时针旋转,负数表示顺时针旋转
- scale 为变换尺度(缩放大小),该值如果是 1 则图像比例不变。
利用函数 cv2.getRotationMatrix2D()可以直接生成要使用的转换矩阵 M。
代码-3:(复杂的图像变换)
python
import cv2
import numpy as np
original = cv2.imread('images/original.jpg')
rows, cols, ch = original.shape
# 设置变换矩阵: 输入图像的坐标点 (左上、右上、左下)
p1 = np.float32([[0, 0], [cols - 1, 0], [0, rows - 1]])
# 设置变换矩阵: 输出图像的坐标点(左上、右上、左下)
p2 = np.float32([[0, rows * 0.33], [cols * 0.85, rows * 0.2], [cols * 0.15, rows * 0.7]])
M = cv2.getAffineTransform(p1, p2)
rst = cv2.warpAffine(original, M, (cols, rows))
cv2.imshow('original', original)
cv2.imshow('rst', rst)
cv2.waitKey(0)
cv2.destroyAllWindows()
运行结果:

代码解读:
对于更复杂仿射变换 OpenCV 提供了函数 cv2.getAffineTransform()来生成仿射函数 cv2.warpAffine()所使用的转换矩阵 M。
语法格式:
retval=cv2.getAffineTransform(src,dst) 其中:
src 代表输入图像的三个点坐标dst 代表输出图像的三个点坐标。