OpenCV(Python3)_16(图像金字塔)

目标

在这一章当中,

  • 我们将学习Image Pyramids
  • 我们将使用图像金字塔创建一个新的水果:橘子苹果
  • 我们将看到这些函数:cv.pyrUp()cv.pyrDown()

理论

通常情况下,我们使用一个大小不变的图像。但在某些情况下,我们需要使用同一张图像不同分辨率的子图像。例如,在搜索图像中的某些内容时(例如脸部),我们不确定该图像中物体的大小。在这种情况下,我们需要创建一组具有不同分辨率的图像,并在其中搜索对象。这些具有不同分辨率的图像集被称为图像金字塔(因为我们把最大的图像放在底部,而最小的图像放在顶部,它看起来像金字塔,因而得名图像金字塔)。

有两种图像金字塔。1)高斯金字塔和2)拉普拉斯金字塔

补充:

对图像的向下取样

为了获取层级为 G_i+1 的金字塔图像,我们采用如下方法:

   (1)对图像G_i进行高斯内核卷积

   (2)将所有偶数行和列去除

 得到的图像即为G_i+1的图像,显而易见,结果图像只有原图的四分之一。通过对输入图像G_i(原始图像)不停迭代以上步骤就会得到整个金字塔。同时我们也可以看到,向下取样会逐渐丢失图像的信息。 以上就是对图像的向下取样操作,即缩小图像

 对图像的向上取样

  如果想放大图像,则需要通过向上取样操作得到,具体做法如下:

  (1)将图像在每个方向扩大为原来的俩倍,新增的行和列以0填充

 (2)使用先前同样的内核(乘以4)与放大后的图像卷积,获得新增像素的近似值

补充完毕:

高斯金字塔的顶部是通过将底部图像中的连续的行和列去除得到的。顶部图像中的每个像素值等于下一层图像中 5 个像素的高斯加权平均值。这样操作一次一个 MxN 的图像就变成了一个 M/2xN/2 的图像。所以这幅图像的面积就变为原来图像面积的四分之一。这被称为 Octave。连续进行这样的操作我们就会得到一个分辨率不断下降的图像金字塔。我们可以使用函数cv2.pyrDown() 和 cv2.pyrUp() 构建图像金字塔。函数 cv2.pyrDown() 从一个高分辨率大尺寸的图像向上构建一个金子塔(尺寸变小,分辨率降低)。

程序:

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt

img = cv.imread('lena.jpg')
lower_reso = cv.pyrDown(img)
cv.imshow('dst',lower_reso)
cv.waitKey(0)

结果:

                                         

函数 cv2.pyrUp() 从一个低分辨率小尺寸的图像向下构建一个金子塔(尺寸变大,但分辨率不会增加)。

程序:

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt

img = cv.imread('lena.jpg')
lower_reso = cv.pyrDown(img)
higher_reso2 = cv.pyrUp(lower_reso)
cv.imshow('dst1',lower_reso)
cv.imshow('dst2',higher_reso2)
cv.waitKey(0)

结果:

请记住,higher_reso2不等于img(本程序中如此),因为一旦您降低分辨率,就会丢失信息。

拉普拉斯金字塔可以有高斯金字塔计算得来,公式如下:

                

补充:

拉普拉斯金字塔是通过源图像减去先缩小后再放大的图像的一系列图像构成的

整个拉普拉斯金字塔运算过程可以通过下图来概括:

       

图像混合使用金字塔

图像金字塔的一个应用是图像融合。例如,在图像缝合中,你需要将两幅图叠在一起,但是由于连接区域图像像素的不连续性,整幅图的效果看起来会很差。这时图像金字塔就可以排上用场了,他可以帮你实现无缝连接。这里的一个经典案例就是将两个水果融合成一个,看看下图也许你就明白我在讲什么了。

                       


你可以通过阅读后边的更多资源来了解更多关于图像融合,拉普拉斯金字塔的细节。实现上述效果的步骤如下:
1. 读入两幅图像,苹果和句子
2. 构建苹果和橘子的高斯金字塔(6 层)
3. 根据高斯金字塔计算拉普拉斯金字塔
4. 在拉普拉斯的每一层进行图像融合(苹果的左边与橘子的右边融合)

5. 根据融合后的图像金字塔重建原始图像。

程序:

import cv2 as cv
import numpy as np,sys
from matplotlib import pyplot as plt

A = cv.imread('apple.jpg')
B = cv.imread('orange.jpg')
# generate Gaussian pyramid for A
G = A.copy()
gpA = [G]
for i in range(6):
    G = cv.pyrDown(G)
    gpA.append(G)
# generate Gaussian pyramid for B
G = B.copy()
gpB = [G]
for i in range(6):
    G = cv.pyrDown(G)
    gpB.append(G)
# generate Laplacian Pyramid for A
lpA = [gpA[5]]
for i in range(5,0,-1):
    GE = cv.pyrUp(gpA[i])
    L = cv.subtract(gpA[i-1],GE)
    lpA.append(L)
# generate Laplacian Pyramid for B
lpB = [gpB[5]]
for i in range(5,0,-1):
    GE = cv.pyrUp(gpB[i])
    L = cv.subtract(gpB[i-1],GE)
    lpB.append(L)
# Now add left and right halves of images in each level
LS = []
for la,lb in zip(lpA,lpB):
    rows,cols,dpt = la.shape
    print(cols)
    temp=int(cols/2)
    ls = np.hstack((la[:,0:temp], lb[:,temp:]))
    LS.append(ls)
# now reconstruct
ls_ = LS[0]
for i in range(1,6):
     ls_ = cv.pyrUp(ls_)
     ls_ = cv.add(ls_, LS[i])
# image with direct connecting each half
temp=int(cols/2)
real = np.hstack((A[:,:temp],B[:,temp:]))
cv.imshow('image1',ls_)
cv.imshow('image2',real)
cv.waitKey(0)

结果:


猜你喜欢

转载自blog.csdn.net/qq_27806947/article/details/80769339