几何变换

学习对图像进行几个变换,例如移动、旋转、仿射变换等

opencv中提供了两个变换函数,cv2.warpAffine和cv2.warpPerspective,使用这两个函数可以实现所有类型的变换;cv2.warpAffine接收的参数是2*3的矩阵,cv2.warpPerspective接收的参数是3*3的矩阵

扩展缩放

扩展缩放只是改变图像的尺寸大小,opencv.resize函数可以实现这个功能;图像的尺寸可以自己动手设置,你可以指定缩放因子;我们可以选择使用不同的插值方法,在缩放的时候我们推荐使用cv2.INTER_AREA, 在扩展的时候我们推荐使用cv2.INTER_CUBIC(慢)和cv2.INTER_LINEAR;在默认情况下所有改变图像尺寸大小的操作使用的插值方法都是cv2.INT

ER_LINEAR

image = cv.imread('D:/2019-02/lena.jpg')
height, width = image.shape[:2]
res = cv.resize(image, (2*width, 2*height), interpolation=cv.INTER_CUBIC)
cv.imshow('image', res)
print(res.shape)
cv.waitKey(0)

运行结果:

shape变为当前图像的二倍

opencv 放射变化 opencv 变形_仿射变换

平移

平移就是将对象换一个位置,如果你要沿(x, y)方向移动,移动的距离是(tx, ty),可以 通过下面的方式构建矩阵:

np.array([[1, 0, tx], [0, 1, ty]])

可以使用这个数组构建这个矩阵(数据类型为np.float32),然后把它传给函数cv.warpAffine()

image = cv.imread('D:/2019-02/lena.jpg')
row, col = image.shape[:2]
W = np.array([[1, 0, 100], [0, 1, 50]], np.float32)
dst = cv.warpAffine(image, W, (col, row))
cv.imshow('image', dst)
cv.imwrite('D:/2019-02/2_lena.jpg', dst)
cv.waitKey(0)

运行结果:

opencv 放射变化 opencv 变形_仿射变换_02

有几个值的注意的点:

  • cv.wrapAffine函数的第三个参数是输出图像的大小,它的格式应该是图像的(宽, 高);但是image.shape返回的时候,输出的顺序是(高, 宽)
  • 矩阵一定是一个2*3的矩阵,而且整个矩阵的dtype一定是np.float32

旋转

image = cv.imread('D:/2019-02/image18.jpg')
row, col = image.shape[:2]
# 第一个参数设定旋转的中心
# 第二个参数设定旋转的角度
# 第三个参数设定缩放因子,1表示不进行缩放
W = cv.getRotationMatrix2D((col/2, row/2), 90, 1)
# 第三个参数为输出的图像尺寸
dst = cv.warpAffine(image, W, (col, row))
cv.imshow('image', dst)
cv.imwrite('D:/2019-02/2_lena.jpg', dst)
cv.waitKey(0)

运行结果:

opencv 放射变化 opencv 变形_仿射变换_03

仿射变换

仿射变换是二维坐标到二维坐标之间的线性变换,并保持二维图像的‘平直性’,转换前平行的直线,转换后依然平行的直线 
 

opencv 放射变化 opencv 变形_仿射变换_04

对于任意一个位置,都有:

opencv 放射变化 opencv 变形_仿射变换_05

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt

image = cv.imread('D:/2019-02/2_lena.jpg')
row, col = image.shape[:2]
pts1 = np.array([[50, 50], [250, 50], [50, 200]], np.float32)
pts2 = np.array([[10, 100], [200, 50], [100, 250]], np.float32)
W = cv.getAffineTransform(pts1, pts2)
dst = cv.warpAffine(image, W, (col, row))
cv.imshow('image', dst)
cv.imwrite('D:/2019-02/2_lena.jpg', dst)
cv.waitKey(0)

运行结果:

opencv 放射变化 opencv 变形_仿射变换_06


 

透视变换

对于视觉变换,我们需要一个3*3的矩阵,在变换前后直线还是直线。要构建这个矩阵,我们需要在图像上找到四个点以及他们自输出图像上的对应位置;这四个点中的任意三个点都不能共线,这个变换矩阵可以由函数cv2.getPerspectiveTransform构建,然后把这个矩阵传给cv2.warpPerspective

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt

image = cv.imread('D:/2019-02/2_lena.jpg')
row, col = image.shape[:2]
pts1 = np.array([[56, 65], [368, 52], [28, 387], [389, 390]], np.float32)
pts2 = np.array([[0, 0], [300, 0], [0, 300], [300, 300]], np.float32)
W = cv.getPerspectiveTransform(pts1, pts2)
dst = cv.warpPerspective(image, W, (300, 300))
cv.imshow('image', dst)
cv.imwrite('D:/2019-02/2_lena.jpg', dst)
cv.waitKey(0)

运行结果:

opencv 放射变化 opencv 变形_二维_07