dst = cv2.resize( src, dsize[, fx[, fy[, interpolation]]] )
在 cv2.resize()函数中,目标图像的大小可以通过“参数dsize”或者“参数fx和fy”二者之一来指定,具体介绍如下。
如果指定参数dsize的值,则无论是否指定了参数fx和fy的值,都由参数dsize来决定目标图像的大小。此时需要注意的是,dsize内第1个参数对应缩放后图像的列数(width,即cols),第2个参数对应缩放后图像的行数(height,即行数rows)。
如果参数dsize的值是None,那么目标图像的大小通过参数fx(控制列数)和fy(控制行数)来决定。此时,目标图像的大小为:
dsize=Size(round(fx·src.cols),round(fy·src.rows))
当缩小图像时,使用区域插值方式(INTER_AREA)能够得到最好的效果;当放大图像时,使用三次样条插值(INTER_CUBIC)方式和双线性插值(INTER_LINEAR)方式都能够取得较好的效果。三次样条插值方式速度较慢,双线性插值方式速度相对较快且效果并不逊色。
dst = cv2.flip( src, flipCode )
仿射变换是指图像可以通过一系列的几何变换来实现平移、旋转等多种操作。该变换能够保持图像的平直性和平行性。平直性是指图像经过仿射变换后,直线仍然是直线;平行性是指图像在完成仿射变换后,平行线仍然是平行线。
dst = cv2.warpAffine( src, M, dsize[, flags[, borderMode[, borderValue]]] )
其通过转换矩阵M 将原始图像src 转换为目标图像dst:
dst (x, y) = src(11 + 12 + 13, 21 + 22 + 23)
因此,进行何种形式的仿射变换完全取决于转换矩阵M。下面分别介绍通过不同的转换矩阵M实现的不同的仿射变换。
将原始图像src 向右侧移动100个像素、向下方移动200个像素,则其对应关系为:
dst (x, y) = src (x + 100, y + 200)
将上述表达式补充完整,即:
dst (x, y) = src (1·x + 0·y + 100, 0·x + 1·y + 200)
由此可得转换矩阵M为:
设计程序如下:
import cv2
import numpy as np
img=cv2.imread("lena.bmp")
height,width=img.shape[:2]
x=100
y=200
M = np.float32([[1, 0, x], [0, 1, y]])
move=cv2.warpAffine(img,M,(width,height))
cv2.imshow("original",img)
cv2.imshow("move",move)
cv2.waitKey()
cv2.destroyAllWindows()
在使用函数 cv2.warpAffine()对图像进行旋转时,可以通过函数cv2.getRotationMatrix2D()获取转换矩阵。该函数的语法格式为:
retval=cv2.getRotationMatrix2D(center, angle, scale)
利用函数cv2.getRotationMatrix2D()可以直接生成要使用的转换矩阵M。例如,想要以图像中心为圆点,逆时针旋转45°,并将目标图像缩小为原始图像的0.6 倍:
import cv2
img=cv2.imread("lena.bmp")
height,width=img.shape[:2]
M=cv2.getRotationMatrix2D((width/2,height/2),45,0.6)
rotate=cv2.warpAffine(img,M,(width,height))
cv2.imshow("original",img)
cv2.imshow("rotation",rotate)
cv2.waitKey()
cv2.destroyAllWindows()
对于更复杂仿射变换,OpenCV 提供了函数cv2.getAffineTransform()来生成仿射函数cv2.warpAffine()所使用的转换矩阵M。该函数的语法格式为:
retval=cv2.getAffineTransform(src, dst)
在该函数中,其参数值src和dst是包含三个二维数组(x, y)点的数组。上述参数通过函数cv2.getAffineTransform()定义了两个平行四边形。src和dst中的三个点分别对应平行四边形的左上角、右上角、左下角三个点。函数cv2.warpAffine()以函数cv2.getAffineTransform()获取的转换矩阵M 为参数,将src中的点仿射到dst中。函数cv2.getAffineTransform()对所指定的点完成映射后,将所有其他点的映射关系按照指定点的关系计算确定。
import cv2
import numpy as np
img=cv2.imread('lena.bmp')
rows,cols,ch=img.shape
p1=np.float32([[0,0],[cols-1,0],[0,rows-1]])
p2=np.float32([[0,rows*0.33],[cols*0.85,rows*0.25],[cols*0.15,rows*0.7]])
M=cv2.getAffineTransform(p1,p2)
dst=cv2.warpAffine(img,M,(cols,rows))
cv2.imshow("origianl",img)
cv2.imshow("result",dst)
cv2.waitKey()
cv2.destroyAllWindows()
在本例中,首先构造了两个三分量的点集合p1和p2,分别用来指代原始图像和目标图像内平行四边形的三个顶点(左上角、右上角、左下角)。然后使用M=cv2.getAffineTransform(p1,p2)获取转换矩阵M。接下来,dst=cv2.warpAffine(img,M,(cols,rows))完成了从原始图像到目标图像的仿射。
第三节所讲的仿射变换可以将矩形映射为任意平行四边形,透视变换则可以将矩形映射为任意四边形。
dst = cv2.warpPerspective( src, M, dsize[, flags[, borderMode[, borderValue]]] )
与仿射变换一样,同样可以使用一个函数来生成函数cv2.warpPerspective()所使用的转换矩阵。该函数是cv2.getPerspectiveTransform(),其语法格式为:
retval = cv2.getPerspectiveTransform( src, dst )
需 要 注 意 的 是 , src参数和dst参数是包含四个点的数组, 与仿射变换函数cv2.getAffineTransform()中的三个点是不同的。实际使用中,我们可以根据需要控制src 中的四
个点映射到dst 中的四个点。
import cv2
import numpy as np
img=cv2.imread('demo.bmp')
rows,cols=img.shape[:2]
print(rows,cols)
pts1 = np.float32([[150,50],[400,50],[60,450],[310,450]])
pts2 = np.float32([[50,50],[rows-50,50],[50,cols-50],[rows-50,cols-50]])
M=cv2.getPerspectiveTransform(pts1,pts2)
dst=cv2.warpPerspective(img,M,(cols,rows))
cv2.imshow("img",img)
cv2.imshow("dst",dst)
cv2.waitKey()
cv2.destroyAllWindows()
在本例中,指定原始图像中平行四边形的四个顶点pts1,指定目标图像中矩形的四个顶点pts2,使用M=cv2.getPerspectiveTransform(pts1,pts2)生成转换矩阵M。接下来,使用语句dst=cv2.warpPerspective(img,M,(cols,rows))完成从平行四边形到矩形的转换。
把一幅图像内的像素点放置到另外一幅图像内的指定位置,这个过程称为重映射。OpenCV提供了多种重映射方式,但是我们有时会希望使用自定义的方式来完成重映射。
dst = cv2.remap( src, map1, map2, interpolation[, borderMode[, borderValue]] )
#例:设计程序,使用cv2.remap()完成数组映射,将目标数组内的所有像素点都映射为原始图像内第0 行第3 列上的像素点。
import cv2
import numpy as np
img=np.random.randint(0,256,size=[4,5],dtype=np.uint8)
rows,cols=img.shape
mapx = np.ones(img.shape,np.float32)*3
mapy = np.ones(img.shape,np.float32)*0
rst=cv2.remap(img,mapx,mapy,cv2.INTER_LINEAR)
print("img=\n",img)
print("mapx=\n",mapx)
print("mapy=\n",mapy)
print("rst=\n",rst)
运行程序,出现如下结果:
img=
[[120 183 101 252 219]
[ 51 106 168 221 118]
[147 16 3 14 159]
[219 67 254 16 62]]
mapx=
[[3. 3. 3. 3. 3.]
[3. 3. 3. 3. 3.]
[3. 3. 3. 3. 3.]
[3. 3. 3. 3. 3.]]
mapy=
[[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]]
rst=
[[252 252 252 252 252]
[252 252 252 252 252]
[252 252 252 252 252]
[252 252 252 252 252]]