在 OpencV中,使用函数 cv2.resize() 实现对图像的缩放,该函数的具体形式为
dst = cv2.resize(src,dsize[,fx[,fy[,interpolation]]])
式中
dst 代表输出的目标图像,该图像的类型与 src相同,其大小为 dsize(当该值非零时), 或者可以通过 src.size()、fx、fy 计算得到
src代表需要缩放的原始图像
dsize代表输出图像大小
fx代表水平方向的缩放比例
fy代表垂直方向的缩放比例。
interpolation 代表插值方式
具体如表
序号 | 类型 | 说明 |
---|---|---|
1 | cv2.INTER_NEAREST | 最近邻插值 |
2 | cv2.INTER_LINEAR | 双线性插值(默认设置) |
3 | cv2.INTER_CUBIC | 三次样条插值,首先对源图像附近的 4×4 近邻区域进行三次样条拟合,然后将目标像素对应的三次样条值作为目标图像对应像素点的值 |
4 | cv2.INTER_AREA | 区域插值,根据当前像素点边区域的像素实现当前像素点的采样,该方法类似最临近插值方式 |
5 | cv2.INTER_LANCZOS4 | 一种使用 8* 8近邻的lanczos插值方法 |
6 | cv2.INTER_LINEAR_EXACT | 位精度双线性插值 |
7 | cv2.WARP_FILL_OUTLIERS | 标志,填补目标图像中的所有像素,如果它们中的一些对应源图像中的奇异点(离群值)则将它们设置为零 |
8 | cv2.WARP_INVERSE_MAP | 标志,逆变换 |
在 cv2.resize() 函数中,目标图像的大小可以通过“参数 dsize ”或者“参数fx 和fy ”二者之一来指定,具体介绍如下
情况 1:通过参数 dsize 指定
如果指定参数 dsize 的值,则无论是否指定了参数fx 和 fy 的值,都由参数 dsize 来决定目标图像的大小
此时需要注意的是, dsize 内第1 个参数对应缩放后图像的宽度(width,即列数 cols,与参数fx相关),第2 个参数对应缩放后图像的高度(height,即行数 rows,与参数fy相关)
指定参数 dsize 的值时,x 方向的缩放大小(参数 fx)为:
(double) dsize.width/src.cols
同时,y 方向的缩放大小(参数 fy)为:
(double) dsize.height/src.rows
情况 2:通过参数fx 和fy 指定
如果参数 dsize 的值是 None,那么目标图像的大小通过参数 fx 和fy 来决定,此时,目标 图像的大小为:
dsize = Size(round(fxsrc.cols), round(fysrc.rows))
插值是指在对图像进行几何处理时,给无法直接通过映射得到值的像素点赋值。例如,将图像放大为原来的2倍,必然会多出一些无法被直接映射值的像素点,对于这些像素点,插值方式决定了如何确定它们的值。除此以外,还会存在一些非整数的映射值,例如,反向映射可能会把目标图像中的像素点值映射到原始图像中的非整数值对应的位置上,当然原始图像内是不可能存在这样的非整数位置的,即目标图像上的该像素点不能对应到原始图像的某个具体位置上,此时也要对这些像素点进行插值处理,以完成映射
通数 cv2.resize()能实现对原始图像的缩放功能,需要注意的是,开始运算前,操作前的目标图像dst 自身的大小、类型与最终得到的目标图像是没有任何关系的,目标图像 dst 的最终大小和类型是通过 src、dsize 、fx、fy 指定的。如果想让原始图像调整为和目标图像一样大,得必须通过上述属性指定
当缩小图像时,使用区域插值方式( INTER_AREA)能够得到最好的效果,当放大图像时,使用三次样条插值( INTER_CUBIC)方式和双线性插值( INTER_LINEAR)方式都能够取得较好的效果。三次择条插值方式速度较慢。双线性插值方式速度相对较快且效果并不逊色
【例 51】设计程序,使用函数 cv2.resize() 对一个数组进行简单缩放
为了方便观察,这里我们尝试直接通过函数 cv2.resize() 来生成一个与原始数组等大小的数组
import cv2
import numpy as np
img=np.ones([2,4,3],dtype=np.uint8)
size=img.shape[:2]
rst=cv2.resize(img,size)
print("img.shape=\n",img.shape)
print("img=\n",img)
print("rst.shape=\n",rst.shape)
print("rst=\n",rst)
'''
在本例中,我们期望通过cv2.resize() 对原始图像进行缩放
img.shape=
(2, 4, 3)
img=
[[[1 1 1]
[1 1 1]
[1 1 1]
[1 1 1]]
[[1 1 1]
[1 1 1]
[1 1 1]
[1 1 1]]]
rst.shape=
(4, 2, 3)
rst=
[[[1 1 1]
[1 1 1]]
[[1 1 1]
[1 1 1]]
[[1 1 1]
[1 1 1]]
[[1 1 1]
[1 1 1]]]
通过程序我们观察到,我们的目的没有达到,目标图像的大小与原始图像的大小并不一致,原始图像的大小是2行4列,目标图像的大小是4行2列
1.目标图像的行数是原始图像的列数
2.目标图像的列数是原始图像的行数
通过以上例题我们进一步确认:函数 cv2.resize()内 dsize 参数与图像 shape,属性在行,列的上是不一致的,或者说
1.在 shape 属性中,第1 个值对应的是行数,第2 个值对应的是列数
2.在 dsize 参数中,第1 个值对应的是列数,第2 个值对应的是行数
我们通常使用等大小的图像进行测试,在这种情况下,可能无法发现 cv2.resize() 函数内数的具体使用方式
在使用cv2.resize() 函数时,要额外注意参数 dsize 的属性顺序问题
【例 5.2】设计程序,使用函数 cv2.resize() 完成一个简单的图像缩放
根据题目要求,设计程序如下:
import cv2
img=cv2.imread("C:\\Users\\Administrator\\Desktop\\opencv\\test.bmp")
rows,cols=img.shape[:2]
size=(int(cols*0.9),int(rows*0.5))
rst=cv2.resize(img,size)
print("img.shape=",img.shape)
print("rst.shape=",rst.shape)
运行结果:
img.shape= (512, 51, 3)
rst.shape= (256, 45, 3)
从程序可以看出:
1.列数变为原来的 0.9倍,计算得到 51×09=45.9,取整得到 45
2.行数变为原来的 0.5倍,计算得到 512×0.5=256
【例 5.3】设计程序,控制函数 cv2.resize的fx 参数、fy 参数,完成图像缩放
根据题目要求,设计程序如下:
import cv2
img=cv2.imread("test.bmp")
rst=cv2.resize(img,None,fx=2,fy=0.5)
print("img.shape=",img.shape)
print("rst.shape=",rst.shape)
从程序可以看出:
1.fx进行的是水平方向的缩放,将列数变为原来的2倍,得到 51×2=102
2.fy进行的是垂度方向的缩放,将行数变为来的 0.5 倍。得到 512×0.5=256