目录
1 图像金字塔简介
2 向下取样——pyrDown()
2.1 基础理论
2.2 代码示例
3 向上取样——pyrUp()
3.1 基础理论
3.2 代码示例
4 Laplacian 金字塔
4.1 基础理论
4.2 代码示例
参考资料
以多个分辨率来表示图像的一种有效且概念简单的结构是图像金字塔。图像金字塔最初用于机器视觉和图像压缩,一个图像金字是一系列以金字塔形状排列的、分辨率逐步降低的图像集合。
如图下图所示,它包括了四层图像,将这一层一层的图像比喻成金字塔。图像金字塔可以通过梯次向下采样获得,直到达到某个终止条件才停止采样,在向下采样中,层级越高,则图像越小,分辨率越低。
生成图像金字塔主要包括两种方式:向下取样 和 向上取样。
如下图所示:
向下取样:将图像从G0转换为G1、G2、G3,图像分辨率不断降低的过程;
向上取样:将图像从G3转换为G2、G1、G0,图像分辨率不断增大的过程。
下面将依次介绍向下取样 和 向上取样。
在图像向下取样中,一般分两步:
(1)对图像Gi进行高斯卷积核(高斯滤波);
(2)删除所有的偶数行和列。
其中,高斯核卷积运算(高斯滤波)就是对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身和邻域内的其他像素值(权重不同)经过加权平均后得到。常见的 33 和 55 高斯核如下:
关于高斯滤波的详细过程,可以参见博客:图像平滑 (均值滤波、中值滤波和高斯滤波)
如下图所示,向下取样后,原始图像 具有 MN 个像素,进行向下取样之后,所得到的图像 +1 具有 M/2 N/2 个像素,只有原图的四分之一。通过对输入的原始图像不停迭代以上步骤就会得到整个金字塔。
注:由于每次向下取样会删除偶数行和列,所以它会不停地丢失图像的信息。
下面是向下取样的图像,可以看到图像不断缩小。
在OpenCV中,向下取样使用的函数为pyrDown(),其函数用法如下所示:
dst = pyrDown(src[, dst[, dstsize[, borderType]]])
其中,参数:
src 表示输入图像;
dst 表示输出图像,和输入图像具有一样的尺寸和类型;
dstsize 表示输出图像的大小,默认值为Size();
borderType 表示像素外推方法,详见cv::bordertypes 。
(1)一次向下采样
代码如下所示:
-
# -*- coding: utf-8 -*-
-
import cv2
-
import numpy
as np
-
import matplotlib.pyplot
as plt
-
-
#读取原始图像
-
img = cv2.imread(
'zxp.jpg')
-
-
#图像向下取样
-
r = cv2.pyrDown(img)
-
-
#显示图像
-
cv2.imshow(
'original', img)
-
cv2.imshow(
'PyrDown', r)
-
-
cv2.waitKey()
-
cv2.destroyAllWindows()
运行结果如下图所示:
(2)多次向下采样
代码如下所示:
-
# -*- coding: utf-8 -*-
-
import cv2
-
import numpy
as np
-
import matplotlib.pyplot
as plt
-
-
#读取原始图像
-
img = cv2.imread(
'zxp.jpg')
-
-
#图像向下取样
-
r1 = cv2.pyrDown(img)
-
r2 = cv2.pyrDown(r1)
-
r3 = cv2.pyrDown(r2)
-
-
#显示图像
-
cv2.imshow(
'original', img)
-
cv2.imshow(
'PyrDown1', r1)
-
cv2.imshow(
'PyrDown2', r2)
-
cv2.imshow(
'PyrDown3', r3)
-
-
cv2.waitKey()
-
cv2.destroyAllWindows()
运行结果如下图所示:
在图像向上取样是由小图像不断放图像的过程。它将图像在每个方向上扩大为原图像的2倍,新增的行和列均用0来填充,并使用与“向下取样”相同的卷积核乘以4,再与放大后的图像进行卷积运算,以获得“新增像素”的新值。
如图下图所示,它在原始像素45、123、89、149之间各新增了一行和一列值为0的像素。
如下图所示,为图像的向上采样和向下采样的例子。
注:向上取样和向下取样无法互逆的。
在OpenCV中,向上取样使用 pyrUp() 函数,其函数用法如下所示:
dst = pyrUp(src[, dst[, dstsize[, borderType]]])
其中,参数:
src 表示输入图像;
dst 表示输出图像,和输入图像具有一样的尺寸和类型;
dstsize 表示输出图像的大小,默认值为Size();
borderType 表示像素外推方法,详见cv::bordertypes 。
代码如下所示:
-
# -*- coding: utf-8 -*-
-
import cv2
-
import numpy
as np
-
import matplotlib.pyplot
as plt
-
-
#读取原始图像
-
img = cv2.imread(
'zxp_PyrDown2.jpg')
-
-
#图像向上取样
-
r = cv2.pyrUp(img)
-
-
#显示图像
-
cv2.imshow(
'original', img)
-
cv2.imshow(
'PyrUp', r)
-
cv2.waitKey()
-
cv2.destroyAllWindows()
运行结果如下图所示:
前面提到的均是高斯金字塔(使用高斯核),下面介绍拉普拉斯(Laplacian) 金字塔,拉普拉斯(Laplacian) 金字塔是在高斯金字塔的基础上新的金字塔。
如下图所示,拉普拉斯(Laplacian) 金字塔的表达式:
拉普拉斯每一层表示如下图所示:
下图高斯金字塔和拉普拉斯金字塔 交叉使用得到不同的图像。
(1) 拉普拉斯第0层
代码如下所示:
-
# -*- coding: utf-8 -*-
-
import cv2
-
import numpy
as np
-
import matplotlib.pyplot
as plt
-
-
#读取原始图像
-
img = cv2.imread(
'lena.tiff')
-
-
#图像向下取样
-
r1 = cv2.pyrDown(img)
-
-
#图像向上取样
-
r2 = cv2.pyrUp(r1)
-
-
# 拉普拉斯第0层
-
LapPyr0 =img-r2
-
-
-
-
#显示图像
-
cv2.imshow(
'original', img)
-
cv2.imshow(
'LapPyr', LapPyr0)
-
cv2.waitKey()
-
cv2.destroyAllWindows()
运行结果如下图所示:
(2) 拉普拉斯第0层和拉普拉斯第1层
代码如下所示:
-
# -*- coding: utf-8 -*-
-
import cv2
-
import numpy
as np
-
import matplotlib.pyplot
as plt
-
-
#读取原始图像
-
img = cv2.imread(
'lena.tiff')
-
-
#图像向下取样
-
r1 = cv2.pyrDown(img)
-
-
#图像向上取样
-
r2 = cv2.pyrUp(r1)
-
-
# 拉普拉斯第0层
-
LapPyr0 =img-r2
-
-
-
-
#图像向下取样
-
r3 = cv2.pyrDown(r1)
-
-
#图像向上取样
-
r4 = cv2.pyrUp(r3)
-
-
# 拉普拉斯第1层
-
LapPyr1 =r1-r4
-
-
#显示图像
-
cv2.imshow(
'original', img)
-
cv2.imshow(
'LapPyr0', LapPyr0)
-
cv2.imshow(
'LapPyr1', LapPyr1)
-
cv2.waitKey()
-
cv2.destroyAllWindows()
运行结果如下图所示:
[1] https://blog.csdn.net/Eastmount/article/details/89341077
[2] Python+OpenCV图像处理
[3] 冈萨雷斯. 数字图像处理(第三版)