Python OpenCV3 图像操作

来源:互联网 发布:战龙三国左慈进阶数据 编辑:程序博客网 时间:2024/05/17 13:08

今天看看OpenCV3如何对图像进行操作,图像操作主要只对图像进行的各种坐标变换,主要有尺度变换,旋转变换,平移变换以及偏移变换(水平或垂直),这些变换都是针对图像的坐标进行的,而不是图像的像素,可被统称为仿射变换,下面就来看看使用OpenCV如何实现这些变换。下图是冈萨雷斯的《数字图像处理》中对几种变换的说明,作者设图像上一个点表示为(x,y,灰度值),与变换矩阵相乘就会得到(新x,新y,不变的灰度值),所以,对于仿射变换,实际上我们仅需要2X3的矩阵即可,我们不会改变图像的灰度值。


OpenCV提供了resize方法,用来对图像进行比例放大或缩小,代码如下:

#resizeimage = cv2.imread(r'pics/lena.png', cv2.IMREAD_GRAYSCALE)shrink_image = cv2.resize(image, None, fx=0.5, fy=0.5)zoom_image = cv2.resize(image, None, fx=2, fy=2, interpolation=cv2.INTER_LINEAR)plt.subplot(131), plt.imshow(image, 'gray'), plt.title('origin')plt.subplot(132), plt.imshow(shrink_image, 'gray'), plt.title('shrink')plt.subplot(133), plt.imshow(zoom_image, 'gray'), plt.title('zoom')plt.show()

使用resize可以对图像进行尺度变换,如果进行放大,由于图像的像素增加,需要对增加的像素指定插值方式,这里使用了线性插值(cv2.INTER_LINEAR)。之后我们使用matplotlib进行了绘图:


可以看到,缩小后的图像由于像素丢失,放大到与原图像同样大小时,图像出现了一些失真,而放大的图像,使用线性插值后,插入像素值是用其邻点像素值进行估计得到的,所以变相起到了平滑的效果。


OpenCV提供了warpAffine方法进行各种仿射变换,传递一个2X3的矩阵给该函数,可以对感兴趣区域进行对应的变换,下面看例子。

image = cv2.imread(r'pics/lena.png', cv2.IMREAD_GRAYSCALE)# translationtranslation_M = np.array([[1, 0, 20], [0, 1, 20]], dtype=np.float32)translation_image = cv2.warpAffine(image, translation_M, image.shape)# rotationrows, cols = image.shaperotation_M = cv2.getRotationMatrix2D((cols/2, rows/2), 45, 1)rotation_image = cv2.warpAffine(image, rotation_M, image.shape)# offsetoffset_M = np.array([[1, 0.5, 0], [0, 1, 0]], dtype=np.float32)offset_image = cv2.warpAffine(image, offset_M, image.shape)plt.figure(12)plt.subplot(221), plt.imshow(image, 'gray'), plt.title('origin')plt.subplot(222), plt.imshow(translation_image, 'gray'), plt.title('translation')plt.subplot(223), plt.imshow(rotation_image, 'gray'), plt.title('rotation')plt.subplot(224), plt.imshow(offset_image, 'gray'), plt.title('offset')plt.show()

读取原图像后首先进行了平移变换,Python的OpenCV需要借助numpy模块,我们使用numpy创建了一个2X3的二位数组:

[[1,0,20],

 [0,1,20]]

这会将原图像沿x和y方向分别平移20个像素。接下来的旋转和偏移也是同样的原理,只是构造的矩阵有所差别,旋转的比较特殊,为了避免自己计算旋转矩阵中的三角函数值,我们可以使用getRotationMatrix2D方法进行构造。如果去看看cv2模块的接口,我们还能看到一个getAffineTransform方法,使用该方法我们可以使用三个点定制自己的仿射变换矩阵。


上面代码运行结果如下图所示。



原创粉丝点击