opencv图像处理之图像金字塔+图像融合案例

1.原理

  • 我以前写过一篇 图像金字塔是什么
  • 从高斯金字塔计算拉普拉斯金字塔的公式 : L i = G i p y r U p ( G i + 1 ) L_i=G_i-pyrUp(G_i+1)

2.图像金字塔代码和结果

  • cv2.pyrDown()
  • cv2.pyrUp()

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

def pyr_up_down(self):
    lower_reso=cv2.pyrDown(self.img)#降采样一次,长宽缩小为1/2,面积变为1/4
    higher_reso2=cv2.pyrUp(lower_reso)#放大到二倍
    cv2.imshow('raw', self.img)
    cv2.imshow('low',lower_reso)
    cv2.imshow('high', higher_reso2)
    cv2.waitKey(0)
    print(self.img.shape)#(640, 640, 3)
    print(lower_reso.shape)#(320, 320, 3)
    print(higher_reso2.shape)#(640, 640, 3)

在这里插入图片描述
可以看到缩小后,再放大,图像已经变模糊了。因为一旦使用cv2.pyrDown(),图像的分辨率就会降低,信息就会被丢失。

3.图像融合代码和结果

def img_blend(self):
    #【1】读入两幅图像
    A=cv2.imread('../images/apple.jpg')
    B=cv2.imread('../images/orange.jpg')
    # 【2】构建两幅图像的高斯金字塔(6层)
    G=A.copy()
    gpA=[G]
    for i in range(6):
        G=cv2.pyrDown(G)
        gpA.append(G)

    G=B.copy()
    gpB=[G]
    for i in range(6):
        G=cv2.pyrDown(G)
        gpB.append(G)

    # 【3】根据高斯金字塔计算拉普拉斯金字塔-计算公式
    # Li = Gi -PyrUp(Gi+1)
    lpA=[gpA[5]]#L[5]=G[5]
    for i in range(5,0,-1):#倒着计算,至下而上
        L=cv2.subtract(gpA[i-1],cv2.pyrUp(gpA[i]))#L[4]=G[4]-pyrUp(G[5])
        lpA.append(L)

    lpB=[gpB[5]]
    for i in range(5,0,-1):
        L=cv2.subtract(gpB[i-1],cv2.pyrUp(gpB[i]))
        lpB.append(L)

    # 【4】在拉普拉斯的每一层进行图像融合(苹果的左边,橘子的右边)
    LS=[]
    for la,lb in zip(lpA,lpB):
        rows,cols,dpt=la.shape
        ls=np.hstack((la[:,0:cols//2],lb[:,cols//2:]))
        LS.append(ls)

    # 【5】根据融合后的图像金字塔重建原始图像
    res=[]
    ls_=LS[0]#LS是融合后的拉普拉斯图像,0-5是从小到大
    res.append(ls_)
    for i in range(1,6):
        ls_=cv2.pyrUp(ls_)#向上构建金字塔
        ls_=cv2.add(ls_,LS[i])
        res.append(ls_)

    real=np.hstack((A[:,:cols//2],B[:,cols//2:]))
    titles = ['apple', 'orange','real','blend']
    images = [A, B,real,ls_]
    for i in range(4):
        img=cv2.cvtColor(images[i],cv2.COLOR_BGR2RGB)
        plt.subplot(1,4,i+1),plt.imshow(img)
        plt.title(titles[i])
        plt.xticks([]),plt.yticks([])
    plt.show()

中间结果:
(1)橙子的高斯金字塔gpB(图像实际面积,下一个是上一个的1/4)
在这里插入图片描述
(2)橙子的拉普拉斯金字塔lpB(图像实际面积,下一个是上一个的4倍)
L i = G i p y r U p ( G i + 1 ) L_i=G_i-pyrUp(G_i+1) 即,L[4]=G[4]-pyrUp(G[5])。由这个公式可以推测出,拉普拉斯金字塔的每一层的含义是,高斯金字塔每一层缩小后又放大到原尺寸所丢失的信息。
在这里插入图片描述
(3)拉普拉斯金字塔上的图像融合LS(图像实际面积,下一个是上一个的4倍)
在这里插入图片描述
(4)融合时的图像ls_的变化过程:第一幅图放大一次后,和对应的拉普拉斯层的图像相加(把丢失的信息加回来),得到第二幅图。第二幅图再放大,和对应拉普拉斯层相加。依次类推。
在这里插入图片描述
这里就产生了一个疑问,非要把拉普拉斯金字塔加上去吗?不加会怎样?直接从用LS[0]向上构建金字塔,结果如下:
在这里插入图片描述
最后的正常结果:
在这里插入图片描述

发布了132 篇原创文章 · 获赞 40 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/qq_36622009/article/details/104564351