图像金字塔操作的将是图像的像素问题(图像变清晰了还是模糊了)(本质上有点像图像的放大与缩小一样(前面介绍过的cv2.resize()函数))。
一般来说我们操作的图像是具有固定分辨率的,但是有些情况下,我们需要对同一图像的不同分辨率的子图像进行处理(尤其是在我们需要提取图像特征的时候)。这个时候我们需要创建一组新的图像,这些图像是具有不同分辨率的原始图像,那么我们把这组图像讲座图像金字塔。我们把最大的图像放在底部,最小的放在底部,看起来就像金字塔。如下所示:
详细的介绍有:
Opencv图像金字塔文档
图像金字塔的一个比较明显的应用就是图像匹配中的sift算法。找了一个介绍好的文章,感兴趣的可以看下:
图像匹配算法研究之sift算法
图像金字塔主要有两类:高斯金字塔和拉普拉斯金字塔。
高斯金字塔的顶部是通过将底部图像的连续行与列去掉得到的。每一层图像中的像素值等于下一层图像中对应位置5个像素的高斯加权平均值。这样操作一个M*N的图像就变成了(M/2)*(N/2)的图像,图像的面积就变为原来的1/4,连续进行这样的操作,就会得到一些列的金字塔的图像。Opencv中可以通过函数cv2.pyrDown()和cv2.pyrUp()来构建金字塔。函数cv2.pyrDown()是从一个高分辨率图像变成低分辨率图像的。cv2.pyrDown()函数接受3个参数:
默认情况下直接输入需要操作的图像就可以,他会把图像按缩小1/4的来处理。如:
import cv2
import matplotlib.pyplot as plt
img = cv2.imread('flower.jpg',0) #直接读为灰度图像
img1 = cv2.pyrDown(img)
plt.subplot(121),plt.imshow(img,'gray')
plt.subplot(122),plt.imshow(img1,'gray')
cv2.pyrUp()函数与cv2.pyrDown()函数的功能相反,把金字塔上层的图像变到下一层来,也就是图像变大,但是有一点要注意的是,虽然变大了,但是图像并不能恢复成以前的样子,也就是分辨率上不能达到以前的那种效果(仅仅是变大了而已)。比如对一幅图先cv2.pyrDown()然后再cv2.pyrUp()变回来就可以是:
import cv2
import matplotlib.pyplot as plt
img = cv2.imread('flower.jpg',0) #直接读为灰度图像
img1 = cv2.pyrDown(img)
img2 = cv2.pyrUp(img1)
plt.subplot(131),plt.imshow(img,'gray'),plt.title('original')
plt.subplot(132),plt.imshow(img1,'gray'),plt.title('down')
plt.subplot(133),plt.imshow(img2,'gray'),plt.title('up')
可以看到经过金字塔一上一下变换后,图像的大小不变,然而图像的清晰度变差了(这也是可以理解的,好的可以变成坏的,但是坏的想变成好的那是不可能的)。
图像的拉普拉斯金字塔可以由图像的高斯金字塔得到,转换的公式为:
import cv2
import matplotlib.pyplot as plt
img = cv2.imread('flower.jpg',0) #直接读为灰度图像
img1 = cv2.pyrDown(img)#高斯金字塔
temp_img1 = cv2.pyrDown(img1)
temp = cv2.pyrUp(temp_img1)
img2 = img1 - temp #拉普拉斯金字塔
plt.subplot(131),plt.imshow(img,'gray')
plt.subplot(132),plt.imshow(img1,'gray')
plt.subplot(133),plt.imshow(img2,'gray')