10.OpenCV的几何变换
几何变换是指对图像执行放大、缩小、旋转等各种操作。
OpenCV的cv2.resize()函数用于缩放图像。
det = cv2.resize(src, dsize[,dst[,fx[,fy[,interpolation]]]])
dst表示转换后的图像
src表示原图像
dsize表示转换后图像大小
fx表示水平方向的缩放比例
fy表示垂直方向的缩放比例
interpolation表示插值方式
在转换过程中,可能存在一些不能通过转换算法确定值的像素,插值方式决定了如何获得这些像素的值。
插值方式 | 说明 |
---|---|
cv2.INTER_NEAREST | 最近邻差值 |
cv2.INTER_LINEAR | 双线性插值(默认插值方式) |
cv2.INTER_CUBIC | 3次样条插值 |
cv2.INTER_AREA | 区域插值 |
cv2.INTER_LANCZOS4 | LANCZOS插值 |
需要注意的是,当dsize不为None时,不管是否设置了fx和fy的参数,都由dsize来确定目标图像的大小,格式为(width,height)。
img = cv2.imread('lena_small.jpg')
# 等比缩放
width = 256
high = int(img.shape[0]*(width/img.shape[1]))
img1 = cv2.resize(img, (width, high), interpolation=cv2.INTER_LINEAR)
img2 = cv2.resize(img, (width, high), interpolation=cv2.INTER_NEAREST)
img3 = cv2.resize(img, (width, high), interpolation=cv2.INTER_AREA)
img4 = cv2.resize(img, (width, high), interpolation=cv2.INTER_CUBIC)
img5 = cv2.resize(img, (width, high), interpolation=cv2.INTER_LANCZOS4)
interpolation = ['LINEAR', 'NEAREST', 'AREA', 'CUBIC', 'LANCZOS4']
Img = [img1, img2, img3, img4, img5]
for i in range(5):
cv2.imwrite(str(interpolation[i]+'.png'), Img[i])
cv2.imshow(str(interpolation[i]), Img[i])
k = cv2.waitKey()
if k == 27:
cv2.destroyAllWindows()
OpenCV的cv2.flip()函数用于反转图像。
dst = cv2.flip(src,flipCode)
dst表示转换后的图像
src表示原图像
flipCode表示反转类型
flipCode | 说明 |
---|---|
0 | 绕x轴翻转(垂直翻转) |
1 | 绕y轴翻转(水平翻转) |
-1 | 绕x轴和y轴翻转(垂直和水平翻转) |
img = cv2.imread('lena.jpg')
# 水平翻转-->1
# 垂直翻转-->0
# 水平+垂直翻转-->-1
img1 = cv2.flip(img, 1)
img2 = cv2.flip(img, 0)
img3 = cv2.flip(img, -1)
flip = ['1', '0', '-1']
Img = [img1, img2, img3]
for i in range(3):
cv2.imwrite(str(flip[i]+'.png'), Img[i])
cv2.imshow(str(flip[i]), Img[i])
k = cv2.waitKey(0)
if k == 27:
cv2.destroyAllWindows()
放射变换包含了平移、旋转、缩放等操作,其特点是:原图像中的所有平行线在转换后的图像中任然平行。OpenCV的cv2.warpAffine()函数用于实现图像的仿射变换。
dst = cv2.warpAffine(src,M,dsize[,dst[,flags[,borderMode[,broderValue]]]])
dst表示转换后的图像
src表示原图像
M是一个大小为2*3的转换矩阵,使用不同的转换矩阵可实现平移、旋转等多种操作
dsize为转换后图像的大小
flags为插值方式
borderMode为边类型
broderValue为边界值
平移是指将图像沿水平或垂直方向移动一定的像素。假设将图像水平移动m个像素,垂直移动n个像素,则图像转换的矩阵运算公式为:
dst(x,y) = src(x + m, y + n)
等价于
dst(x,y) = src(1 · x + 0 · y + m, 0 · x + 1 · y + n)
所以,转换矩阵为
M=[[1,0,m],[0,1,n]]
# 平移
img = cv2.imread('lena.jpg')
# 往右平移25像素,往下平移50像素
M1 = np.float32([[1, 0, 25], [0, 1, 50]])
# 往左平移25像素,往上平移50像素
M2 = np.float32([[1, 0, -25],[0, 1, -50]])
shifted1 = cv2.warpAffine(img, M1, (img.shape[1], img.shape[0]))
shifted2 = cv2.warpAffine(img, M2, (img.shape[1], img.shape[0]))
cv2.imshow('shifted1', shifted1)
cv2.imshow('shifted2', shifted2)
cv2.waitKey(0)
cv2.destroyAllWindows()
假设图像的宽度缩放比例为h,高度缩放比例为v,则图像转换的矩阵运算公式为:
M=[[h,0,0],[0,v,0]]
# 缩放
img = cv2.imread('lena.jpg')
# 宽度高度均缩小50%
M1 = np.float32([[0.5, 0, 0], [0, 0.5, 0]])
shifted = cv2.warpAffine(img, M1, (img.shape[1], img.shape[0]))
cv2.imshow('shifted', shifted)
cv2.waitKey(0)
cv2.destroyAllWindows()
OpenCV的cv2.getRotationMatrix2D()函数可用于旋转操作的转换矩阵。
m = cv2.getRotationMatrix2D(center,angle,scale)
center表示原图中旋转中心的坐标
angle表示旋转角度(正:按逆时针方向旋转)
scale目标图像与原图像的大小比例
# 旋转
img = cv2.imread('lena.jpg')
# (cX,cY)-->旋转中心点
(h, w) = img.shape[:2]
(cX, cY) = (h / 2, w / 2)
# 45-->逆时针旋转45度, -45-->顺时针旋转45度
# 1.0-->大小不变, 2.0-->放大, 0.5-->缩小
M1 = cv2.getRotationMatrix2D((cX, cY), 45, 1.0)
M2 = cv2.getRotationMatrix2D((cX, cY), -45, 1.0)
M3 = cv2.getRotationMatrix2D((cX, cY), 45, 2.0)
M4 = cv2.getRotationMatrix2D((cX, cY), 45, 0.5)
M5 = cv2.getRotationMatrix2D((cX-25, cY-25), 45, 1.0)
img1 = cv2.warpAffine(img, M1, (w,h))
img2 = cv2.warpAffine(img, M2, (w,h))
img3 = cv2.warpAffine(img, M3, (w,h))
img4 = cv2.warpAffine(img, M4, (w,h))
img5 = cv2.warpAffine(img, M5, (w,h))
cv2.imshow('img1', img1)
cv2.imshow('img2', img2)
cv2.imshow('img3', img3)
cv2.imshow('img4', img4)
cv2.imshow('img5', img5)
cv2.waitKey(0)
cv2.destroyAllWindows()
三点映射变换会将图像转换为任意的平行四边形,cv2.getAffineTransform()用于计算转换矩阵。
m = cv2.getAffineTransform(src, dst)
src为原图中三个点的坐标(左上角、右上角、左下角)
dst为原图像三个点在目标图像中对应坐标
# 三点映射变换
img = cv2.imread('lena.jpg')
cv2.imshow('img',img)
# 原图中的3个点
src = np.float32([[0, 0], [img.shape[1] - 10, 0], [0, img.shape[0] - 1]])
#设置3个点在目标图像中的坐标
dst = np.float32([[50, 50], [img.shape[1] - 100, 80], [100, img.shape[0] - 100]])
M = cv2.getAffineTransform(src, dst)
img1 = cv2.warpAffine(img, M , (img.shape[1], img.shape[0]))
cv2.imshow('warpAffine',img1)
cv2.waitKey(0)
cv2.destroyAllWindows()
透视变换会将图像转换为任意的四边形,其特点为:原始图像中的所有直线在转换后的图像中仍然是直线。cv2.warpPerspective()函数用于执行透视变换操作。
m = cv2.warpPerspective(src,M,dsize[,dst[,flags[,borderMode[,broderValue]]]])
OpenCV的cv2.getPerspectiveTransform()函数用于计算透视变换使用的转换矩阵。
m = cv2.getPerspectiveTransform(src, dst)
src为原图中四个点的坐标
dst为原图像四个点在目标图像中对应坐标
# 透视
img = cv2.imread('lena.jpg')
cv2.imshow('img',img)
# 原图中的4个点
src = np.float32([[0, 0], [img.shape[1]-10, 0],
[0, img.shape[0]-1], [img.shape[1]-1,img.shape[0]-1]])
#设置4个点在目标图像中的坐标
dst = np.float32([[50, 50], [img.shape[1]-50, 80],
[50, img.shape[0]-100], [img.shape[1]-100,img.shape[0]-10]])
M = cv2.getPerspectiveTransform(src, dst)
img1 = cv2.warpPerspective(img, M , (img.shape[1], img.shape[0]))
cv2.imshow('warpPerspective',img1)
cv2.waitKey(0)
cv2.destroyAllWindows()
OpenCV-Python测试用图片、中文官方文档、opencv-4.5.4源码
以上内容介绍了OpenCV-Python中几何变换基本操作,有关Python、数据科学、人工智能等文章后续会不定期发布,请大家多多关注,一键三连哟(●’◡’●)。