opencv-python图像增强四:多曝光融合(方法一)
文章目录
- 一、简介:
- 二、多曝光融合方案:
- 三、算法实现步骤
- 3.1 读取图像与曝光时间:
- 3.2 计算响应曲线并合并
- 3.3 色调映射
- 四:整体代码实现
- 五:效果
一、简介:
在摄影和计算机视觉领域,高动态范围(HDR)技术已经成为了捕捉丰富细节和真实感图像的重要手段。然而,要实现高质量的HDR效果,我们需要对多张不同曝光时间的图像进行融合处理。本文将探讨多曝光融合技术的基本原理和应用,帮助您深入了解这一技术如何捕捉更丰富、更真实的世界。
在自然界中,我们的眼睛能够感知从最暗到最亮的广阔亮度范围。然而,传统的相机传感器和显示设备却无法捕捉到这一完整的亮度范围,导致图像在亮度上出现失真。为了解决这一问题,HDR技术应运而生。HDR技术通过拍摄多张不同曝光时间的图像,并将其融合为一张包含更广泛亮度范围的图像,从而在视觉上更接近真实世界的亮度。多曝光融合是实现HDR效果的关键步骤。在这一过程中,我们需要拍摄多张不同曝光时间的图像,然后将这些图像融合为一张HDR图像。多曝光融合技术能够捕捉到更多细节,特别是在高光和阴影区域,从而使得图像在视觉上更加真实和生动。
在本文中,我将深入探讨多曝光融合技术的基本原理、常用算法以及实际应用并通过示例和代码,帮助您了解如何使用Python和OpenCV库来实现多曝光融合。
二、多曝光融合方案:
我们首先将读取的图片封装成一个列表。接着,我们根据图像内容和曝光时间来计算相机的CRF(相机响应函数),这一步骤对于后续图像融合至关重要。利用计算得到的CRF,我们将多曝光图像进行融合,以获得更丰富的图像细节。最后,通过色彩映射技术,将融合后的多曝光图片进行映射处理,使得最终生成的图片在色彩上更加饱满、自然。
三、算法实现步骤
3.1 读取图像与曝光时间:
代码如下(示例):
def readImagesAndTimes():"""该函数用于读取多张图像及其对应的曝光时间。1. 首先,定义一个曝光时间数组,其中包含四张图像的曝光时间,单位为秒。2. 接着,定义一个文件名列表,包含四张图像的路径。3. 使用一个循环遍历文件名列表,对于每个文件名,使用OpenCV的imread函数读取图像。4. 将读取到的图像添加到images列表中。5. 循环结束后,返回images列表和曝光时间数组。:return: images: 包含四张图像的列表。times: 包含四张图像曝光时间的数组。"""times = np.array([1 / 30.0, 0.25, 2.5, 15.0], dtype=np.float32) # 定义曝光时间数组filenames = ["F:\ccccccc/img09.jpg", "F:\ccccccc/img08.jpg", "F:\ccccccc/img04.jpg", "F:\ccccccc/img01.jpg"] # 定义文件名列表images = [] # 创建一个空列表来存储图像for filename in filenames: # 遍历文件名列表im = cv2.imread(filename) # 使用OpenCV的imread函数读取图像images.append(im) # 将读取到的图像添加到images列表中return images, times # 返回images列表和曝光时间数组
3.2 计算响应曲线并合并
计算相机响应曲线(CRF)的过程可以简述如下:
首先,通过分析不同曝光时间下的图像数据,计算出相机的响应曲线,即CRF。这一步通常涉及对图像的亮度进行采样,并使用数学模型(如多项式或指数函数)来拟合这些采样点,从而得到一个能够描述相机如何将场景亮度转换为数字信号的函数。
然后,利用得到的CRF,对多张具有不同曝光时间的图像进行融合处理。这一过程包括以下步骤:
- 将每张图像的像素值根据CRF转换为场景亮度值。
- 对转换后的亮度值进行加权平均,以平衡不同曝光图像之间的亮度差异。
- 将融合后的亮度值重新映射回像素值,得到一张具有宽动态范围的单张图像。
代码如下(示例):
# 创建一个用于计算相机响应函数(CRF)的对象
calibrateDebevec = cv2.createCalibrateDebevec()
# 使用该对象处理多张图像和对应的曝光时间,以计算CRF
responseDebevec = calibrateDebevec.process(images, times)
# 创建一个用于合并多张图像的对象
mergeDebevec = cv2.createMergeDebevec()
# 使用该对象处理多张图像、曝光时间以及计算出的CRF,以合并为一张HDR图像
hdrDebevec = mergeDebevec.process(images, times, responseDebevec)
3.3 色调映射
常见的色调映射方法有三种分别为
1. Drago色调映射:
特点:Drago色调映射算法是基于感知的,它试图模拟人眼对亮度的适应能力。该算法特别强调在低亮度区域保持细节,同时在高亮度区域避免过曝。
参数:通常包括一个对比度参数,用于调整图像的整体对比度。
效果:产生的图像通常具有较好的视觉舒适度和细节保留,特别是在暗部区域。
2. Reinhard色调映射:
特点:Reinhard色调映射算法是基于全局对比度压缩的,它通过调整图像的亮度,使得图像的亮度分布符合特定的统计特性(例如,亮度直方图的均值)。
参数:可能包括亮度、对比度、饱和度和白色点等参数,允许用户对最终图像的外观进行精细调整。
效果:产生的图像通常具有自然的亮度和对比度,但可能在极端亮度和暗度区域丢失一些细节。
3. Mantiuk色调映射:
特点:Mantiuk色调映射算法强调在压缩动态范围的同时保持图像的局部对比度。它使用了一种称为“细节增强”的技术,可以在保留更多细节的同时避免晕轮效应(halos)。
参数:通常包括对比度、饱和度和亮度参数,这些参数可以帮助用户根据需要调整图像的视觉风格。
效果:产生的图像通常具有更高的对比度和更丰富的细节,尤其是在高光和阴影区域。这种算法特别适合于需要强调场景细节和结构的场景。
# 创建一个用于Drago色调映射的对象,并设置对比度参数
tonemapDrago = cv2.createTonemapDrago(1.0, 0.7)
# 使用Drago色调映射对象处理HDR图像,得到LDR图像
ldrDrago = tonemapDrago.process(hdrDebevec)
# 调整LDR图像的亮度,使其更接近标准显示设备的范围
ldrDrago = 3 * ldrDrago
# 将调整后的LDR图像保存为jpg格式
cv2.imwrite("ldr-Drago.jpg", ldrDrago * 255)
# 创建一个用于Reinhard色调映射的对象,并设置对比度参数
tonemapReinhard = cv2.createTonemapReinhard(1.5, 0, 0, 0)
# 使用Reinhard色调映射对象处理HDR图像,得到LDR图像
ldrReinhard = tonemapReinhard.process(hdrDebevec)
# 将Reinhard色调映射后的LDR图像保存为jpg格式
cv2.imwrite("ldr-Reinhard.jpg", ldrReinhard * 255)
# 创建一个用于Mantiuk色调映射的对象,并设置对比度参数
tonemapMantiuk = cv2.createTonemapMantiuk(2.2, 0.85, 1.2)
# 使用Mantiuk色调映射对象处理HDR图像,得到LDR图像
ldrMantiuk = tonemapMantiuk.process(hdrDebevec)
# 调整LDR图像的亮度,使其更接近标准显示设备的范围
ldrMantiuk = 3 * ldrMantiuk
# 将Mantiuk色调映射后的LDR图像保存为jpg格式
cv2.imwrite("ldr-Mantiuk.jpg", ldrMantiuk * 255)
四:整体代码实现
import cv2
import numpy as np
def readImagesAndTimes():times = np.array([1 / 30.0, 0.25, 2.5, 15.0], dtype=np.float32)filenames = ["F:\ccccccc/img09.jpg", "F:\ccccccc/img08.jpg", "F:\ccccccc/img04.jpg", "F:\ccccccc/img01.jpg"]images = []for filename in filenames:im = cv2.imread(filename)images.append(im)return images, timesif __name__ == '__main__':# Read images and exposure timesprint("Reading images ... ")images, times = readImagesAndTimes()calibrateDebevec = cv2.createCalibrateDebevec()responseDebevec = calibrateDebevec.process(images, times)mergeDebevec = cv2.createMergeDebevec()hdrDebevec = mergeDebevec.process(images, times, responseDebevec)# Save HDR image.cv2.imwrite("hdrDebevec.hdr", hdrDebevec)print("saved hdrDebevec.jpg ")# # Tonemap using Drago's method to obtain 24-bit color imagetonemapDrago = cv2.createTonemapDrago(1.0, 0.7)ldrDrago = tonemapDrago.process(hdrDebevec)ldrDrago = 3 * ldrDragocv2.imwrite("ldr-Drago.jpg", ldrDrago * 255)# # Tonemap using Reinhard's method to obtain 24-bit color imagetonemapReinhard = cv2.createTonemapReinhard(1.5, 0, 0, 0)ldrReinhard = tonemapReinhard.process(hdrDebevec)cv2.imwrite("ldr-Reinhard.jpg", ldrReinhard * 255)# # Tonemap using Mantiuk's method to obtain 24-bit color imagetonemapMantiuk = cv2.createTonemapMantiuk(2.2, 0.85, 1.2)ldrMantiuk = tonemapMantiuk.process(hdrDebevec)ldrMantiuk = 3 * ldrMantiukcv2.imwrite("ldr-Mantiuk.jpg", ldrMantiuk * 255)
五:效果
不同曝光图像:




融合后的图像:
drago:
Reinhard:

Mantiuk:
相关文章:
opencv-python图像增强四:多曝光融合(方法一)
文章目录 一、简介:二、多曝光融合方案:三、算法实现步骤3.1 读取图像与曝光时间:3.2 计算响应曲线并合并3.3 色调映射 四:整体代码实现五:效果 一、简介: 在摄影和计算机视觉领域,高动态范围&…...
Qt 实战(9)窗体 | 9.2、QDialog
文章目录 一、QDialog1、基本概念2、常用特性2.1、模态与非模态2.2、数据交互 3、总结 前言: Qt框架中的QDialog类是一个功能强大且灵活的对话框控件,广泛应用于各种GUI(图形用户界面)应用程序中,用于处理用户输入、消…...
Spring 事务机制
1. 引言 1.1 什么是事务 事务是由用户定义的一系列操作序列所组成的最小工作单元;这些操作要么全部完成,要么全部不完成,是一个不可分割的工作单元。常见于数据库中的并发控制和数据一致性处理场景。 1.2 事务的特性 事务具有以下特性&am…...
Android 13 GMS 内置壁纸
如图,原生系统上,设备上的壁纸 显示系统内置壁纸。如果没有添加内置壁纸,就显示默认的壁纸。点击进去就是预览页面 扩展下,默认壁纸在 frameworks/base/core/res/res/drawable-sw720dp-nodpi/default_wallpaper.png frameworks/b…...
【LeetCode】234. 回文链表
回文链表 题目描述: 给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。 示例 1: 输入:head [1,2,2,1] 输出:true示例 2&#…...
零基础学会机器学习,到底要多久?
这两天啊,有不少朋友和我说,想学机器学习,但是之前没有基础,不知道能不能学得会。 首先说结论,只要坚持,就能学会,但是一定不能三天打鱼两天晒网,要持之以恒,至少每隔两…...
视频汇聚/安防监控综合平台EasyCVR接入海康私有协议EHOME显示失败是什么原因?
安防监控/视频综合管理平台/视频集中存储/磁盘阵列EasyCVR视频汇聚平台,支持多种视频格式和编码方式(H.264/H.265),能够轻松对接各类前端监控设备,实现视频流的统一接入与集中管理。安防监控EasyCVR平台支持多种流媒体…...
Qt解析XML
背景 本来想解析VS的项目配置文件(*.vcxproj),配合cppclean来发现多余的#incldue。 结果发现低估了难度,VS会间接引入许多目录。 略有不甘,暂且作为一个解析XML文件的示例。 代码 VSProjectParser.h #include <QVector> #include…...
PwnLab: init-文件包含、shell反弹、提权--靶机渗透思路讲解
Vulnhub靶机链接回【PwnLab】 首页有一个登录框 image-20240807124822770 他没有验证码,我们试试暴力破解 image-20240807122743025 开始爆破了,全部失败,哈哈哈 image-20240807122851001 nmap全端口扫描试试 image-20240807131408315 有…...
OpenCV—二值化Threshold()、adaptiveThreshold()
cv2.threshold() c:double cv::threshold ( InputArray src, OutputArray dst, double thresh, double maxval, int type ) (注:源图片, 目标图, 阈值, 填充色, 阈值类型) python:cv.threshold(src,thresh, maxval, type[, dst]) src:源图片…...
第二天:java面向对象编程(OOP)
第二天:java面向对象编程(OOP) 1. 深入理解OOP四大特性 封装(Encapsulation):学习如何将数据(属性)和操作数据的方法(行为)组合成一个独立的单元࿰…...
Selenium + Python 自动化测试07(滑块的操作方法)
我们的目标是:按照这一套资料学习下来,大家可以独立完成自动化测试的任务。 本篇文章主要讲述如何操作滑块。 目前很多系统登录或者注册的页面都有滑块相关的验证,selenium 中对滑块的基本操作采用了元素的拖曳的方式。需要用到Actiochains模…...
三防平板满足多样化定制为工业领域打造硬件解决方案
在当今工业领域,数字化、智能化的发展趋势日益显著,对于高效、可靠且适应各种复杂环境的硬件设备需求不断增长。三防平板作为一种具有坚固耐用、防水防尘防摔特性的工业级设备,正以其出色的性能和多样化的定制能力,为不同行业的应…...
pytorch,用lenet5识别cifar10数据集(训练+测试+单张图片识别)
目录 LeNet-5 LeNet-5 结构 CIFAR-10 pytorch实现 lenet模型 训练模型 1.导入数据 2.训练模型 3.测试模型 测试单张图片 代码 运行结果 LeNet-5 LeNet-5 是由 Yann LeCun 等人在 1998 年提出的一种经典卷积神经网络(CNN)模型,主要…...
Word卡顿的处理方法
1. 检查和关闭后台程序 关闭不必要的后台程序,释放系统资源。使用任务管理器(Ctrl + Shift + Esc)查看占用CPU和内存较高的应用,并关闭它们。2. 更新Microsoft Office 确保你的Microsoft Office软件是最新版本。新版本通常修复了已知的性能问题。打开Word,点击文件 > 账…...
在 Linux上常见的10大压缩格式解压命令和它们对应的压缩格式
文章目录 前言一、解压 .zip 文件二、解压 .tar.gz 或 .tgz 文件三、解压 .tar 文件四、解压 .tar.bz2 文件五、解压 .tar.xz 文件六、解压 .gz 文件七、解压 .bz2 文件八、解压 .xz 文件九、解压 .7z 文件十、解压 .rar 文件总结 前言 Linux 命令可以解压不同格式的压缩文件。…...
【数据结构】三、栈和队列:6.链队列、双端队列、队列的应用(树的层次遍历、广度优先BFS、先来先服务FCFS)
文章目录 2.链队列2.1初始化(带头结点)不带头结点 2.2入队(带头结点)2.3出队(带头结点)❗2.4链队列c实例 3.双端队列考点:输出序列合法性栈双端队列 队列的应用1.树的层次遍历2.图的广度优先遍历3.操作系统…...
技术速递|使用 Native Library Interop 为 .NET MAUI 创建绑定
作者:Rachel Kang 排版:Alan Wang 在当今的应用开发领域,通过利用本机功能来扩展 .NET 应用程序的能力非常宝贵。.NET MAUI 处理程序架构使开发人员能够使用 .NET 代码直接操作本机控件,甚至允许无缝创建跨平台自定义控件。然而&a…...
Linux笔记 --- 标准IO
系统IO的最大特点一个是更具通用性,不管是普通文件、管道文件、设备节点文件、接字文件等等都可以使用,另一个是他的简约性,对文件内数据的读写在任何情况下都是带任何格式的,而且数据的读写也都没有经过任何缓冲处理,…...
洛谷:B3625 迷宫寻路
迷宫寻路 题目描述 机器猫被困在一个矩形迷宫里。 迷宫可以视为一个 n m n\times m nm 矩阵,每个位置要么是空地,要么是墙。机器猫只能从一个空地走到其上、下、左、右的空地。 机器猫初始时位于 ( 1 , 1 ) (1, 1) (1,1) 的位置,问能否…...
OpenCore Legacy Patcher终极指南:让老Mac免费运行最新macOS的完整教程
OpenCore Legacy Patcher终极指南:让老Mac免费运行最新macOS的完整教程 【免费下载链接】OpenCore-Legacy-Patcher Experience macOS just like before 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher OpenCore Legacy Patcher是…...
Taotoken用量看板如何帮助个人开发者管理月度预算
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 Taotoken用量看板如何帮助个人开发者管理月度预算 对于独立工作的个人开发者而言,项目预算往往是决定技术选型与使用策…...
Lingoose框架实战:构建智能客服工单处理AI工作流
1. 项目概述:从“Lingo”到“Goose”,一个AI应用编排框架的诞生如果你最近在折腾大语言模型应用,尤其是想把OpenAI、Anthropic这些API的能力整合到自己的业务流程里,那你大概率已经体会过那种“胶水代码”的烦恼了。今天要聊的这个…...
Ruby LLM框架:为Ruby开发者打造的大语言模型应用开发工具包
1. 项目概述:一个为Ruby语言量身打造的LLM应用框架如果你是一名Ruby开发者,最近被各种大语言模型(LLM)的应用搞得心痒痒,但看着满世界的Python库和框架感到无从下手,那么crmne/ruby_llm这个项目可能就是你在…...
面向开发者的轻量级计划管理工具:配置驱动与命令行优先
1. 项目概述:一个为开发者而生的计划管理工具在软件开发的世界里,我们每天都在与各种“计划”打交道:版本迭代计划、个人学习计划、项目里程碑、甚至是每日的待办清单。然而,一个尴尬的现实是,市面上大多数项目管理工具…...
All in Token, 移动,电信,联通,阿里,百度,华为,字节,Token石油战争,Token经济,百度要“重写”AI价值度量
AI Agent的价值,应该怎么被衡量? 2026年,AI行业的标志性拐点是Agent(智能体)快速普及。Agent作为核心生产力载体,将AI从Chatbot聊天模式带进主动执行的办事时代。 这个时候,如果我们还用旧尺子…...
AI科技热点日报 | 2026年5月16日
文章目录AI科技热点日报 | 2026年5月16日一、大模型与基础技术《人工智能终端智能化分级》系列国家标准发布"九章四号"量子计算原型机刷新世界纪录二、AI政策与监管人工智能科技伦理审查与服务先导计划启动工信部部署高质量行业数据集建设三、Agent与应用"AI教育…...
基于CircuitPython与ItsyBitsy M4打造可编程宏键盘:从硬件到代码全解析
1. 项目概述:打造你的专属输入利器 在键盘这个看似成熟的领域里,我们真的满足于厂商提供的“标准答案”吗?对于视频剪辑师、程序员、设计师或者硬核游戏玩家来说,一套固定的键位布局和功能,往往意味着效率的妥协。真正…...
基于WebRTC的P2P远程控制工具vibe-remote部署与实战
1. 项目概述:一个远程控制的开源解决方案最近在折腾智能家居和远程设备管理,发现很多场景下,我们需要的并不是一个功能大而全的远程桌面软件,而是一个轻量、快速、能穿透内网的远程控制工具。比如,家里的NAS需要临时重…...
RT-Thread SMP启动流程深度解析:从多核同步到调度就绪
1. 项目概述:从单核到多核,RT-Thread的启动逻辑变迁如果你是从RT-Thread 3.x版本一路用过来的老用户,或者刚开始接触RT-Thread 4.x,可能会发现一个显著的变化:启动流程变“复杂”了。以前,一个main函数或者…...
