opencv-python实战项目九:基于拉普拉斯金字塔的图像融合
文章目录
- 一,简介:
- 二,拉普拉斯金字塔介绍:
- 三,算法实现步骤
- 3.1 构建融合拉普拉斯金字塔
- 3.2 融合后的拉普拉斯金字塔复原:
- 四,整体代码实现:
- 五,效果:
一,简介:
图像融合是一种将两个或多个图像合成为一幅新图像的技术,目的是结合源图像中的有用信息,生成一幅更具信息量和视觉效果的新图像。拉普拉斯金字塔是一种常用于图像融合的方法,它通过多尺度分解图像,并在不同尺度上进行融合,最终重建出融合后的图像。
二,拉普拉斯金字塔介绍:
在拉普拉斯金字塔的构建过程中如下所示:首先通过高斯模糊和逐层减半尺寸的下采样,形成高斯金字塔。然后,通过从当前层高斯图像中减去经过上采样和下采样处理的上一层高斯图像,计算出拉普拉斯金字塔的每一层。在这个过程中,下采样用于降低图像分辨率,上采样用于恢复分辨率。最后,使用掩模对两张图像的拉普拉斯金字塔进行加权平均,生成混合的拉普拉斯金字塔。通过迭代处理高斯金字塔的每一层,直至达到预设的最大迭代次数,完成图像的融合和细节保留。这种多尺度分解技术可以在不同的尺度上处理图像,保留更多的细节信息,并且在图像融合、图像放大等任务中发挥着重要作用。
三,算法实现步骤
3.1 构建融合拉普拉斯金字塔
为了实现图像融合,我们构建了一个六层的拉普拉斯金字塔。每一层都通过从原始图像中减去经过高斯滤波和上下采样处理后的图像来构造。构建完当前层后,我们对其进行下采样,并按照相同的步骤继续构建下一层。通过这种方式,我们能够有效地融合两张图片的特征,从而实现图像融合的目标。制作拉普拉斯金字塔使用opencv内置函数cv2.pyrUp,以及cv2.pyrDown实现
cv2.pyrUp:
● 功能:上采样图像。
● 参数:输入图像。
● 返回值:上采样后的图像。
● 说明:cv2.pyrUp函数通过对输入图像进行双线性插值来扩大图像的尺寸。双线性插值是一种常用的图像插值方法,它通过计算像素周围点的加权平均值来估算新的像素值。这个函数通常与cv2.pyrDown一起使用,以构建高斯金字塔和拉普拉斯金字塔。
cv2.pyrDown:
● 功能:下采样图像。
● 参数:输入图像。
● 返回值:下采样后的图像。
● 说明:cv2.pyrDown函数通过对输入图像进行高斯滤波和下采样来减小图像的尺寸。高斯滤波器用于平滑图像,去除噪声,而下采样则是通过去除图像的偶数行和列来实现的。这个函数也是构建高斯金字塔和拉普拉斯金字塔的关键步骤之一。
实现代码:
for i in range(maxIterations):# 计算拉普拉斯金字塔laplacianA = cv2.subtract(guassianA, cv2.pyrUp(cv2.pyrDown(guassianA)))laplacianB = cv2.subtract(guassianB, cv2.pyrUp(cv2.pyrDown(guassianB)))# 结合两张图片的拉普拉斯金字塔,通过掩模的高斯金字塔取加权平均值combinedLaplacian = guassianMask * laplacianA + (1.0 - guassianMask) * laplacianB# 将组合的拉普拉斯金字塔添加到列表的开始位置combinedLaplacianPyramids.insert(0, combinedLaplacian)# 更新高斯金字塔,进行下一次迭代guassianA = cv2.pyrDown(guassianA)guassianB = cv2.pyrDown(guassianB)guassianMask = cv2.pyrDown(guassianMask)# 添加最后一级的拉普拉斯金字塔(金字塔的顶部)
lastCombined = guassianMask * guassianA + (1.0 - guassianMask) * guassianB
combinedLaplacianPyramids.insert(0, lastCombined)
3.2 融合后的拉普拉斯金字塔复原:
为了将两张图片融合成一张新的图片,我们首先获取了融合后的拉普拉斯金字塔的顶层图像,并将其存储在变量blendedImage中。接着,我们进入一个循环,从第二层开始,遍历融合后的拉普拉斯金字塔中的每一层。在循环中,我们首先将blendedImage上采样到下一层金字塔的尺寸,然后将上采样后的blendedImage与金字塔中的当前层图像相加,以重建金字塔。通过这种方式,我们逐渐重建出融合后的图片,保留了两张图片的细节信息,并最终得到了一张融合后的图像。
代码如下(示例):
blendedImage = combinedLaplacianPyramids[0]
for i in range(1, len(combinedLaplacianPyramids)):blendedImage = cv2.pyrUp(blendedImage)blendedImage = cv2.add(blendedImage, combinedLaplacianPyramids[i])
四,整体代码实现:
# 导入必要的库
import cv2
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mpimg# 读取两张图片
A = cv2.imread(r"F:\learnopencv-master\SeamlessCloning\images\man.jpg") # 读取男性图片
B = cv2.imread(r"F:\learnopencv-master\SeamlessCloning\images\woman.jpg") # 读取女性图片# 将图片转换为浮点数并归一化
A = np.float32(A) / 255.0
B = np.float32(B) / 255.0# 在图片A中创建一个男性脸部的大致掩模
mask = np.zeros(A.shape, A.dtype) # 初始化掩模为零矩阵
# 取出男性脸部区域制作蒙版
polygon = np.array([[164,226], [209,225], [238,188], [252,133], [248,75], [240,29], [192,15], [150,15], [100,70], [106,133], [123,194]], np.int32)
cv2.fillPoly(mask, [polygon], (255, 255, 255)) # 填充多边形
mask = np.float32(mask) / 255.0 # 将掩模转换为浮点数并归一化# 通过与小于1.0的浮点数相乘来取得男性和女性脸部的加权平均值
mask = mask * 0.7 # 男性脸部占比0.7,女性脸部占比0.3# 将图片调整为2的幂次方大小,此处为32,调整为384x352
A = cv2.resize(A, (384, 352))# B和掩模需要与A尺寸相同,以便后续的乘法和加法操作
B = cv2.resize(B, (A.shape[1], A.shape[0]))
mask = cv2.resize(mask, (A.shape[1], A.shape[0]))# 从原始图片(金字塔的底部)开始
guassianA = A.copy()
guassianB = B.copy()
guassianMask = mask.copy()# 存储合并的拉普拉斯金字塔
combinedLaplacianPyramids = []# 金字塔的层数,可以尝试不同的值,注意图片尺寸
maxIterations = 5for i in range(maxIterations):# 计算拉普拉斯金字塔laplacianA = cv2.subtract(guassianA, cv2.pyrUp(cv2.pyrDown(guassianA)))laplacianB = cv2.subtract(guassianB, cv2.pyrUp(cv2.pyrDown(guassianB)))# 结合两张图片的拉普拉斯金字塔,通过掩模的高斯金字塔取加权平均值combinedLaplacian = guassianMask * laplacianA + (1.0 - guassianMask) * laplacianB# 将组合的拉普拉斯金字塔添加到列表的开始位置combinedLaplacianPyramids.insert(0, combinedLaplacian)# 更新高斯金字塔,进行下一次迭代guassianA = cv2.pyrDown(guassianA)guassianB = cv2.pyrDown(guassianB)guassianMask = cv2.pyrDown(guassianMask)# 添加最后一级的拉普拉斯金字塔(金字塔的顶部)
lastCombined = guassianMask * guassianA + (1.0 - guassianMask) * guassianB
combinedLaplacianPyramids.insert(0, lastCombined)
# 重建图片
blendedImage = combinedLaplacianPyramids[0]
for i in range(1, len(combinedLaplacianPyramids)):blendedImage = cv2.pyrUp(blendedImage)blendedImage = cv2.add(blendedImage, combinedLaplacianPyramids[i])cv2.imshow('Blended', blendedImage) # 显示混合后的图片# 直接混合两张图片以进行比较
directCombination = mask * A + (1.0 - mask) * B
cv2.imshow('Direct combination', directCombination) # 显示直接混合后的图片
cv2.waitKey(0) # 等待按键后关闭窗口
五,效果:
原图:
融合后效果(左图为直接融合,右图为拉普拉斯融合):
相关文章:

opencv-python实战项目九:基于拉普拉斯金字塔的图像融合
文章目录 一,简介:二,拉普拉斯金字塔介绍:三,算法实现步骤3.1 构建融合拉普拉斯金字塔3.2 融合后的拉普拉斯金字塔复原: 四,整体代码实现:五,效果: 一&#x…...

浅谈JDK
JDK(Java Development Kit) JDK是Java开发工具包,是Java编程语言的核心软件开发工具。 JDK包含了一系列用于开发、编译和运行Java应用程序的工具和资源。其中包括: 1.Java编译器(javac):用于将Java源代码编译成字节…...

爬虫案例3——爬取彩票双色球数据
简介:个人学习分享,如有错误,欢迎批评指正 任务:从500彩票网中爬取双色球数据 目标网页地址:https://datachart.500.com/ssq/ 一、思路和过程 目标网页具体内容如下: 我们的任务是将上图中…...

C++ | Leetcode C++题解之第337题打家劫舍III
题目: 题解: struct SubtreeStatus {int selected;int notSelected; };class Solution { public:SubtreeStatus dfs(TreeNode* node) {if (!node) {return {0, 0};}auto l dfs(node->left);auto r dfs(node->right);int selected node->val…...

软件架构设计师-UML知识导图
软件架构设计师-UML知识导图,包含如下内容: 结构化设计,包含结构化设计的概念、结构化设计的主要内容、概要设计、详细设计及模块设计原则;UML是什么:介绍UML是什么;UML的结构:构造块、公共机制…...
在使用transformers和pytorch时出现的版本冲突的问题
在使用transformers和torch库的时候,出现了以下问题: 1、OSError: [WinError 126] 找不到指定的模块。 Error loading "D:\Program Files\anaconda3\envs\testenv\Lib\site-packages\torch\lib\fbgemm.dll" or one of its dependencies. 2、…...

uniapp粘贴板地址识别
1: 插件安装 主要是依靠 address-parse 这个插件: 官网 收货地址自动识别 支持pc、h5、微信小程序 - DCloud 插件市场 // 首先需要引入插件 npm install address-parse --save 2:html部分 <view class""><view class&quo…...

C语言 | Leetcode C语言题解之第335题路径交叉
题目: 题解: bool isSelfCrossing(int* distance, int distanceSize){if (distance NULL || distanceSize < 4) {return false;}for (int i 3; i < distanceSize; i) {if ((distance[i] > distance[i - 2]) && (distance[i - 1] &l…...
TypeScript学习第十三篇 - 泛型
在编译期间不确定变量的类型,在调用时,由开发者指定具体的类型。 1. 如何给arg参数和函数指定类型? function identity(arg){return arg; }identity(1) identity(jack) identity(true) identity([]) identity(null)定义的时候,无…...

工业智能网关在汽车制造企业的应用价值及功能-天拓四方
随着工业互联网的飞速发展,工业智能网关作为连接物理世界与数字世界的桥梁,正逐渐成为制造业数字化转型的核心组件。本文将以一家汽车制造企业的实际使用案例为蓝本,深入解析工业智能网关在实际应用中的价值、功能及其实操性。 一、背景与挑…...

LLM - 在服务器中使用 Ollama + OpenWebUI 部署最新大模型
欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://spike.blog.csdn.net/article/details/140992533 免责声明:本文来源于个人知识与公开资料,仅用于学术交流,欢迎讨论,不支持转载。 Ollama 是一个开源的大型语言模型(LLM)服务工具,目的是简化本地运行…...

重启人生计划-积蓄星火
🥳🥳🥳 茫茫人海千千万万,感谢这一刻你看到了我的文章,感谢观赏,大家好呀,我是最爱吃鱼罐头,大家可以叫鱼罐头呦~🥳🥳🥳 如果你觉得这个【重启人生…...
2024.08.11 校招 实习 内推 面经
地/球🌍 : neituijunsir 交* 流*裙 ,内推/实习/校招汇总表格 1、自动驾驶一周资讯 - 比亚迪将采购华为智驾系统,用于方程豹新款越野车;英特尔发布第一代车载独立显卡;黑芝麻智能上市首日破发大跌 自动…...
LCA(Lowest Common Ancestor)
LCA(Lowest Common Ancestor) 定义 在树上取两点 x,yx,y,他们的 LCA 为距离他们最近的公共祖先。 本章主要讲的是倍增求 LCA。 暴力求取 从 xx 开始向上移动到根结点,并标记沿途结点。从 yy 开始向上移动到根结点,…...

张钹院士:大模型时代的企业AI发展趋势
在当今技术迅速发展的时代,生成式人工智能与大模型正成为推动产业变革的重要力量。随着AI技术的不断成熟与普及,它的应用已从个人领域扩展至企业层面,广泛覆盖各行各业。 那么,新技术究竟会给产业带来哪些积极地影响?…...

php连接sphinx的长连接事宜以及sphinx的排除查询以及关于sphinx里使用SetSelect进行复杂的条件过滤或复杂查询
一、php连接sphinx的长连接事宜以及sphinx的排除查询 在使用php连接sphinx时,默认的sphinx连接非长连接,于是在想php连接sphinx能否进行一些优化 publish:January 9, 2018 -Tuesday: 方法:public bool SphinxClient::open ( void ) — 建立到…...
抓包分析排查利器TCPdump
tcpdump命令介绍与常规用法。 基础命令介绍 # 固定语法 -i 指定网卡名称 -nn 显示IP地址 -w 指定输出的文件名称 tcpdump -i eth0 -nn -w test.cap-nn 不把主机的网络地址与协议转换成名字 -w 把数据包数据写入指定的文件 and 连接参数 host 指明主机 port 指明端口 src 源IP…...

八种排序算法的复杂度(C语言)
归并排序(递归与非递归实现,C语言)-CSDN博客 快速排序(三种方法,非递归快排,C语言)-CSDN博客 堆排序(C语言)-CSDN博客 选择排序(C语言)以及选择排序优化-CSDN博客 冒泡排序(C语言)-CSDN博客 直接插入排序(C语言)-CSDN博客 希尔排序( 缩小增量排序 )(C语言)-CSDN博客 计数…...

docker compose部署rabbitmq集群,并使用haproxy负载均衡
一、创建rabbitmq的data目录 mkdir data mkdir data/rabbit1 mkdir data/rabbit2 mkdir data/rabbit3 二、创建.erlang.cookie文件(集群cookie用) echo "secretcookie" > .erlang.cookie 三、创建haproxy.cfg配置文件 global log stdout fo…...

git强制推送代码教程
git强制推送代码教程 首先说明情况,我的代码remote了两个git库,现在想要推送到其中一个,但是版本不对,被拒绝,因此下面将进行强制推送 首先检查远程库都有哪些 git remote -v2. 检查当前的分支 git branch当前分支前…...

网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

React第五十七节 Router中RouterProvider使用详解及注意事项
前言 在 React Router v6.4 中,RouterProvider 是一个核心组件,用于提供基于数据路由(data routers)的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

DAY 47
三、通道注意力 3.1 通道注意力的定义 # 新增:通道注意力模块(SE模块) class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

聊聊 Pulsar:Producer 源码解析
一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...