在我们之前的学习过程中,使用的都是恒定大小的图像,但是在某些情况下,我们需要使用不同分辨率的(相同)图像。例如,当在图像中搜索某些东西(例如人脸)时,我们不确定对象将以多大的尺寸显示在图像中。在这种情况下,我们将需要创建一组具有不同分辨率的相同图像,并在所有图像中搜索对象,这些具有不同分辨率的图像集称为“图像金字塔”。
本期我们来实现使用图像金字塔将两张图片融合到一张图片。
完成本期内容,你可以:
-
了解图像金字塔的原理和应用
-
掌握上采样和下采样对应的原理和函数
-
掌握高斯金字塔的实现和应用
-
掌握拉普拉斯金字塔的实现和应用
若要运行案例代码,你需要有:
-
操作系统:Ubuntu 16 以上 或者 Windows10
-
工具软件:VScode 或者其他源码编辑器
-
硬件环境:无特殊要求
-
核心库:python 3.6.13, opencv-contrib-python 3.4.11.39,opencv-python 3.4.2.16
点击下载源码
下采样
OpenCV将下采样封装成了cv2.pyrDown()
方法。
函数原型:dst = cv2.pyrDown( src[, dstsize[, borderType]] )
dst为输出图像。
参数描述如下:
- dst:目标图像。
- src: 原始图像。
- dstsize:目标图像的大小。
- borderType:边界类型。
上采样
OpenCV将下采样封装成了cv2.pyrDown()
方法。
函数原型:dst = cv2.pyrDown( src[, dstsize[, borderType]] )
dst为输出图像。
参数描述如下:
- dst:目标图像。
- src: 原始图像。
- dstsize:目标图像的大小。
- borderType:边界类型。
高斯金字塔
高斯金字塔是由底部的最大分辨率图像逐次向下采样得到的一系列图像。最下面的图像分辨率最高,越往上图像分辨率越低。高斯金字塔的向下采样过程是:对于给定的图像先做一次高斯平滑处理,也就是使用一个大小为的卷积核对图像进行卷积操作,然后再对图像采样,去除图像中的偶数行和偶数列,然后就得到一张图片,对这张图片再进行上述操作就可以得到高斯金字塔。
拉普拉斯金字塔
拉普拉斯金字塔是通过源图像减去先缩小后再放大的图像的一系列图像构成的。拉普拉金字塔的图像看起来就像边界图,其中很多像素都是0。他们经常被用在图像压缩中。将降采样之后的图像再进行上采样操作,然后与之前还没降采样的原图进行做差得到残差图。为还原图像做信息的准备。
图像融合
图像金字塔的重要应用就是图像融合,它的具体操作是首先对两张图片分别进行降采样,或者采用高斯金字塔法,当降采样到一定程度后,将两张图片合并,这时候由于在降采样时丢失了一部分边缘信息,因此边缘处不匹配的现象就消失了。之后对合并的图像进行上采样,或者采用拉普拉斯金字塔法,使图像回到原来的大小。此时,边缘处的不匹配现象就会明显降低甚至消失。
具体步骤
使用图像金字塔将下列两张图片进行融合。
步骤一:创建项目工具
创建项目名为使用图像金字塔进行图像融合
,项目根目录下新建code
文件夹储存代码,新建dataset
文件夹储存数据,项目结构如下:
使用图像金字塔进行图像融合 # 项目名称
├── code # 储存代码文件
├── dataset # 储存数据文件
注:如项目结构已存在,无需再创建。
步骤二:加载苹果和橙子的两个图像
- 导入所需模块:OpenCV、NumPy ;
- 读取
dataset
文件夹下的apple.png
和orange.png
图片; - 将两张图像均修改为
515*512
的尺寸;
代码实现
# 导入OpenCV、numpy
import cv2
import numpy as np
# 读取图片
img = cv2.imread("../dataset/apple.png")
img1 = cv2.imread("../dataset/orange.png")
# resize到2的幂次,方便降采样处理
img = cv2.resize(img, (512, 512))
img1 = cv2.resize(img1, (512, 512))
步骤三:定义构建高斯金字塔的函数
- 将原图像复制,作为第一张图像;
- 高斯平滑处理;
- 下采样操作;
- 循环上面两步操作,并将得到的图像储存至列表中。
代码实现
# 定义构建高斯金字塔的函数
def gaussian(ori_image, down_times=2):
# 1:添加第一个图像为原始图像
temp_gau = ori_image.copy()
gaussian_pyramid = [temp_gau]
for i in range(down_times):
# 高斯平滑
gaussian_img = cv2.GaussianBlur(temp_gau, (5, 5), 0, 0)
# 2:连续存储2次下采样,这样高斯金字塔就有3层
temp_gau = cv2.pyrDown(gaussian_img)
gaussian_pyramid.append(temp_gau)
return gaussian_pyramid
步骤四:定义构建拉普拉斯金字塔的函数
- 将高斯金字塔图像列表中的最后一张图像作为第一张图像;
- 上采样操作
- 与之前还没降采样的原图进行做差得到残差图;
- 循环上面两步操作,并将得到的图像储存至列表中。
代码实现
# 定义构建拉普拉斯金字塔的函数
def laplacian(gaussian_pyramid, up_times=2):
laplacian_pyramid = [gaussian_pyramid[-1]]
for i in range(up_times,0, -1):
# i的取值为2,1,0也就是拉普拉斯金字塔有3层
temp_pyrUp = cv2.pyrUp(gaussian_pyramid[i])
temp_lap = cv2.subtract(gaussian_pyramid[i-1], temp_pyrUp)
laplacian_pyramid.append(temp_lap)
return laplacian_pyramid
步骤五:对两张图像分别进行高斯金字塔和拉普拉斯金字塔操作
代码实现
# 第一张图进行高斯金字塔计算
gp1 = gaussian(img, down_times=5)
# 第二张图进行高斯金字塔计算
gp2 = gaussian(img1,down_times=5)
# 第一张图进行拉普拉斯金字塔计算
lp1 = laplacian(gp1,up_times=5)
# # 第二张图进行拉普拉斯金字塔计算
lp2 = laplacian(gp2,up_times=5)
步骤六:图像融合
- 在每个级别中添加第一张图像的左边和第二张图像的右边,组成新的图像;
- 重建图像;
- 展示图像。
# 现在在每个级别中添加左右两半图像
merges = []
for i in range(step + 1):
w, h, d = lp1[i].shape
merge = np.hstack((lp1[i][:, 0:w // 2 - 10 // 2 ** i], lp2[i][:, w // 2 - 10 // 2 ** i:]))
merges.append(merge)
# 现在重建
ls_ = merges[0]
for i in range(1,6):
ls_ = cv2.pyrUp(ls_)
ls_ = cv2.add(ls_, merges[i])
cv2.imshow('Pyramid_blending2.jpg',ls_)
cv2.waitKey()
cv2.destroyAllWindows()
图像金字塔是图像中多尺度表达的一种,最主要用于图像的分割,是一种以多分辨率来解释图像的有效但概念简单的结构。图像金字塔最初用于机器视觉和图像压缩,一幅图像的金字塔是一系列以金字塔形状排列的分辨率逐步降低,且来源于同一张原始图的图像集合。其通过梯次向下采样获得,直到达到某个终止条件才停止采样。金字塔的底部是待处理图像的高分辨率表示,而顶部是低分辨率的近似。我们将一层一层的图像比喻成金字塔,层级越高,则图像越小,分辨率越低。
点击下载源码