当前位置: 首页 > news >正文

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

C语言 | Leetcode C语言题解之第335题路径交叉

题目&#xff1a; 题解&#xff1a; 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学习第十三篇 - 泛型

在编译期间不确定变量的类型&#xff0c;在调用时&#xff0c;由开发者指定具体的类型。 1. 如何给arg参数和函数指定类型&#xff1f; function identity(arg){return arg; }identity(1) identity(jack) identity(true) identity([]) identity(null)定义的时候&#xff0c;无…...

工业智能网关在汽车制造企业的应用价值及功能-天拓四方

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

LLM - 在服务器中使用 Ollama + OpenWebUI 部署最新大模型

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

重启人生计划-积蓄星火

&#x1f973;&#x1f973;&#x1f973; 茫茫人海千千万万&#xff0c;感谢这一刻你看到了我的文章&#xff0c;感谢观赏&#xff0c;大家好呀&#xff0c;我是最爱吃鱼罐头&#xff0c;大家可以叫鱼罐头呦~&#x1f973;&#x1f973;&#x1f973; 如果你觉得这个【重启人生…...

2024.08.11 校招 实习 内推 面经

地/球&#x1f30d; &#xff1a; neituijunsir 交* 流*裙 &#xff0c;内推/实习/校招汇总表格 1、自动驾驶一周资讯 - 比亚迪将采购华为智驾系统&#xff0c;用于方程豹新款越野车&#xff1b;英特尔发布第一代车载独立显卡&#xff1b;黑芝麻智能上市首日破发大跌 自动…...

LCA(Lowest Common Ancestor)

LCA&#xff08;Lowest Common Ancestor&#xff09; 定义 在树上取两点 x,yx,y&#xff0c;他们的 LCA 为距离他们最近的公共祖先。 本章主要讲的是倍增求 LCA。 暴力求取 从 xx 开始向上移动到根结点&#xff0c;并标记沿途结点。从 yy 开始向上移动到根结点&#xff0c…...

张钹院士:大模型时代的企业AI发展趋势

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

php连接sphinx的长连接事宜以及sphinx的排除查询以及关于sphinx里使用SetSelect进行复杂的条件过滤或复杂查询

一、php连接sphinx的长连接事宜以及sphinx的排除查询 在使用php连接sphinx时&#xff0c;默认的sphinx连接非长连接&#xff0c;于是在想php连接sphinx能否进行一些优化 publish:January 9, 2018 -Tuesday: 方法&#xff1a;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文件&#xff08;集群cookie用&#xff09; echo "secretcookie" > .erlang.cookie 三、创建haproxy.cfg配置文件 global log stdout fo…...

git强制推送代码教程

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

windows C++-高级并发和异步(三)

深入了解 winrt::resume_foreground(下) 调用 winrt::resume_foreground 时会始终先排队&#xff0c;然后展开堆栈。 也可选择设置恢复优先级。 winrt::fire_and_forget RunAsync(DispatcherQueue queue) {...co_await winrt::resume_foreground(queue, DispatcherQueuePrior…...

河北移动:核心系统数据库成功完成整体迁移 ,实现全栈国产|OceanBase案例

本文作者&#xff1a;移动通信集团河北有限公司架构规划专家&#xff0c;房瑞 项目背景&#xff1a; 中国移动通信集团河北有限公司一直在积极响应国家及集团的号召&#xff0c;以磐舟&磐基云原生为底座&#xff0c;结合国产浏览器、中间件、数据库、操作系统和服务器等&a…...

ZKRollup

目录 ZKRollup 基本概念 运作原理 特点与优势 应用场景 典型项目 ZKRollup ZKRollup,全称为Zero-Knowledge Rollup,是一种基于零知识证明的二层扩容方案(Layer 2)。它旨在通过提高交易处理效率和降低交易成本来扩展区块链网络的能力,尤其是在以太坊等区块链平台上得…...

letcode 分类练习 树的遍历

letcode 分类练习 树的遍历 树的构建递归遍历前序遍历中序遍历后序遍历 迭代遍历前序遍历中序遍历后序遍历 层序遍历层序遍历可以解决的问题107. 二叉树的层序遍历 II199. 二叉树的右视图637. 二叉树的层平均值429. N 叉树的层序遍历515.在每个树行中找最大值116.填充每个节点的…...

redisssion分布式锁

分布式锁的问题 基于setnx的分布式锁实现起来并不复杂&#xff0c;不过却存在一些问题。 锁误删问题 第一个问题就是锁误删问题&#xff0c;目前释放锁的操作是基于DEL&#xff0c;但是在极端情况下会出现问题。 例如&#xff0c;有线程1获取锁成功&#xff0c;并且执行完任…...

嘎嘎嘎拿到去年想要的包

一年多了 继续&#xff0c;把项目收尾吧 好好学前端&#xff0c;外企&#xff01;react&#xff01;从0开始&#xff0c;紧迫&#xff01;加油&#xff01;...

前奏编曲:如何编写二段式前奏

选好音源 Pianoteq 6 STAGE比较明亮些&#xff0c;适合做前奏的音源 确定和弦进行 比如4536251&#xff0c;每个小节2和弦&#xff0c;每个小节的和弦弹一下 优化和弦进行衔接和织体 二段式不用对和弦进行就近解决的处理&#xff0c;因为前奏前后要形成对比。 前半部分往…...

征服云端:Kubernetes如何让微服务与云原生技术如虎添翼

引言 在这个数字化转型的时代&#xff0c;微服务架构已经成为构建现代应用程序的首选方式。它不仅提高了开发效率&#xff0c;还增强了系统的可扩展性和灵活性。而随着云计算技术的迅猛发展&#xff0c;云原生的概念逐渐深入人心&#xff0c;它代表了一种全新的软件开发方法论…...

开源AI智能名片系统与高级机器学习技术的融合应用:重塑商务交流的未来

摘要&#xff1a;在数字化浪潮的推动下&#xff0c;人工智能&#xff08;AI&#xff09;技术&#xff0c;尤其是机器学习领域的快速发展&#xff0c;正深刻改变着各行各业的面貌。开源AI智能名片系统作为这一变革的先锋&#xff0c;通过集成并优化多种高级机器学习技术&#xf…...

Java中synchronized的偏向锁是如何减少锁开销的

偏向锁&#xff08;Biased Locking&#xff09;是一种优化 Java synchronized 锁的机制&#xff0c;旨在减少在无竞争情况下的锁开销。它通过将锁偏向于单个线程来优化锁的性能。以下是偏向锁减少锁开销的具体方式和原理&#xff1a; 偏向锁的工作原理 锁的初始状态: 当一个对…...

湖南省造价管理站官网/微信引流被加软件

文章目录前言系列文章目录&#xff0c;Vue学习目录&#xff0c;每一章都有代码例子说明二、Vue组件初次使用2.1 创建组件的第一种方式&#xff1a; 使用Vue.component创建一个组件2.2 创建组件的第二种方式&#xff1a;在Vue实例里注册,先定义好对象&#xff0c;然后在实例的co…...

洛阳网站建设优化案例/太原推广团队

最近研究Flash XML的动态图表实现.看了些商业的方案.汇总在这里. AnyChart Flash Chart ComponentAurigma FlashChartB-Line Charting ComponentCordas PopChartFusionChartsGraph ZXPHP/SWF ChartsRich Chart BuilderSwiff ChartWA Dynamic Flash ChartsXPCharting转载于:http…...

建设网站西丽/最专业的seo公司

文章目录 前言I、定时器的基本用法1.1 添加计时器1.2 往运行循环添加timer1.3 保证定时器的运行不受UI事件影响II 停止定时器的方案2.1 invalidate的用法2.2 FireDate的用法III CADisplayLink 与 NSTimer 有什么不同?3.1 精确度3.2 使用场合3.3 注意事项IV、使用CALayer 实现时…...

五道口网站建设/品牌公关公司

在做混合开发时发现&#xff0c;无论是APP内的字体大小&#xff0c;还是前端的字体大小&#xff0c;都会随着系统字体大小发生变化。当遇到老人字体&#xff08;特大号字体&#xff09;时&#xff0c;有些页面的布局就乱掉了。而玩过游戏的都知道&#xff0c;所有游戏APP的字体…...

手机网站和微信网站的区别/河南推广网站

pandas的DataFrame与python的dict字典之间的相互转换 一、dict生成DataFrame 1、如果只有一个dict&#xff0c;即一行dataframe数据 复制代码 注&#xff1a;dict的形式必须是如下2种&#xff0c;不然会报错 1、dict外面加一层list【】 dict_a [{‘a’: 0, ‘b’: 1, ‘c’…...

网站设计代做/市场调研报告模板ppt

一、简介 美国国家漏洞数据库收集了操作系统&#xff0c;应用软件的大量漏洞信息&#xff0c;当有新的漏洞出现时&#xff0c;它也会及时发布出来&#xff0e; 由于信息量巨大&#xff0c;用户每次都需要到它的网站进行搜索&#xff0c;比较麻烦&#xff0e;如果能有个工具&…...