Opencv入门系列四
主要内容
- 缩放
- 翻转
- 仿射变换
- 透视
- 重映射
1.缩放
cv2.resize()函数用于实现图像的缩放,其语法如下:
● dst:缩放后的图像,
图像的类型与src相同,
图像的大小为dsize 或者 可以通过src.size()、fx、fy计算得到。
● src:缩放的原图像。
● dsize:输出图像大小。
● fx:水平方向的缩放比例。
● fy:垂直方向的缩放比例。
● interpolation代表插值方式
关于缩放尺寸的参数传入方式:
方式一:通过fx,fy
-
fx:表示x方向的缩放比例
-
fy:表示y方向的缩放比例
方式二:通过dsize
注意:从img.shape[0:2]获取的参数为[行,列]
传入的 dsize = [列,行]
如下程序:
import cv2 import numpy as np #按照原比例缩放需要注意,行列参数顺序 # 从原始图像获取图像大小信息 npImg = np.random.randint(0,255,[4,3,3],dtype=np.uint8) Rows,Clos = OriShape = npImg.shape[0:2] # OriShape = (4, 3) ChangeImg = cv2.resize(npImg,OriShape) NewShape = ChangeImg.shape[0:2] # NewShape = (3, 4) Size = (int(Rows*0.9),int(Clos*0.5)) ChangeImg2 = cv2.resize(npImg,Size) NewShape2 = ChangeImg2.shape[0:2] ChangeImg3 = cv2.resize(npImg,None,fx=Rows,fy=Clos) #fx x的增缩比例 fy y的增缩比例 NewShape3 = ChangeImg3.shape[0:2] print(npImg) print(ChangeImg) print(ChangeImg2) print(ChangeImg3) print("OriShape = ",OriShape) print("\n") print("NewShape = ",NewShape) print("\n") print("Size",Size) print("\n") print("NewShape3",NewShape3)
从图中的转换的前后的shape信息可以看出其性质。
● 在shape属性中,第1个值对应的是行数,第2个值对应的是列数。
● 在dsize参数中,第1个值对应的是列数,第2个值对应的是行数。
关于插值方式:
插值:插值指的是
①:在放大时,有部分点无法得到对应的映射,需要填充像素点。
②:在缩小时,有部分像素点是非整数索引位置,此时也需要插值处理。
Opencv库提供了一系列的插值方式如下表:
Opencv中默认使用双线性插值方式。
在缩小图像时,使用区域插值方式(INTER_AREA)能够得到最好的效果。
在放大图像时,使用三次样条插值(INTER_CUBIC)方式和双线性插值(INTER_LINEAR)方式都能够取得较好的效果。
2.翻转
cv2.flip()用于图像的水平,垂直方向,其语法如下:
● dst代表和原始图像具有同样大小、类型的目标图像。
● src代表要处理的原始图像。
● flipCode代表旋转类型。
flipCode旋转类型如下:
3.仿射
仿射:变换保持原有的平直性和平行性,用于实现放射可以完成平移、旋转等多种操作。
3.1 平移
cv2.warpAffine()其语法如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jMl7e5lO-1612163236890)(C:\Users\44338\AppData\Roaming\Typora\typora-user-images\image-20210201135943897.png)]
● dst:仿射后的输出图像,该图像的类型和原始图像的类型相同。dsize决定输出图像的实际大小。
● src:要仿射的原始图像。
● M:一个2×3的变换矩阵。使用不同的变换矩阵,就可以实现不同的仿射变换。
● dsize:输出图像的尺寸大小。
● flags:插值方法,默认为INTER_LINEAR。当该值为WARP_INVERSE_MAP时,意味着M是逆变换类型,实现从目标图像dst到原始图像src的逆变换。
● borderMode:边类型,默认为BORDER_CONSTANT。当该值为BORDER_TRANSPARENT时,意味着目标图像内的值不做改变,这些值对应原始图像内的异常值。
● borderValue:边界值,默认是0。
一般情况下,falgs、borderMode、borderValue等参数可以省略,使用默认值
仿射后的矩阵与原始矩阵关系如下式:
M13、M23:通常用于平移操作
M11、M12、M21、M22:通常御用图像的变换
下列程序是一个平移的实例:
import cv2
import numpy as np
lena = cv2.imread("Resources/lena.png",1)
cv2.imshow("lena",lena)
Width,High = lena.shape[0:2]
x = 100
y = 200
M = np.float32([[1,0,x],[0,1,y]]) #M参数是一个np中float32类型的矩阵
wrapLena = cv2.warpAffine(lena,M,dsize=(Width,High))
cv2.imshow("warpLena",wrapLena)
cv2.waitKey(0)
3.2 旋转
cv2.getRotationMatrix2D()获取转换矩阵,用于cv2.warpAffine()中的参数M中。其语法如下:
● center为旋转的中心点。
● angle为旋转角度,正数表示逆时针旋转,负数表示顺时针旋转。
● scale为变换尺度(缩放大小)。
import cv2
import numpy as np
lena = cv2.imread("Resources/lena.png",1)
cv2.imshow("lena",lena)
Width,High = lena.shape[0:2]
RotationCenter = (Width/2,High/2)
#M_Rotation为以原图中心为旋转中心,旋转角度45度,缩小到原来的图像
M_Rotation = cv2.getRotationMatrix2D(RotationCenter,45,0.5)
wrapLena2 = cv2.warpAffine(lena,M_Rotation,dsize=(Width,High))
cv2.imshow("warpLena2",wrapLena2)
cv2.waitKey(0)
3.3 复杂的仿射
OpenCV提供了函数cv2.getAffineTransform()来生成仿射函数cv2.warpAffine()所使用的转换矩阵M。该函数的语法格式为:
● src代表输入图像的三个点坐标。
● dst代表输出图像的三个点坐标。
其参数值src和dst是包含三个二维数组(x, y)点的数组
import cv2
import numpy as np
lena = cv2.imread("Resources/lena.png",1)
cv2.imshow("lena",lena)
Width,High = lena.shape[0:2]
ArrayOri = np.float32([[0,0],[Width-1,0],[0,High-1]])
ArrayNew = np.float32([[0,0],[Width*0.5,0],[0,High*0.5]])
M = cv2.getAffineTransform(ArrayOri,ArrayNew)
wrapLena2 = cv2.warpAffine(lena,M,dsize=(Width,High))
cv2.imshow("warpLena2",wrapLena2)
cv2.waitKey(0)
4. 透视
透视:将矩形映射为任意平行四边形,透视变换则可以将矩形映射为任意四边形,cv2.warpPerspective()实现透视,其语法是:
● dst:透视处理后的输出图像,该图像和原始图像具有相同的类型。dsize决定输出图像的实际大小。
● src:要透视的图像。
● M:一个3×3的变换矩阵。
● dsize:输出图像的尺寸大小。
● flags:插值方法,默认为INTER_LINEAR。当该值为WARP_INVERSE_MAP时,意味着M是逆变换类型,能实现从目标图像dst到原始图像src的逆变换。具体可选值参见表5-1。
● borderMode:边类型,默认为BORDER_CONSTANT。当该值为BORDER_TRANSPARENT时,意味着目标图像内的值不做改变,这些值对应原始图像内的异常值。
● borderValue:边界值,默认是0。
我们可以通过函数cv2.getPerspectiveTransform()来生成函数cv2.warpPerspective()所使用的转换矩阵M:其语法格式如下
● src:输入图像的四个顶点的坐标。
● dst:输出图像的四个顶点的坐标。
5. 重映射
重映射:值将一幅图的像素点的任何位置放到另一幅图像的操作。Opencv库中提供了很多方法实现重映射操作,比如cv2.remap(),其语法格式如下:
● dst代表目标图像,它和src具有相同的大小和类型。
● src代表原始图像。
● map1参数有两种可能的值:
- 表示(x, y)点的一个映射。
- 表示CV_16SC2 , CV_32FC1, CV_32FC2类型(x, y)点的x值。
● map2参数同样有两种可能的值:
- 当map1表示(x, y)时,该值为空。
- 当map1表示(x, y)点的x值时,该值是CV_16UC1,CV_32FC1类型(x, y)点的y值。
● Interpolation代表插值方式,这里不支持INTER_AREA方法。具体值参见表5-1。
● borderMode代表边界模式。当该值为BORDER_TRANSPARENT时,表示目标图像内的对应源图像内奇异点(outliers)的像素不会被修改。
● borderValue代表边界值,该值默认为0。
注意:
①:map1和map2的值都是浮点数。所以需要插值方式提供安全操作。
②:参数map1指代的是像素点所在位置的列号,参数map2指代的是像素点所在位置的行号
下面程序实现了图像的复制和进行x,y镜像
import cv2
import numpy as np
Newnp = np.random.randint(0,100,[3,3],dtype=np.uint8)
rows,clos = Newnp.shape[0:2]
# 必须保证类型为float32
np_x = np.float32(np.ones([3,3],dtype=np.uint8)*2)
np_y = np.float32(np.ones([3,3],dtype=np.uint8)*1)
for i in range(rows):
for j in range(clos):
#np_x[i,j] = j
#np_y[i,j] = i
np_x.itemset((i,j),j)
np_y.itemset((i,j),i)
CopyImg = cv2.remap(Newnp,np_x,np_y,cv2.INTER_LINEAR)
for i in range(rows):
for j in range(clos):
#np_x[i,j] = j
#np_y[i,j] = i
np_x.itemset((i,j),i)
np_y.itemset((i,j),j)
TurnImg = cv2.remap(Newnp,np_x,np_y,cv2.INTER_LINEAR)
print(Newnp)
print(CopyImg)
print(TurnImg)
#print(np2)cv2.imshow("warpLena2",wrapLena2)
cv2.waitKey(0)
不难看出我们还可以使用remap()方法实现x轴镜像,y轴镜像,以及一些更复杂的操作。