图像的几何变形
这篇教学会介绍 OpenCV 里的 warpAffine() 和 warpPerspective() 方法,搭配 getPerspectiveTransform()、warpPerspective() 和 getAffineTransform() 方法,就可以将图像进行平移、指定角度旋转或透视的几何变形效果。
快速导览:
因为程序中的 OpenCV 会需要使用镜头或 GPU,所以请使用本机环境 ( 参考:使用 Python 虚拟环境 ) 或使用 Anaconda Jupyter 进行实作 ( 参考:使用 Anaconda ) ,并安装 OpenCV 函数库 ( 参考:OpenCV 函数库 )。
warpAffine() 平移图像
warpAffine() 方法可以将来源的图像,根据指定的“仿射矩阵”,输出成仿射转换后的新图像,矩阵必须采用 numpy 的矩阵格式,使用的方法如下:
cv2.warpAffine(img, M, (w, h))
# img 來源圖像,M 仿射矩陣,(w, h) 圖片長寬
如果要平移图像,可以使用 2x3 的矩阵来实现,下方的程序码执行后,会将图片的垂直与水平方向,移动 100 像素。
import cv2
import numpy as np
img = cv2.imread('meme.jpg')
M = np.float32([[1, 0, 100], [0, 1, 100]]) # 2x3 矩陣,x 軸平移 100,y 軸平移 100
output = cv2.warpAffine(img, M, (480, 360))
cv2.imshow('oxxostudio', output)
getRotationMatrix2D() 旋转图像
getRotationMatrix2D() 方法可以产生旋转指定角度图像的仿射矩阵,再透过 warpAffine() 产生旋转的图像,使用方式如下:
cv2.getRotationMatrix2D((x, y), angle, scale)
# (x, y) 旋轉的中心點,angle 旋轉角度 ( - 順時針,+ 逆時針 ),scale 旋轉後的尺寸
下方的程序码,会产生一张顺时针旋转 45 度的图片。
import cv2
img = cv2.imread('meme.jpg')
M = cv2.getRotationMatrix2D((240, 180), 45, 1) # 中心點 (240, 180),旋轉 45 度,尺寸 1
output = cv2.warpAffine(img, M, (480, 360))
cv2.imshow('oxxostudio', output)
getAffineTransform() 图像仿射变换
getAffineTransform() 方法,可以根据输入图像的三个点,对应输出图像的三个点,产生仿射矩阵,再透过 warpAffine() 产生仿射变换后的图像,使用 2x3 的 numpy 矩阵作为三个点的座标格式,使用方法如下:
cv2.getAffineTransform(輸入影像三個點的座標,輸出影像三個點的座標)
下方的程序码,会将左边的图片,仿射变换成右边的图片。
import cv2
import numpy as np
img = cv2.imread('meme.jpg')
p1 = np.float32([[100,100],[480,0],[0,360]])
p2 = np.float32([[0,0],[480,0],[0,360]])
M = cv2.getAffineTransform(p1, p2)
output = cv2.warpAffine(img, M, (480, 360))
cv2.imshow('oxxostudio', output)
warpPerspective() + getPerspectiveTransform() 图像透视
warpPerspective() 方法为图像透视的方法,根据指定的“透视矩阵”,输出成透视转换后的新图像,使用方法如下:
cv2.warpPerspective(img, M, (w, h))
# img 來源圖像,M 透視矩陣,(w, h) 圖片長寬
getPerspectiveTransform() 方法,可以根据输入图像的四个点,对应输出图像的四个点,产生透视矩阵,再透过 warpPerspective() 产生透视变换后的图像,使用 2x4 的 numpy 矩阵作为四个点的座标格式,使用方法如下:
cv2.getPerspectiveTransform(輸入影像四個點的座標,輸出影像四個點的座標)
下方的程序码,会将左边的图片,透视变换成右边的图片。
import cv2
import numpy as np
p1 = np.float32([[100,100],[480,0],[0,360],[480,360]])
p2 = np.float32([[0,0],[480,0],[0,360],[480,360]])
m = cv2.getPerspectiveTransform(p1,p2)
img = cv2.imread('meme.jpg')
output = cv2.warpPerspective(img, m, (480, 360))
cv2.imshow('oxxostudio', output)
微信扫码关注
抖音扫码关注