【youcans 的 OpenCV 例程200篇】189.基于掩模的拉普拉斯金字塔图像融合

OpenCV 例程200篇 总目录-202205更新


【youcans 的 OpenCV 例程200篇】189.基于掩模的拉普拉斯金字塔图像融合


图像金字塔是一系列来源于同一张原始图像、以金字塔形状排列的分辨率逐步降低的图像集合。从底层图像可以看清更多细节,从顶层图像可以看到更多的轮廓特征。

在计算高斯金字塔时,不断进行高斯滤波和下采样,丢失了高频信息。为了描述这些高频信息,将通过原图像减去先缩小后放大的图像的一系列差分图像,定义为拉普拉斯金字塔(Laplacian Pyramid)。


6.3 基于拉普拉斯金字塔的图像融合

图像融合的目的就是使两幅图像的重叠区域过渡自然且平滑。

拉普拉斯金字塔将源图像分解到不同的频带,越高频的图像信息越到上层。在相同显示尺寸下比较不同分辨率的拉普拉斯图像,可以发现不同尺度下关注的细节是不同的,低分辨率下关注的是较大尺度的基本纹理,而高分辨率下关注的是更精细的纹理。

金字塔图像融合过程,是在不同尺度、不同空间分辨率和不同分解层上分别进行的,也称为多波段融合(Multi-band Blending)。多波段融合的思想,是先对多幅图像分别构建拉普拉斯金字塔,然后对同一层图像(相同频段)按一定规则融合,对融合后的图像金字塔重建得到融合图像。

在这里插入图片描述

在上一个例程的基础上,通过掩模图像 mask 实现图像融合,将前景图像叠加到背景图像的指定位置,通过拉普拉斯金字塔在不同频段层次上进行图像融合。

简单地,融合区域中的像素值采用前景图像和背景的掩模加法计算:
P ( i , j ) = ω P A ( i , j ) + ( 1 − ω ) P B ( i , j ) P(i,j) = \omega P_A(i,j) + (1-\omega) P_B(i,j) P(i,j)=ωPA(i,j)+(1ω)PB(i,j)

ω \omega ω 为掩模图像,前景区域为黑色遮罩; ( 1 − ω ) (1-\omega) (1ω)为逆遮罩,前景区域白色开窗,其它区域黑色。

算法原理:

(1)读取背景图像和前景图像,指定叠加位置,将前景图像调整到指定的大小。
(2)生成掩模图像 mask,标识叠加前景的位置。
(3)建立背景图像和前景图像的高斯金字塔和拉普拉斯金字塔。
(4)基于掩模图像将顶层高斯金字塔、各层拉普拉斯金字塔的背景和前景图像分别进行加权融合。
(5)从顶层的高斯金字塔融合图像开始重建融合图像,与各层拉普拉斯金字塔融合图像相加,得到重建的各层高斯金字塔融合图像,直到底层高斯金字塔融合图像 G0 即为重建的结果。


例程:1.89 基于掩模的拉普拉斯金字塔图像融合

    # 1.89:基于掩模的金字塔图像融合
    img1 = cv2.imread("../images/seaside02.png")  # 背景图像
    img2 = cv2.imread("../images/seagull02.png")  # 添加的前景图像
    xmin, ymin, w, h = 256, 64, 200, 200  # 矩形 ROI 位置: (ymin:ymin+h, xmin:xmin+w)
    levels = 5

    # 调整尺寸,将背景图片调整到 power(2,levels) 的整数倍
    imgBack = cv2.resize(img1, (512, 512), interpolation=cv2.INTER_CUBIC)
    # h = round(w * img2.shape[0]/img2.shape[1])  # 调整 ROI 尺寸与前景图像尺寸匹配
    front = cv2.resize(img2, (w+50, h+50))  # 将前景图像调整到指定大小 (w,h)
    imgFront = np.zeros(imgBack.shape, dtype=np.uint8)  # 与 imgback 尺寸相同的黑色图像
    imgFront[ymin-25:ymin+h+25, xmin-25:xmin+w+25] = front
    mask0 = np.ones((imgBack.shape[:2]), dtype=np.uint8)  # 返回与图像 imgback 尺寸相同的全零数组
    mask0[ymin:ymin+h, xmin:xmin+w] = 0  # 掩模图像,ROI 为黑色
    bg = cv2.bitwise_and(imgBack, imgBack, mask=mask0)  # 生成背景,mask 遮罩区域黑色
    fg = cv2.bitwise_and(imgFront, imgFront, mask=1-mask0)  # 生成前景,前景以外区域黑色
    stack = cv2.add(bg, fg)  # 直接合成前景与背景

    # 图像向下取样, 构造高斯金字塔: [原图,下取样1次,下取样2次,下取样3次,下取样4次]
    gaussPyrB, gaussPyrF, maskLPyr = [imgBack], [imgFront], [mask0]
    for i in range(1, levels):  # 计算第 i 层高斯金字塔
        gaussPyrB.append(cv2.pyrDown(gaussPyrB[i-1]))
        gaussPyrF.append(cv2.pyrDown(gaussPyrF[i-1]))
        maskLPyr.append(cv2.resize(maskLPyr[i-1], dsize=None, fx=0.5, fy=0.5))

    # 图像向上取样, 构造拉普拉斯金字塔 [第1层残差,第2层残差,第3层残差,第4层残差]
    lapPyrB, lapPyrF = [], []  # 从最顶层开始恢复
    for i in range(levels-1):  # 拉普拉斯金字塔有 4 层: 0,1,2,3
        lapB = gaussPyrB[i] - cv2.pyrUp(gaussPyrB[i+1])  # 残差
        lapPyrB.append(lapB)
        lapF = gaussPyrF[i] - cv2.pyrUp(gaussPyrF[i+1])  # 残差
        lapPyrF.append(lapF)

    # 基于掩模图像的拉普拉斯加权融合
    lapFusion = []
    for i in range(levels-1):  # 拉普拉斯金字塔共 4 层: 0,1,2,3
        mask = maskLPyr[i]  # 当前分辨率的掩模遮罩,前景区域黑色遮罩
        maskInv = 1 - mask  # 生成逆遮罩,前景区域白色开窗,前景以外区域黑色
        bg = cv2.bitwise_and(lapPyrB[i], lapPyrB[i], mask=mask)  # 生成背景,mask 遮罩区域黑色
        fg = cv2.bitwise_and(lapPyrF[i], lapPyrF[i], mask=maskInv)  # 生成前景,前景以外区域黑色
        lapStack = cv2.add(bg, fg)  # 前景与背景合成,得到当前分辨率的拉普拉斯融合图像
        lapFusion.append(lapStack)

    # 拼接高斯金字塔顶层 G4: (32,32)
    mask = maskLPyr[levels-1]  # 当前分辨率的掩模遮罩,前景区域黑色遮罩
    maskInv = 1 - mask  # 生成逆遮罩,前景区域白色开窗,前景以外区域黑色
    bg = cv2.bitwise_and(gaussPyrB[levels-1], gaussPyrB[levels-1], mask=mask)  # 生成背景,mask 遮罩区域黑色
    fg = cv2.bitwise_and(gaussPyrF[levels-1], gaussPyrF[levels-1], mask=maskInv)  # 生成前景,前景以外区域黑色
    gaussStack = cv2.add(bg, fg)  # 前景与背景合成,得到叠加图像 (32,32)

    plt.figure(figsize=(10, 7))
    plt.subplot(231), plt.axis('off'), plt.title("Origin")
    plt.imshow(cv2.cvtColor(img1, cv2.COLOR_BGR2RGB))
    plt.subplot(232), plt.axis('off'), plt.title("Stacked")
    plt.imshow(cv2.cvtColor(stack, cv2.COLOR_BGR2RGB))

    fusion = gaussStack  # 从高斯金字塔顶层 G4:(32,32) 开始逐层复原
    for i in range(levels-1, 0, -1):  # 拉普拉斯金字塔有 4 层: 3,2,1,0
        pyrG = cv2.pyrUp(fusion)  # # 上采样,图像尺寸加倍
        fusion = lapFusion[i-1] + cv2.pyrUp(fusion)
        plt.subplot(2,3,levels-i+2), plt.axis('off'), plt.title("G{}: {}".format(i-1,fusion.shape[:2]))
        plt.imshow(cv2.cvtColor(fusion, cv2.COLOR_BGR2RGB))

    plt.tight_layout()
    plt.show()

在这里插入图片描述



(本节完)


版权声明:

OpenCV 例程200篇 总目录-202205更新
youcans@xupt 原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/124866268)

Copyright 2022 youcans, XUPT
Crated:2022-5-20


欢迎关注 『youcans 的 OpenCV 例程 200 篇』 系列,持续更新中
欢迎关注 『youcans 的 OpenCV学习课』 系列,持续更新中

【youcans 的 OpenCV 例程200篇】147. 图像分割之孤立点检测
【youcans 的 OpenCV 例程200篇】148. 图像分割之线检测
【youcans 的 OpenCV 例程200篇】149. 图像分割之边缘模型
【youcans 的 OpenCV 例程200篇】150. 边缘检测梯度算子
【youcans 的 OpenCV 例程200篇】151. 边缘检测中的平滑处理
【youcans 的 OpenCV 例程200篇】152. 边缘检测之 LoG 算子
【youcans 的 OpenCV 例程200篇】153. 边缘检测之 DoG 算子
【youcans 的 OpenCV 例程200篇】154. 边缘检测之 Canny 算子
【youcans 的 OpenCV 例程200篇】155. 边缘连接的局部处理方法
【youcans 的 OpenCV 例程200篇】156. 边缘连接局部处理的简化算法
【youcans 的 OpenCV 例程200篇】157. 霍夫变换直线检测
【youcans 的 OpenCV 例程200篇】158. 阈值处理之固定阈值法
【youcans 的 OpenCV 例程200篇】159. 图像分割之全局阈值处理
【youcans 的 OpenCV 例程200篇】160. 图像处理之OTSU 方法
【youcans 的 OpenCV 例程200篇】161. OTSU 阈值处理算法的实现
【youcans 的 OpenCV 例程200篇】162. 全局阈值处理改进方法
【youcans 的 OpenCV 例程200篇】163. 基于边缘信息改进全局阈值处理
【youcans 的 OpenCV 例程200篇】164.使用 Laplace 边缘信息改进全局阈值处理
【youcans 的 OpenCV 例程200篇】165.多阈值 OTSU 处理方法
【youcans 的 OpenCV 例程200篇】166.自适应阈值处理
【youcans 的 OpenCV 例程200篇】167.基于移动平均的可变阈值处理
【youcans 的 OpenCV 例程200篇】168.图像分割之区域生长
【youcans 的 OpenCV 例程200篇】169.图像分割之区域分离
【youcans 的 OpenCV 例程200篇】170.图像分割之K均值聚类
【youcans 的 OpenCV 例程200篇】171.SLIC 超像素区域分割
【youcans 的 OpenCV 例程200篇】172.SLIC 超像素区域分割算法比较
【youcans 的 OpenCV 例程200篇】173.SEEDS 超像素区域分割
【youcans 的 OpenCV 例程200篇】174.LSC 超像素区域分割
【youcans 的 OpenCV 例程200篇】175.超像素区域分割方法比较
【youcans 的 OpenCV 例程200篇】176.图像分割之均值漂移算法
【youcans 的 OpenCV 例程200篇】177.图像分割之 GraphCuts 图割法
【youcans 的 OpenCV 例程200篇】178.图像分割之 GrabCut 图割法(框选前景)
【youcans 的 OpenCV 例程200篇】179.图像分割之 GrabCut 图割法(掩模图像)
【youcans 的 OpenCV 例程200篇】180.基于距离变换的分水岭算法
【youcans 的 OpenCV 例程200篇】181.基于 Sobel 梯度的分水岭算法
【youcans 的 OpenCV 例程200篇】182.基于形态学梯度的分水岭算法
【youcans 的 OpenCV 例程200篇】183.基于轮廓标记的分水岭算法
【youcans 的 OpenCV 例程200篇】184.鼠标交互标记的分水岭算法
【youcans 的 OpenCV 例程200篇】185.图像金字塔之高斯金字塔
【youcans 的 OpenCV 例程200篇】186.图像金字塔之拉普拉斯金字塔
【youcans 的 OpenCV 例程200篇】187.由拉普拉斯金字塔还原图像
【youcans 的 OpenCV 例程200篇】188.基于拉普拉斯金字塔的图像融合
【youcans 的 OpenCV 例程200篇】189.基于掩模的拉普拉斯金字塔图像融合

猜你喜欢

转载自blog.csdn.net/youcans/article/details/124940650