opencv-python-学习笔记九(图像几何转换)

opencv提供了2个转换函数,可以对图像进行任意转换。

cv.warpAffine和cv.warpPerspective.第一种采取2*3的矩阵作为输入。第二种采取3*3的矩阵作为输入。

1.缩放

函数:

cv.resize(src, dsize[, dst[, fx[, fy[, interpolation]]]])

参数:

src:输入图像

dsize:目标尺寸,整形,非0

dst:目标图像,大小为dsize,或由src.size()计算而来

fx:水平轴缩放比例,非0

fy:垂直轴缩放比例,非0

interpolation:插值算法,分为以下几种

INTER_NEAREST 
Python: cv.INTER_NEAREST

nearest neighbor interpolation最邻近插值

INTER_LINEAR 
Python: cv.INTER_LINEAR

bilinear interpolation双线性插值

INTER_CUBIC 
Python: cv.INTER_CUBIC

bicubic interpolation双三次插值

INTER_AREA 
Python: cv.INTER_AREA

resampling using pixel area relation. It may be a preferred method for image decimation, as it gives moire'-free results. But when the image is zoomed, it is similar to the INTER_NEAREST method.基于局部像素的重采样

INTER_LANCZOS4 
Python: cv.INTER_LANCZOS4

Lanczos interpolation over 8x8 neighborhood.基于8x8像素邻域的Lanczos插值

INTER_LINEAR_EXACT 
Python: cv.INTER_LINEAR_EXACT

Bit exact bilinear interpolation.位精确双线性插值

INTER_MAX 
Python: cv.INTER_MAX

mask for interpolation codes.插补码掩码

WARP_FILL_OUTLIERS 
Python: cv.WARP_FILL_OUTLIERS

flag, fills all of the destination image pixels. If some of them correspond to outliers in the source image, they are set to zero

WARP_INVERSE_MAP 
Python: cv.WARP_INVERSE_MAP

flag, inverse transformation

For example, linearPolar or logPolar transforms:

  • flag is not set: dst(ρ,ϕ)=src(x,y)
  • flag is set: dst(x,y)=src(ρ,ϕ)

举例

import numpy as np
import cv2 as cv


src = cv.imread('4.jpg')
# method 1
res1 = cv.resize(src, None, fx=1.2, fy=1.2, interpolation=cv.INTER_CUBIC)
# method 2 直接设置输出尺寸
height, width = src.shape[:2]  # 获得原尺寸
res2 = cv.resize(src, (int(0.5*width), int(0.5*height)),interpolation=cv.INTER_CUBIC)
while(1):
    cv.imshow("src", src)
    cv.imshow("res1", res1)
    cv.imshow("res2", res2)
    if cv.waitKey(1) & 0xFF == 27:
        break
cv.destroyAllWindows()

 

平移

平移是物体的移动,如果知道物体平移的坐标(tx,ty),可以创建如下变换矩阵

将其放入类型为np.float32的数组中,将M矩阵赋值给 cv.warpAffine() 函数。即可实现平移

函数

dst=cv.warpAffine(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]])

参数:

src 输入图像
dst 与src同类型的输出图像
M 2×3 的变换矩阵
dsize 输出图像尺寸大小
flags combination of interpolation methods (see InterpolationFlags) and the optional flag WARP_INVERSE_MAP that means that M is the inverse transformation ( dstsrc ).插值矩阵,上一章的表。
borderMode 边界像素模式,默认为BORDER_CONSTANT ,边界按常数填充
borderValue 边界填充值; 默认为0,所以默认情况下填充为黑色

特别注意:dsize参数是指输出图像的宽高,即对应图像的列,行。

举例

import numpy as np
import cv2 as cv


img = cv.imread('4.jpg', 0)
rows, cols = img.shape
M = np.float32([[1, 0, 300], [0, 1, 50]])
dst
= cv.warpAffine(img, M, (cols, rows)) cv.imshow('img', dst) cv.waitKey(0) cv.destroyAllWindows()

旋转

平移和旋转都是仿射变换的特例,所用函数都是cv2.warpAffine,只是转换矩阵M有所不同。

图像旋转θ度是由变换矩阵  M 得到的

 

但是opencv改进了这个矩阵,如下图。使得提供了缩放旋转与可调的旋转中心。

     

上述矩阵表示绕 center.x,center.y 旋转 θ度

 

 函数:

  retval=cv.getRotationMatrix2D(center, angle, scale)获取变换矩阵M

 参数:

center 旋转中心
angle Rotation angle in degrees. Positive values mean counter-clockwise rotation (the coordinate origin is assumed to be the top-left corner).旋转角度,角度为正则表示逆时针旋转
scale 旋转后的缩放系数

举例:

import numpy as np
import cv2 as cv


src = cv.imread('4.jpg', 0)
rows, cols = src.shape
# 旋转中心  旋转角度  缩放系数
M = cv.getRotationMatrix2D(((cols-1) / 2.0,(rows-1)/2.0), 90,1)
# 原图像 变换矩阵 输出图像尺寸中心
dst = cv.warpAffine(src, M, (cols, rows))

while(1):
    cv.imshow('src', src)
    cv.imshow('dst', dst)
    if cv.waitKey(1) & 0xFF == 27:
        break
cv.destroyAllWindows()

 

仿射变换

在仿射变换中,原图像中的所有平行线在输出图像中仍然是平行的,直线仍然是直线,为了找到变换矩阵,我们需要从输入图像中选取三个点,以及它们在输出图像中的对应位置。利用 cv.getAffineTransform创建一个2*3 的变换矩阵,赋值给cv.warpAffine

函数

retval=cv.getAffineTransform(src, dst),获取仿射矩阵M

参数:

src Coordinates of triangle vertices in the source image.原图中3个点所组成的矩阵,数据类型为np.float32
dst Coordinates of the corresponding triangle vertices in the destination image.目标图中对应的3个点所组成的矩阵,数据类型为np.float32                                                         

举例

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


img = cv.imread('4.jpg')
rows, cols, ch = img.shape
#原图3个点的矩阵
pts1 = np.float32([[50, 50], [200, 50], [50, 200]])

#输出图3个点的矩阵
pts2 = np.float32([[10, 100], [200, 50], [100, 250]])
M = cv.getAffineTransform(pts1, pts2) 
dst
= cv.warpAffine(img, M, (cols, rows))
plt.subplot(
121), plt.imshow(img), plt.title('Input')
plt.subplot(
122), plt.imshow(dst), plt.title('Output')
plt.show()

 

透视变换

透视变换。需要一个3*3的变换矩阵,直线在变换之后仍然是直线,但不能保证平行。为了找到这个变换矩阵,我们需要输入图像的4个点和对应的输出图像的点。在4个点中,其中的任意三个点不能连成直线,然后利用 cv.getPerspectiveTransform函数求出变换矩阵最后3*3的变换矩阵作为函数 cv.warpPerspective 的输入,进行变换

 函数:

retval=cv.getPerspectiveTransform(src, dst[, solveMethod])获取转换矩阵M

参数:

src 原图像四边形顶点坐标,数据类型为np.float32                                                                                                       
dst 目标图像对应四边形顶点坐标,数据类型为np.float32
solveMethod DecompTypes

dst=cv.warpPerspective(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]])

参数:

src 输入图像
dst 和src具有相同类型具有dsize大小的输出图像
M 3×3 变换矩阵
dsize 输出图像大小
flags 插值方法,见页首                                                                                                    
borderMode pixel extrapolation method (BORDER_CONSTANT or BORDER_REPLICATE).边界像素模式,默认为BORDER_CONSTANT
borderValue 边界填充值; 默认为0,所以默认情况下填充为黑色

举例:

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


img = cv.imread('4.jpg')
rows, cols, ch = img.shape
pts1 = np.float32([[56, 65], [368, 52], [28, 387], [389, 390]])
pts2 = np.float32([[0, 0], [300, 0], [0, 300], [300, 300]])
M = cv.getPerspectiveTransform(pts1, pts2)
dst = cv.warpPerspective(img, M, (300, 300))
plt.subplot(121), plt.imshow(img), plt.title('Input')
plt.subplot(122), plt.imshow(dst), plt.title('Output')
plt.show()

 

 

posted @ 2019-07-25 11:26  少灬儿郎  Views(1987)  Comments(0Edit  收藏  举报