OpenCV-Python教程:几何空间变换~缩放、转置、翻转(resize,transpose,flip)

原文链接:http://www.juzicode.com/opencv-python-resize-transpose-flip

返回Opencv-Python教程

OpenCV-Python教程:色彩空间变换 一文中我们介绍了在色彩空间对图像进行转换的方法,比如BGR转换为GRAY格式的灰度图,BGR色彩空间转换为HSV色彩空间,这篇文件将介绍图像在几何空间的转换,包括图片的缩放、转置、翻转等等。

1、缩放resize()

resize()可以实现图片大小的缩小或放大,接口形式:

dst=cv2.resize(src, dsize[, dst[, fx[, fy[, interpolation]]]])
  • 参数含义:
  • src:源图像;
  • dsize:缩放后目标图像的尺寸,如果设置为0,目标图像则使用源图像的尺寸乘以fx和fy得到;dsize优先级高于fx和fy,如果设置了dsize,后面的fx和fy设置无效;
  • fx和fy:dsize未设置的情况下,使用fx和fy分别作为宽度和高度的放大倍数;
  • interpolation:插值方法,默认使用双线性插值cv2.INTER_LINEAR;

下面的例子中第1个resize直接指定新图像的大小为800×800,第2个例子则设置新图像的宽度为原始图像的0.5倍,高度为0.3倍:

import cv2
print('VX公众号: 桔子code / juzicode.com')
print('cv2.__version__:',cv2.__version__)

img1 = cv2.imread('..\\lena.jpg')  

img_ret1 = cv2.resize(img1,(800,800))
print('img_ret1.shape:',img_ret1.shape) 
cv2.imshow('lena-resize',img_ret1)

img_ret2 = cv2.resize(img1,None,fx=0.5,fy=0.3)
print('img_ret2.shape:',img_ret2.shape)
cv2.imshow('lena-resize2',img_ret2)
cv2.waitKey(0)

运行结果:

cv2.__version__: 4.5.2
img_ret1.shape: (800, 800, 3)
img_ret2.shape: (154, 256, 3)

通过设置fx或fy其中一个为1,另外一个为非0非1的值,可以实现图像的“拉伸”效果。

2、转置transpose()

transpose()可以实现像素下标的x和y轴坐标进行对调:dst(i,j)=src(j,i),接口形式:

dst = cv2.transpose(src[, dst])

下面的例子对lena.jpg和opencv-logo.png进行转置:

import cv2
print('VX公众号: 桔子code / juzicode.com')
print('cv2.__version__:',cv2.__version__)

img1 = cv2.imread('..\\lena.jpg') 
img2 = cv2.imread('..\\opencv-logo.png') 

img_ret1 = cv2.transpose(img1)
print('img1[161,199]:    ',img1[161,199])
print('img_ret1[199,161]:',img_ret1[199,161])
cv2.imshow('lena-transpose',img_ret1)

img_ret2 = cv2.transpose(img2)
print('img2[100,200]:    ',img2[100,200])
print('img_ret2[200,100]:',img_ret2[200,100])
cv2.imshow('logo-transpose',img_ret2)
cv2.waitKey(0)

运行结果:

VX公众号: 桔子code / juzicode.com
cv2.__version__: 4.5.2
img1[161,199]:     [109 105 201]
img_ret1[199,161]: [109 105 201]
img2[100,200]:     [  0   0 255]
img_ret2[200,100]: [  0   0 255]

从图像显示效果看,图像以对角线为轴,进行了翻转

我们知道OpenCV的图像在Python接口中是以numpy数组形式存储的,numpy数组也有transpose()转置方法和T属性,是否也可以同numpy数组的转置方法进行转置呢?实测一把:

img1 = cv2.imread('..\\lena.jpg') 
#img_ret1 = cv2.transpose(img1)
img_ret1 = img1.transpose()
print('img1.shape:',img1.shape)
print('img_ret1.shape:',img_ret1.shape)
print('img1[161,199]:    ',img1[161,199])
print('img_ret1[199,161]:',img_ret1[199,161])
cv2.imshow('lena-transpose',img_ret1)
cv2.waitKey(0)

运行结果:

img1.shape: (512, 512, 3)
img_ret1.shape: (3, 512, 512)
img1[161,199]:     [109 105 201]
Traceback (most recent call last):
  File "img-transpose2.py", line 20, in <module>
    print('img_ret1[199,161]:',img_ret1[199,161])
IndexError: index 199 is out of bounds for axis 0 with size 3

运行结果出错了,经过numpy数组的transpose()转置,第0轴和第2轴进行了转置,0轴的大小为3,所以数组下标访问越界了。另外图像shpae属性第3个元素表示的通道号变成了512,而不是原来的3,图像的的通道号要么是1、3或者4,其他的值是没有意义的。

3、翻转flip()

flip()函数可以实现对图像的水平翻转、垂直翻转和双向翻转。函数的接口形式:

dst=cv2.flip(src, flipCode[, dst])
  • 参数含义:
  • src:源图像;
  • flipCode:翻转方式,0为水平轴翻转(上下翻转),大于0为垂直轴翻转(左右翻转),小于0做双向翻转。

下面这个例子对messi图像进行3种形式的翻转,并在matplotlib中显示,注意在matplotlib中显示时需要做色彩空间的转换,因为在matplotlib中是以R-G-B格式组织像素的:

import matplotlib.pyplot as plt
import cv2
print('VX公众号: 桔子code / juzicode.com')
print('cv2.__version__:',cv2.__version__)
plt.rc('font',family='Youyuan',size='9')
plt.rc('axes',unicode_minus='False')

img1 = cv2.imread('..\\messi5.jpg')  
img_ret1 = cv2.flip(img1,0)#水平轴翻转(上下翻转)
img_ret2 = cv2.flip(img1,1)#垂直轴翻转(左右翻转)
img_ret3 = cv2.flip(img1,-1)#双向翻转

fig,ax = plt.subplots(2,2)
ax[0,0].set_title('原图   VX:桔子code')
ax[0,0].imshow(cv2.cvtColor(img1,cv2.COLOR_BGR2RGB)) #matplotlib显示图像为rgb格式
ax[0,1].set_title('上下翻转')
ax[0,1].imshow(cv2.cvtColor(img_ret1,cv2.COLOR_BGR2RGB))
ax[1,0].set_title('左右翻转')
ax[1,0].imshow(cv2.cvtColor(img_ret2,cv2.COLOR_BGR2RGB))
ax[1,1].set_title('双向翻转') 
ax[1,1].imshow(cv2.cvtColor(img_ret3,cv2.COLOR_BGR2RGB))
ax[0,0].axis('off');ax[0,1].axis('off');ax[1,0].axis('off');ax[1,1].axis('off')#关闭坐标轴显示
plt.show() 

运行结果:

 

小结:本教程前面几篇文章介绍的色彩空间转换、图像的加减乘除运算针对的是像素值本身,每个像素的坐标并未发生变化,而几何空间的变换主要涉及的则是图像坐标的变换。

 

扩展阅读:

  1. OpenCV-Python教程

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注