当前位置:   article > 正文

【OpenCV-Python】10.OpenCV的几何变换_三点,图像形变

三点,图像形变

10.OpenCV的几何变换



前言

  几何变换是指对图像执行放大、缩小、旋转等各种操作。


一、缩放

  OpenCV的cv2.resize()函数用于缩放图像。

det = cv2.resize(src, dsize[,dst[,fx[,fy[,interpolation]]]])

dst表示转换后的图像
src表示原图像
dsize表示转换后图像大小
fx表示水平方向的缩放比例
fy表示垂直方向的缩放比例
interpolation表示插值方式
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

  在转换过程中,可能存在一些不能通过转换算法确定值的像素,插值方式决定了如何获得这些像素的值。

插值方式说明
cv2.INTER_NEAREST最近邻差值
cv2.INTER_LINEAR双线性插值(默认插值方式)
cv2.INTER_CUBIC3次样条插值
cv2.INTER_AREA区域插值
cv2.INTER_LANCZOS4LANCZOS插值

  需要注意的是,当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()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

二、翻转

  OpenCV的cv2.flip()函数用于反转图像。

dst = cv2.flip(src,flipCode)

dst表示转换后的图像
src表示原图像
flipCode表示反转类型
  • 1
  • 2
  • 3
  • 4
  • 5
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()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

三、仿射

  放射变换包含了平移、旋转、缩放等操作,其特点是:原图像中的所有平行线在转换后的图像中任然平行。OpenCV的cv2.warpAffine()函数用于实现图像的仿射变换。

dst = cv2.warpAffine(src,M,dsize[,dst[,flags[,borderMode[,broderValue]]]])

dst表示转换后的图像
src表示原图像
M是一个大小为2*3的转换矩阵,使用不同的转换矩阵可实现平移、旋转等多种操作
dsize为转换后图像的大小
flags为插值方式
borderMode为边类型
broderValue为边界值
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

1、平移

  平移是指将图像沿水平或垂直方向移动一定的像素。假设将图像水平移动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]]

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
# 平移
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()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

2、缩放

  假设图像的宽度缩放比例为h,高度缩放比例为v,则图像转换的矩阵运算公式为:

M=[[h,0,0],[0,v,0]]
  • 1
# 缩放
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()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

3、旋转

  OpenCV的cv2.getRotationMatrix2D()函数可用于旋转操作的转换矩阵。

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

center表示原图中旋转中心的坐标
angle表示旋转角度(正:按逆时针方向旋转)
scale目标图像与原图像的大小比例
  • 1
  • 2
  • 3
  • 4
  • 5
# 旋转
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()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

4、三点映射变换

  三点映射变换会将图像转换为任意的平行四边形,cv2.getAffineTransform()用于计算转换矩阵。

m = cv2.getAffineTransform(src, dst)

src为原图中三个点的坐标(左上角、右上角、左下角)
dst为原图像三个点在目标图像中对应坐标
  • 1
  • 2
  • 3
  • 4
# 三点映射变换
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()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

在这里插入图片描述


四、透视

  透视变换会将图像转换为任意的四边形,其特点为:原始图像中的所有直线在转换后的图像中仍然是直线。cv2.warpPerspective()函数用于执行透视变换操作。

m = cv2.warpPerspective(src,M,dsize[,dst[,flags[,borderMode[,broderValue]]]])
  • 1

  OpenCV的cv2.getPerspectiveTransform()函数用于计算透视变换使用的转换矩阵。

m = cv2.getPerspectiveTransform(src, dst)

src为原图中四个点的坐标
dst为原图像四个点在目标图像中对应坐标
  • 1
  • 2
  • 3
  • 4
# 透视
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()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

在这里插入图片描述


五、OpenCV-Python资源下载

OpenCV-Python测试用图片、中文官方文档、opencv-4.5.4源码


总结

  以上内容介绍了OpenCV-Python中几何变换基本操作,有关Python、数据科学、人工智能等文章后续会不定期发布,请大家多多关注,一键三连哟(●’◡’●)。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/86764
推荐阅读
相关标签
  

闽ICP备14008679号