目录
一、图片镜像旋转
图像的旋转是围绕一个特定点进行的,而图像的镜像旋转则是围绕坐标轴进行的。图像的镜像旋转分为水平翻转、垂直翻转、水平垂直翻转三种。
水平翻转就是将图片的像素点沿y轴翻转,具体到像素点来说就是令其坐标从(x,y)翻转为
(-x,y);垂直翻转就是将图片的像素点沿x轴翻转,具体到像素点来说就是其坐标从(x,y)翻转为(x,-y);水平垂直翻转就是水平翻转和垂直翻转的结合,具体到像素点来说就是其坐标从(x,y)翻转为(-x,-y)。
在OpenCV中,图片的镜像旋转是以图像的中心为原点进行镜像翻转的,也就是说,水平翻转时,图像的左侧和右侧会关于中心点进行交换;垂直翻转时,图像的上侧和下侧会关于中心点进行交换。
API为 cv2.flip(参数1,参数2),参数1为进行操作的图片,参数2有三个可选参数:
0:垂直翻转;大于0:水平翻转;小于0:水平垂直翻转
具体代码示例如下:
import cv2
def test1():
img1 = cv2.imread('./src/1.jpg')
img2 = cv2.flip(img1, 0) #垂直翻转
img3 = cv2.flip(img1, -1) #水平垂直翻转
img4 = cv2.flip(img1, 1) #水平翻转
cv2.imshow("img1", img1)
cv2.imshow("img2", img2)
cv2.imshow("img3", img3)
cv2.imshow("img4", img4)
if __name__=="__main__":
test1()
运行结果:
二、图像缩放
在图像旋转中,我们涉及到图像的缩放比例,但当时只能按照相同的比例对宽和高进行缩放,而现在我们能够进行x轴和y轴上任意比例的独立缩放。这意味着我们可以单独调整图像在某一个方向上的大小,而不会影响到其他方向上的尺寸。
与图像旋转里的缩放的原理一样,图像缩放的原理也是根据需要将原图像的像素数量增加或减少,并通过插值算法来计算新像素的像素值,图像缩放提供了五种插值方法,分别是最近邻插值、双线性插值、像素区域插值、立方插值、Lanczos插值,与图像旋转实验中的五个插值方法相同,这里就不再过多介绍,详细可看我之前写的插值方法。
API为 cv2.resize(img, dsize=None, fx= , fy= , interpolation= ),img表示要进行缩放的图像,dsize表示目标图像的尺寸(宽度和高度),在这里设置为 None 意味着不直接指定新图像的具体尺寸,而是通过接下来的 fx 和 fy 参数来按比例缩放原图像,fx 和 fy 这两个缩放因子分别控制图像水平方向和垂直方向的缩放比例,例如 fx=0.6,那么原图像的宽度将缩小到原来宽度的60%,如果等于2,则原图拉宽2倍,fy同理;interpolation表示插值方法,可选的有五种,常用的是 cv2.INTER_LINEAR 双线性插值。
具体代码示例如下:
def test2():
'''图像缩放'''
img1 = cv2.imread('./src/11.jpg')
img2 = cv2.resize(img1, dsize=None,fx=0.4, fy=0.4, interpolation=cv2.INTER_LINEAR)
#或者直接用dsize指定缩放范围,例如 宽度=215,高度=512:
# img2 = cv2.resize(img1, dsize=(215, 512),interpolation=cv2.INTER_LINEAR)
cv2.imshow("img1", img1)
cv2.imshow("img2", img2)
cv2.waitKey(0)
这里要注意:dsize 的参数顺序是 (width, height),与 img.shape 的 (heigt, width) 相反
运行结果如图:
三、图像矫正
图像矫正是指对图像进行几何变换,使其满足某种标准或消除畸变的过程,原理是透视变换,即图像存在透视畸变时(如从侧面拍摄的书本、车牌等),需要调整为正面视角,通俗的讲,透视变换的作用其实就是改变一下图像里的目标物体的被观察的视角。
与仿射变换相同,透视变换也有自己的透视变换矩阵,计算API为cv2.getPerspectiveTransform(参数1, 参数2),参数1是原图像上需要进行透视变化的四个点的坐标,这四个点用于定义一个原图中的四边形区域;参数2是经过透视变换后,原图像的四个点在新目标图像上的四个新坐标。
图像矫正的API为 cv2.warpPerspective(img, M, dsize, flags, borderMode),其中img是原图像;M 是透视变换矩阵;dsize是输出图像的大小,可以是一个元组;flags 代表插值方法,同样通常选用双线性插值;boderMode 表示边缘填充方式
具体代码示例如下:
def test3():
'''图像矫正'''
img1 = cv2.imread('./src/3.png')
h,w,c = img1.shape #高度 宽度 通道数
#计算透视变换矩阵 cv2.getPerspectiveTransform(参数1, 参数2)
arg1 = np.float32([[178, 100], [487, 134], [124, 267], [473, 308]]) #原图像的四个角点
arg2 = np.float32([[0,0],[w,0],[0,h],[w,h]])
M = cv2.getPerspectiveTransform(arg1,arg2)
# 图像矫正 cv2.warpPerspective(img, M, dsize, flags, borderMode)
img2 = cv2.warpPerspective(img1, M, dsize=(w,h),flags=cv2.INTER_LINEAR)
cv2.imshow("img1", img1)
cv2.imshow("img2", img2)
cv2.waitKey(0)
几个需要注意的点:
1、arg2的点位顺序必须与arg1的一致,如 左上→左上,右上→右上
2、dsize的格式是(宽度,高度),即(w, h)
顺便,这里没写boderMode 是因为用不上,实际上 flags 也不是必需参数
运行结果如下:
这篇到此为止,下一篇是重点的图像噪点消除、图像梯度处理
以上有问题可以指出。