通常,我们过去使用的是恒定大小的图像。但是在某些情况下,我们需要使用不同分辨率的(相同)图像。
例如,当在图像中搜索某些东西(例如人脸)时,我们不确定对象将以多大的尺寸显 示在图像中。在这种情况下,我们将需要创建一组具有不同分辨率的相同图像,并在所有图像中搜索对象。
这些具有不同分辨率的图像集称为“图像金字塔”(因为当它们堆叠在底部时,最高分辨 率的图像位于顶部,最低分辨率的图像位于顶部时,看起来像金字塔)。
高斯金字塔,首先将图像进行高斯核卷积,并删除原图中的所有偶数行和偶数列,最终缩小图像
其中,高斯核卷积运算就是对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身和邻域内的其他像素值(券种不同)经过加权平均后得到。常见的 33与 55 高斯核(CV9 2D卷积与图像滤波)
高斯核卷积让临近中心的像素点具有更高的重要度,对周围像素计算加权平均值,如下图所示,其中心位置权重最高为 0.4。
进行向下采样之后,所得到的图像 Gi+1 具有 M/2 * N/2 个像素,只有原图的四分之一。通过对输入的原始图像不停迭代以上步骤就会得到整个金字塔。注意,由于每次向下取样会删除偶数行和列,所以它会不停地丢失图像的信息
import cv2
import matplotlib.pyplot as plt
import numpy as np
img = cv2.imread('img.png')
#经过几次高斯金字塔后
dowm = cv2.pyrDown(img)
dowm1=cv2.pyrDown(dowm)
dowm2=cv2.pyrDown(dowm1)
cv2.imshow('dowm',dowm2)
cv2.waitKey(0)
cv2.destroyAllWindows()
上采样:就是图片放大,使用pryUp函数。上采样的步骤:先将图像在每个方向放大为原来的两倍,新增的行和列用0填充,再使用先前同样的内核与放大后的图像卷积,获得新增像素的近似值。
下采样:就是图片缩小,使用pyrDown函数。下采样步骤:先将图片进行高斯内核卷积,再将所有偶数列去除。
注意:上采样和下采样是不可逆的!
我们把3次经高斯金字塔降分辨率的图打开看看
可见,随着pyrdowm不断降分辨率,图片变得十分模糊了
参考资料:OpenCV计算机视觉学习(7)——图像金字塔(高斯金字塔,拉普拉斯金字塔,图像缩放resize函数
拉普拉斯金字塔由高斯金字塔形成。没有专用功能。拉普拉斯金字塔图像仅像边缘图像。它的大多数元素为零。它们用于图像压缩。拉普拉斯金字塔的层由高斯金字塔的层与高斯金字塔的高层的扩展版本之间的差形成
import cv2
import matplotlib.pyplot as plt
import numpy as np
img = cv2.imread('p2 (4).png')
dowm = cv2.pyrDown(img)
dowm_up = cv2.pyrUp(dowm)
l_1 = img-dowm_up
cv2.imshow('l_1',l_1)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.resize()函数是opencv中专门来调整图片的大小,改变图片尺寸,相比于金字塔,其效果更好
import cv2
import numpy as np
img = cv2.imread('MyPic.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
img2 = cv2.resize(gray,(120,120),interpolation=cv2.INTER_LANCZOS4)
print(img.shape,gray.shape,img2.shape)
cv2.imshow('result',img2)
cv2.waitKey(0)
cv2.destroyAllWindows()
输出结果:(290, 290, 3) (290, 290) (120, 120)
cv2.resize()函数
功能:对图像大小(分辨率)的操作
输入参数:
- 图像名(gray)
- 预缩放的分辨率(120,120),输出的尺寸格式为(宽,高)
- interpolation:这个是指定插值的方式,图像缩放之后,肯定像素要进行重新计算的,就靠这个参数来指定重新计算像素的方式
interpolation有以下几种:
- INTER_NEAREST - 最邻近插值
- INTER_LINEAR - 双线性插值,如果最后一个参数你不指定,默认使用这种方法
- INTER_AREA - 区域插值(使用像素区域关系进行重采样)
- INTER_CUBIC - 三次样条插值 (超过4x4像素邻域内的双立方插值)
- INTER_LANCZOS4 - Lanczos插值(超过8x8像素邻域内的Lanczos插值)
对于插值方法,正常情况下使用默认的双线性插值法就够了。不过这里还是有建议的:若要缩小图像,一般情形下最好用 CV_INTER_AREA
来插值,而若要放大图像,一般情况下最好用 CV_INTER_CUBIC
(效率不高,慢,不推荐使用)或 CV_INTER_LINEAR
(效率较高,速度较快,推荐使用)
几种常用方法的效率为:
最邻近插值>双线性插值>双立方插值>Lanczos插值
但是效率和效果是反比的,所以根据自己的情况酌情使用