Hello,大家好呀~今天给大家带来一个超级实用的计算机视觉技巧:如何实现图像融合!图像融合在很多场景中都非常有用,比如全景拼接、图像修复、艺术创作等。如果你对图像处理感兴趣,那一定不要错过这篇文章哦!话不多说,直接开整~


🌟 什么是图像融合?

图像融合是指将两张或多张图像结合在一起,生成一张新的图像的过程。它通常用于以下场景:

  • 全景拼接:将多张照片无缝拼接成一张全景图。
  • 图像修复:通过融合背景和目标区域来修复损坏的图像。
  • 艺术创作:将不同风格的图像混合,创造出独特的视觉效果。

✨ 图像融合的核心技术

实现图像融合的关键在于选择合适的算法和技术。常见的方法包括:

  1. 线性加权平均:简单地对像素值进行加权求和。
  2. 拉普拉斯金字塔融合:通过多尺度分解实现更自然的融合效果。
  3. 泊松融合:基于梯度域优化,保留边缘细节。

今天我们主要讲解线性加权平均拉普拉斯金字塔融合这两种方法,并附上代码解析!


🔥 实战案例:两张图片的线性融合

假设我们有两张图片,分别是image1.jpgimage2.jpg,我们希望将它们按照一定的权重比例融合在一起。


1️⃣ 安装依赖

首先,我们需要安装OpenCV库,这是一个强大的计算机视觉工具包。

pip install opencv-python-headless

2️⃣ 线性加权平均融合

线性加权平均是最简单的融合方法,公式如下:

Ifused=α⋅I1+(1−α)⋅I2 I_{\text{fused}} = \alpha \cdot I_1 + (1 - \alpha) \cdot I_2 Ifused=αI1+(1α)I2

其中:
I1 I_1 I1I2I_2 I2 是两张输入图像。
-α\alphaα 是权重参数,控制两张图像的贡献比例。

代码实现
import cv2
import numpy as np

# 读取两张图片
image1 = cv2.imread('image1.jpg')
image2 = cv2.imread('image2.jpg')

# 确保两张图片大小相同
if image1.shape != image2.shape:
    image2 = cv2.resize(image2, (image1.shape[1], image1.shape[0]))

# 设置融合权重
alpha = 0.5  # 控制两张图片的比例
beta = 1 - alpha

# 线性加权平均融合
fused_image = cv2.addWeighted(image1, alpha, image2, beta, 0)

# 显示结果
cv2.imshow('Fused Image', fused_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

# 保存结果
cv2.imwrite('fused_image.jpg', fused_image)
运行效果
  • 当你调整alpha值时,可以看到两张图片的融合比例发生变化。
  • 如果alpha=0.8,则第一张图片占主导地位;如果alpha=0.2,则第二张图片占主导地位。

🔥 实战案例:拉普拉斯金字塔融合

拉普拉斯金字塔融合是一种更高级的方法,可以生成更自然的过渡效果。它的核心思想是通过多尺度分解,分别融合低频和高频信息。


1️⃣ 拉普拉斯金字塔原理

  1. 高斯金字塔:通过对图像进行多次下采样,提取低频信息。
  2. 拉普拉斯金字塔:通过高斯金字塔的差分,提取高频信息。
  3. 融合:将两张图片的低频和高频信息分别融合,再重构出最终图像。

2️⃣ 代码实现

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

#预处理图片,使大小相同
def load_images():
    apple = cv2.imread('apple.jpeg')
    orange = cv2.imread('orange.jpeg')

    # Ensure both images are of same size
    apple = cv2.resize(apple, (512, 512))
    orange = cv2.resize(orange, (512, 512))

    apple = apple.astype(np.float32)
    orange = orange.astype(np.float32)

    return apple, orange

# 创建高斯金字塔
def gaussian_pyramid(img, levels=6):
    lower = img.copy()
    gaussian_pyr = [lower]

    for i in range(levels):
        lower = cv2.pyrDown(lower)
        gaussian_pyr.append(np.float32(lower))

    return gaussian_pyr[:-1]

# 创建拉普拉斯金字塔
def laplacian_pyramid(gaussian_pyr):
    laplacian_top = gaussian_pyr[-1]
    num_levels = len(gaussian_pyr) - 1

    laplacian_pyr = [laplacian_top]
    for i in range(num_levels, 0, -1):
        size = (gaussian_pyr[i - 1].shape[1], gaussian_pyr[i - 1].shape[0])
        higher_in_laplace = cv2.pyrUp(laplacian_pyr[-1], dstsize=size)
        gaussian_expanded = cv2.pyrUp(gaussian_pyr[i], dstsize=size)
        laplacian = cv2.subtract(gaussian_pyr[i - 1], gaussian_expanded)
        laplacian_pyr.append(laplacian)

    return laplacian_pyr[::-1]


def blend_halves(laplacian_apple, laplacian_orange):
    blended_pyr = []
    n = min(len(laplacian_apple), len(laplacian_orange))
    for l_a, l_o in zip(laplacian_apple, laplacian_orange):
        cols = l_a.shape[1]
        laplacian_merged = np.hstack((l_a[:, :cols // 2], l_o[:, cols // 2:]))
        blended_pyr.append(laplacian_merged)

    return blended_pyr


def reconstruct_image(laplacian_pyr):
    laplacian_top = laplacian_pyr[-1]
    reconstructed_img = laplacian_top.copy()

    for laplacian in reversed(laplacian_pyr[:-1]):
        rows, cols, _ = laplacian.shape
        upsampled_reconstructed = cv2.pyrUp(reconstructed_img, dstsize=(cols, rows))
        reconstructed_img = cv2.add(laplacian, upsampled_reconstructed)

    return reconstructed_img


if __name__ == "__main__":
    apple, orange = load_images()
    gp_apple = gaussian_pyramid(apple)
    gp_orange = gaussian_pyramid(orange)

    lp_apple = laplacian_pyramid(gp_apple)
    lp_orange = laplacian_pyramid(gp_orange)

    ls = blend_halves(lp_apple, lp_orange)
    final_output = reconstruct_image(ls)

    plt.figure(figsize=(8, 4))
    plt.subplot(1, 3, 1);
    plt.imshow(cv2.cvtColor(apple, cv2.COLOR_BGR2RGB));
    plt.title("Apple")
    plt.subplot(1, 3, 2);
    plt.imshow(cv2.cvtColor(final_output.astype(np.uint8), cv2.COLOR_BGR2RGB));
    plt.title("Blended Output")
    plt.subplot(1, 3, 3);
    plt.imshow(cv2.cvtColor(orange, cv2.COLOR_BGR2RGB));
    plt.title("Orange")

    plt.show()

运行效果

  • 拉普拉斯金字塔融合生成的图像具有更自然的过渡效果。

  • 特别适合用于需要保留边缘细节的场景,例如全景拼接或图像修复。

  • 在这里插入图片描述


💡 运行注意事项

  1. 图片尺寸一致:确保两张图片的尺寸相同,否则需要先进行缩放。
  2. 颜色通道一致:确保两张图片的颜色通道一致(如RGB)。
  3. 权重调整:根据实际需求调整融合权重,以达到最佳效果。

🎉 总结

通过本文的学习,我们掌握了两种常见的图像融合方法:

  1. 线性加权平均:简单易用,适合快速实现。
  2. 拉普拉斯金字塔融合:高级方法,适合需要高质量融合的场景。

希望这篇教程能帮到大家!如果你觉得有用的话,记得点赞收藏哦~ 😘

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐