opencv 几何空间变换:resize(),transpose(),flip(),warpAffine(),rotate(),warpPerspective()

1.缩放resize()
resize()可以实现图片大小的缩小或放大
dst=cv2.resize(src, dsize[, dst[, fx[, fy[, interpolation]]]])
src:源图像;
dsize:缩放后目标图像的尺寸,如果设置为0,目标图像则使用源图像的尺寸乘以fx和fy得到;dsize优先级高于fx和fy,如果设置了dsize,后面的fx和fy设置无效;
fx和fy:dsize未设置的情况下,使用fx和fy分别作为宽度和高度的放大倍数;
interpolation:插值方法,默认使用双线性插值cv2.INTER_LINEAR;

img_ret1 = cv2.resize(img1,(800,800))
img_ret2 = cv2.resize(img1,None,fx=0.5,fy=0.3)

2.转置transpose()
transpose()可以实现像素下标的x和y轴坐标进行对调:dst(i,j)=src(j,i)
dst = cv2.transpose(src[, dst])

img_ret1 = cv2.transpose(img1)
#图像显示效果看,图像以对角线为轴,进行了翻转

3.翻转flip()
flip()函数可以实现对图像的水平翻转、垂直翻转和双向翻转.
dst=cv2.flip(src, flipCode[, dst])
src:源图像;
flipCode:翻转方式,0为水平轴翻转(上下翻转),大于0为垂直轴翻转(左右翻转),小于0做双向翻转。

```bash
img_ret1 = cv2.flip(img1,0)#水平轴翻转(上下翻转)
img_ret2 = cv2.flip(img1,1)#垂直轴翻转(左右翻转)
img_ret3 = cv2.flip(img1,-1)#双向翻转```
#matplotlib显示 ,需进行通道调换
fig,ax = plt.subplots(2,2)
ax[0,0].set_title('原图')
ax[0,0].imshow(cv2.cvtColor(img1,cv2.COLOR_BGR2RGB)) #matplotlib显示图像为rgb格式
ax[0,1].set_title('上下翻转')
ax[0,1].imshow(cv2.cvtColor(img_ret1,cv2.COLOR_BGR2RGB))
ax[1,0].set_title('左右翻转')
ax[1,0].imshow(cv2.cvtColor(img_ret2,cv2.COLOR_BGR2RGB))
ax[1,1].set_title('双向翻转') 
ax[1,1].imshow(cv2.cvtColor(img_ret3,cv2.COLOR_BGR2RGB))
ax[0,0].axis('off');ax[0,1].axis('off');ax[1,0].axis('off');ax[1,1].axis('off')#关闭坐标轴显示
plt.show() 

4.仿射变换warpAffine()

仿射变换
dst=cv2.warpAffine(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]])
src: 输入图像。
M: 2×3 2行3列变换矩阵。
dsize: 输出图像的大小。
dst: 可选,输出图像,由dsize指定大小,type和src一样。
flags: 可选,插值方法
borderMode: 可选,边界像素模式
borderValue: 可选,边界填充值; 默认为0

4.1 平移
通过手动指定算子M=[[1,0,X],[0,1,Y]]可以实现图像的移位,其中X表示向图像x方向(向右)移动的像素值,Y表示图像向y方向(向下)移动的像素值。

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

plt.rc('font',family='Youyuan',size='9')
plt.rc('axes',unicode_minus='False')

img = cv2.imread('..\\messi5.jpg')
rows,cols,_ = img.shape

M = np.float32([[1,0,100],[0,1,50]])   #右移100-下移50
img_ret1 = cv2.warpAffine(img,M,(cols,rows))
M = np.float32([[1,0,-100],[0,1,-50]]) #左移100-上移50
img_ret2 = cv2.warpAffine(img,M,(cols,rows))
M = np.float32([[1,0,-100],[0,1,50]])  #左移100-下移50
img_ret3 = cv2.warpAffine(img,M,(cols,rows))

fig,ax = plt.subplots(2,2)
ax[0,0].set_title('原图   by VX:桔子code')
ax[0,0].imshow(cv2.cvtColor(img,cv2.COLOR_BGR2RGB)) #matplotlib显示图像为rgb格式
ax[0,1].set_title('右移100-下移50')
ax[0,1].imshow(cv2.cvtColor(img_ret1,cv2.COLOR_BGR2RGB))
ax[1,0].set_title('左移100-上移50')
ax[1,0].imshow(cv2.cvtColor(img_ret2,cv2.COLOR_BGR2RGB))
ax[1,1].set_title('左移100-下移50') 
ax[1,1].imshow(cv2.cvtColor(img_ret3,cv2.COLOR_BGR2RGB))
#ax[0,0].axis('off');ax[0,1].axis('off');ax[1,0].axis('off');ax[1,1].axis('off')#关闭坐标轴显示
plt.show() 

4.2旋转
旋转需要先用getRotationMatrix2D()方法构造出warpAffine()的算子M,getRotationMatrix2D()接口形式:

retval=cv2.getRotationMatrix2D(center, angle, scale)

center:旋转中心位置
angle:旋转角度
scale:缩放比例,不缩放时为1

import matplotlib.pyplot as plt
import numpy as np
import cv2
plt.rc('font',family='Youyuan',size='9')
plt.rc('axes',unicode_minus='False')

img = cv2.imread('mess.jpg')
rows,cols,_ = img.shape

#以图像中心旋转
M = cv2.getRotationMatrix2D(((cols-1)/2.0,(rows-1)/2.0),90,1)#逆时针90度
img_ret1 = cv2.warpAffine(img,M,(cols,rows))
M = cv2.getRotationMatrix2D(((cols-1)/2.0,(rows-1)/2.0),-90,1)#顺时针90度
img_ret2 = cv2.warpAffine(img,M,(cols,rows))
M = cv2.getRotationMatrix2D(((cols-1)/2.0,(rows-1)/2.0),-180,1)#顺时针180度
img_ret3 = cv2.warpAffine(img,M,(cols,rows))

#显示图像
fig,ax = plt.subplots(2,2)
ax[0,0].set_title('VX:桔子code   原图')
ax[0,0].imshow(cv2.cvtColor(img,cv2.COLOR_BGR2RGB)) #matplotlib显示图像为rgb格式
ax[0,1].set_title('逆时针90度')
ax[0,1].imshow(cv2.cvtColor(img_ret1,cv2.COLOR_BGR2RGB))
ax[1,0].set_title('顺时针90度')
ax[1,0].imshow(cv2.cvtColor(img_ret2,cv2.COLOR_BGR2RGB))
ax[1,1].set_title('顺时针180度') 
ax[1,1].imshow(cv2.cvtColor(img_ret3,cv2.COLOR_BGR2RGB))
ax[0,0].axis('off');ax[0,1].axis('off');ax[1,0].axis('off');ax[1,1].axis('off')#关闭坐标轴显示
plt.show() 

4.3矫正getAffineTransform()
getAffineTransform()构建M算子,入参为变换前和变化后的2组坐标点,每组坐标点包含3个位置参数。

5.旋转rotate()

cv2.rotate(src, rotateCode[, dst]) -> dst,其中src为源图像,rotateCode可选3种参数:
cv2.ROTATE_90_CLOCKWISE 顺时针旋转90度
cv2.ROTATE_180 旋转180度,不区分顺时针或逆时针,效果一样
cv2.ROTATE_90_COUNTERCLOCKWISE 逆时针旋转90度,等同于顺时针270度

img_ret1 = cv2.rotate(img,cv2.ROTATE_90_CLOCKWISE)
img_ret2 = cv2.rotate(img,cv2.ROTATE_180)
img_ret3 = cv2.rotate(img,cv2.ROTATE_90_COUNTERCLOCKWISE)

6.透视变换warpPerspective()

透视变换则需要找到4个点构建kernel。cv2.warpPerspective(src,M,dsize[,dst[,flags[,borderMode[,borderValue]]]])->dst
src: 输入图像。
M: 3×3 3行3列变换矩阵。
dsize: 输出图像的大小。
dst: 可选,输出图像,由dsize指定大小,数据类型和src一样。
flags: 可选,插值方法
borderMode: 可选,边界像素模式
borderValue: 可选,边界填充值; 默认为0。

pts1 = np.float32([[192,40],[610,122],[216,363],[465,415]])
pts2 = np.float32([[0,0],[300,0],[0,350],[300,350]])
kernel = cv2.getPerspectiveTransform(pts1,pts2) #该函数构建kernel
img_pers = cv2.warpPerspective(img_src,kernel,(300,350))

仿射变换可以实现图像的平移、旋转和校正;仿射变换方式的旋转会导致图像丢失、出现黑边,rotate()方法可以解决该问题;rotate()实际是通过封装transpose和flip来实现3种角度的旋转,rotate()并不支持其他角度的旋转。

猜你喜欢

转载自blog.csdn.net/aqiangdeba/article/details/129764909