python-openCV学习笔记(4)-几何变换

几何变换是指将一幅图像映射到另外一幅图像内的操作。

缩放

在OpenCV中,使用函数cv2.resize()实现对图像的缩放,该函数的具体形式为:
dst=cv2.resize(src,dsize[,fx[,fy[,interpolation]]])
式中:
dst代表输出的目标图像,该图像的类型与src相同,其大小为dsize(当该值非零时),或者可以通过src.size()、fx、fy计算得到。
src代表需要缩放的原始图像
dsize代表输出图像大小
fx表示水平方向的缩放比例
fy表示垂直方向的缩放比例
interpolation表示插值方式
53bc9cf2db414549a4b5d86d684d6502.png

lena = cv2.imread("lena.jpg")
rows,cols=lena.shape[:2]
size=(int(cols*0.9),int(rows*0.5))
rst=cv2.resize(lena,size)
rst1=cv2.resize(lena,None,fx=2,fy=0.5)
print("lena.shape=",lena.shape)
print("rst.shape=",rst.shape)
print("rst1.shape=",rst1.shape)
cv2.imshow("lena",lena)
cv2.imshow("rst",rst)
cv2.imshow("rst1",rst1)
cv2.waitKey()
cv2.destroyAllWindows()

翻转

在OpenCV中,图像的翻转采用函数cv2.flip()实现,该函数能够实现图像在水平方向翻转、垂直方向翻转、两个方向同时翻转,其语法结构为:
dst=cv2.flip(src,flipCode)
式中:
dst代表和原始图像具有同样大小、类型的目标图像
src代表要处理的原始图像
flipCode代表旋转类型
5b22346106fc4d78a6f568387082551b.png

lena = cv2.imread("lena.jpg")
x=cv2.flip(lena,0)
y=cv2.flip(lena,2)
xy=cv2.flip(lena,-2)
cv2.imshow("lena",lena)
cv2.imshow("x",x)
cv2.imshow("y",y)
cv2.imshow("xy",xy)
cv2.waitKey()
cv2.destroyAllWindows()

仿射

仿射变换是指图像可以通过一系列的几何变换来实现平移、旋转等多种操作。该变换能够保持图像的平直性和平行性。平直性是指图像经过仿射变换后,直线仍然是直线;平行性是指图像在完成仿射变换后,平行线仍然是平行线。
OpenCV中的仿射函数为cv2.warpAffine(),其通过一个变换矩阵(映射矩阵)M实现变换,具体为:
dst (x, y) = src(𝑀11𝑥 + 𝑀12𝑦 + 𝑀13, 𝑀21𝑥 + 𝑀22𝑦 + 𝑀23)
可以采用仿射函数cv2.warpAffine()实现对图像的旋转,该函数的语法格式如下:
dst=cv2.warpAffine(src,M,dsize[,flags[,borderMode[,borderValue]]] )
dst 代表仿射后的输出图像,该图像的类型和原始图像的类型相同。
src 代表要仿射的原始图像。
M 代表一个2×3 的变换矩阵。使用不同的变换矩阵,就可以实现不同的仿射变换。
dsize 代表输出图像的尺寸大小。
flags 代表插值方法,默认为INTER_LINEAR。当该值为WARP_INVERSE_MAP 时,意味着M是逆变换类型,实现从目标图像dst到原始图像src的逆变换。
borderMode 代表边类型,默认为BORDER_CONSTANT。当该值为BORDER_TRANSPARENT时,意味着目标图像内的值不做改变,这些值对应原始图像内的异常值。
borderValue 代表边界值,默认是0。

平移

当实现平移时,向左(右)平移x,向上(下)平移y,其的转换矩阵M为
M = [ 1 0 x 0 1 y ] M=\begin{bmatrix}1&0&x\\0&1&y\\ \end{bmatrix} M=[1001xy]

lena = cv2.imread("lena.jpg")
h,w=lena.shape[:2]
x=100
y=200
M=np.float32([[1,0,x],[0,1,y]])
move=cv2.warpAffine(lena,M,(w,h))
cv2.imshow("lena",lena)
cv2.imshow("move",move)
cv2.waitKey()
cv2.destroyAllWindows()

旋转

在使用函数cv2.warpAffine()对图像进行旋转时,可以通过函数cv2.getRotationMatrix2D()获取转换矩阵,该函数的语法格式为:
retval=cv2.getRotationMatrix2D(center,angle,scale)
center为旋转的中心点
angle为旋转角度,正数表示逆时针旋转,负数表示顺时针旋转。
scale为变换尺度(缩放大小)

lena = cv2.imread("lena.jpg")
h,w = lena.shape[:2]
M=cv2.getRotationMatrix2D((w/2,h/2),45,0.6)
rotate=cv2.warpAffine(lena,M,(w,h))
cv2.imshow("lena",lena)
cv2.imshow("rotation",rotate)
cv2.waitKey()
cv2.destroyAllWindows()

更复杂的仿射变换

对于更复杂仿射变换,OpenCV提供了函数cv2.getAffineTransform()来生成仿射函数cv2.warpAffine()所使用的转换矩阵M,该函数的语法格式为:
retval=cv2.getAffineTransform(src,dst)
式中:
src代表输入图像的三个点坐标
dst代表输出图像的三个点坐标
在该函数中,其参数值 src 和 dst 是包含三个二维数组(x, y)点的数组。上述参数通过函数cv2.getAffineTransform()定义了两个平行四边形。src 和 dst 中的三个点分别对应平行四边形的左上角、右上角、左下角三个点。函数 cv2.warpAffine()以函数 cv2.getAffineTransform()获取的转换矩阵 M 为参数,将 src 中的点仿射到 dst 中。函数 cv2.getAffineTransform()对所指定的点完成映射后,将所有其他点的映射关系按照指定点的关系计算确定。

lena = cv2.imread("lena.jpg")
h,w = lena.shape[:2]
p1=np.float32([[0,0],[w-1,0],[0,h-1]])
p2=np.float32([[0,h*0.3],[w*0.85,h*0.25],[w*0.15,h*0.7]])
M=cv2.getAffineTransform(p1,p2)
rotate=cv2.warpAffine(lena,M,(w,h))
cv2.imshow("lena",lena)
cv2.imshow("rotation",rotate)
cv2.waitKey()
cv2.destroyAllWindows()

透视

仿射变换可以将矩形映射为任意平行四边形,透视变换则可以将矩形映射为任意四边形。透视变换通过函数cv2.warpPerspective()实现,该函数的语法是:
dst=cv2.warpPerspective(src,M,dsize[,flags[,borderMode[,borderValue]]])
式中:
dst代表透视处理后输出图像,该图像和原始图像具有相同的类型。dsize决定输出图像的实际大小。
src代表要透视的图像
M代表一个3*3的变换矩阵
dsize代表输出图像的尺寸大小
flags代表插值方式,默认为INTER_LINEAR,当该值为WARP_INVERSE_MAP时,意味着M是逆变换类型,能实现从目标图像dst到原始图像src的逆变换。具体可选值如下表

borderMode代表边类型,默认为BORDER_CONSTANT,当该值为BORDER_TRANSPARENT时,意味着目标图像内的值不做改变,这些值对应原始图像内的异常值。
borderValue代表边界值,默认为0
与仿射变换一样,同样可以使用一个函数来生成函数cv2.warpPerspective()所使用的转换矩阵。该函数cv2.getPerspectiveTransform(),其语法格式为:
retval=cv2.getPerspectiveTransform(src,dst)
式中:
src代表输入图像的四个点坐标
dst代表输出图像的四个点坐标
需要注意的是,src参数和dst参数是包含四个点的数组,与仿射变换函数cv2.getAffineTransform()中的三个点不同的。

lena = cv2.imread("lena.jpg")
rows,cols=lena.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(lena,M,(cols,rows))
cv2.imshow("lena",lena)
cv2.imshow("dst",dst)
cv2.waitKey()
cv2.destroyAllWindows()

重映射

把一幅图像内的像素点放到另外一幅图像内的指定位置,这个过程称为重映射。OpenCV提供了多种重映射方式,但我们有时会希望使用自定义的方式来完成重映射。
OpenCV内的重映射函数cv2.remap()提供了更方便、更自由的映射方式,其语法格式如下:
dst=cv2.remap(src,map1,map2,interpolation[,borderMode[,borderValue]])
式中:
dst代表目标图像,它和src具有相同的大小和类型
src代表原始图像
map1参数有两种可能的值:
a.表示(x,y)点的一个映射
b.表示CV_16SC2,CV_32FC1,CV_32FC2类型(x,y)点的X值。
map2参数同样有两种可能的值:
a.当map1表示(x,y)时,该值为空。
b.当map2表示(x,y)点的x值时,该值为CV_16UC1,CV_32FC1类型(x,y)点的y值。
Interpolation代表插值方式,这里不支持INTER_AREA方法,具体如下表

borderMode代表边界模式,当该值为BORDER_TRANSPARENT时,表示目标图像内的对应源图像内奇异点的像素不会被改变
borderValue代表边界值,该值默认为0

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.zeros(img.shape,np.float32)
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)
  • 26
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

全栈小菜花

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值