win10+Python3.7.3+OpenCV3.4.1入门学习(五)————5.3仿射

Python版本是Python3.7.3,OpenCV版本OpenCV.3.4.1,开发环境为PyCharm

仿射变换是指图像可以通过一系列的几何变换来实现平移、旋转等多种操作。该变换能够保持图像的平直性和平行性。平直性是指图像经过仿射变换后,直线仍然是直线;平行性是指图像在完成仿射变换后,平行线仍然是平行线。
OpenCV中的仿射函数为cv2.warpAffine(),其通过一个变换矩阵(映射矩阵)M实现变换,具体为:
dst(x, y)=src(M11x+M12y+M13, M21x+M22y+M23)
如下图所示,可以通过一个变换矩阵M,将原始图像O变换为仿射图像R。
在这里插入图片描述

因此,可以采用仿射函数cv2.warpAffine()实现对图像的旋转,该函数的语法格式如下:

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

式中:
● dst代表仿射后的输出图像,该图像的类型和原始图像的类型相同。dsize决定输出图像的实际大小。
● src代表要仿射的原始图像。
● M代表一个2×3的变换矩阵。使用不同的变换矩阵,就可以实现不同的仿射变换。
● dsize代表输出图像的尺寸大小。
● flags代表插值方法,默认为INTER_LINEAR。当该值为WARP_INVERSE_MAP时,意味着M是逆变换类型,实现从目标图像dst到原始图像src的逆变换。具体可选值参见表5-1。
● borderMode代表边类型,默认为BORDER_CONSTANT。当该值为BORDER_TRANSPARENT时,意味着目标图像内的值不做改变,这些值对应原始图像内的异常值。
● borderValue代表边界值,默认是0。
通过以上分析可知,在OpenCV中使用函数cv2.warpAffine()实现仿射变换,忽略其可选参数后的语法格式为:

dst = cv2.warpAffine( src , M , dsize )

其通过转换矩阵M将原始图像src转换为目标图像dst:
dst(x, y)=src(M11x+M12y+M13, M21x+M22y+M23)
因此,进行何种形式的仿射变换完全取决于转换矩阵M。下面分别介绍通过不同的转换矩阵M实现的不同的仿射变换。

5.3.1 平移
通过转换矩阵M实现将原始图像src转换为目标图像dst:
dst(x, y)=src(M11x+M12y+M13, M21x+M22y+M23)
将原始图像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中各个元素的值为:
● M11=1
● M12=0
● M13=100
● M21=0
● M22=1
● M23=200
将上述值代入转换矩阵M,得到:
在这里插入图片描述
在已知转换矩阵M的情况下,可以直接利用转换矩阵M调用函数cv2.warpAffine()完成图像的平移。
eg1:设计程序,利用自定义转换矩阵完成图像平移。
程序如下:

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()

运行程序,出现如图5-3所示的运行结果,其中左图是原始图像,右图是移动结果图像。
在这里插入图片描述在这里插入图片描述

5.3.2 旋转
在使用函数cv2.warpAffine()对图像进行旋转时,可以通过函数cv2.getRotationMatrix2D()获取转换矩阵。该函数的语法格式为:

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

式中:
● center为旋转的中心点。
● angle为旋转角度,正数表示逆时针旋转,负数表示顺时针旋转。
● scale为变换尺度(缩放大小)。
利用函数cv2.getRotationMatrix2D()可以直接生成要使用的转换矩阵M。例如,想要以图像中心为圆点,逆时针旋转45°,并将目标图像缩小为原始图像的0.6倍,则在调用函数cv2.getRotationMatrix2D()生成转换矩阵M时所使用的语句为:

M=cv2.getRotationMatrix2D((height/2, width/2),45,0.6)

eg2:设计程序,完成图像旋转。
程序如下:

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()

运行程序,出现如下图所示的运行结果,其中左图是原始图像,右图是旋转结果图像。
在这里插入图片描述在这里插入图片描述

5.3.3 更复杂的仿射变换
5.3.1节和5.3.2节讲的两种仿射变换都比较简单,对于更复杂仿射变换,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()对所指定的点完成映射后,将所有其他点的映射关系按照指定点的关系计算确定。
eg:设计程序,完成图像仿射。
根据题目要求,设计程序如下:

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))完成了从原始图像到目标图像的仿射。
运行程序,出现如下图所示的运行结果,其中左图是原始图像,右图是仿射结果图像。

在这里插入图片描述在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值