【HDR图像处理】HDR图像的色调映射 | python+opencv代码实现总结

news2024/9/24 11:23:15

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、前提opencv知识
    • 1.1、opencv打开一般照片并且显示
    • 1.2、opencv打开HDR图像(这里先不讲如何imshow)
  • 二、经典的色调映射技术以及opencv代码实现
    • 2.1、Reinhard
    • 2.2、Drago
    • 2.3、Durand
    • 2.4、Mantiuk
    • 2.5、对比
    • 2.6、线性映射
  • 三.u律压缩(u律色调映射)


前言

最近在做HDR图像的课题,这里对HDR图像处理里面的关键技术进行记录和总结

一、前提opencv知识

1.1、opencv打开一般照片并且显示

import cv2
# 读取照片
img = cv2.imread('photo.jpg')
# 显示照片
cv2.imshow('Photo', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

1.2、opencv打开HDR图像(这里先不讲如何imshow)

import cv2
# 读取照片
img = cv2.imread('photo.hdr',cv2.IMREAD_ANYDEPTH)

cv2.IMREAD_ANYDEPTH参数告诉OpenCV要读取所有像素值,包括高动态范围(HDR)像素值。

除此之外,还可这样读取HDR图像:

import cv2
# 读取照片
img = cv2.imread('photo.hdr',cv2.IMREAD_ANYDEPTH | cv2.IMREAD_COLOR)

以上两句话在读取HDR图像时是等价的(来自chatgpt)

一般情况下,读取了HDR图像后,需要对其进行归一化等操作(也就是映射到LDR域)。如果不进行归一化等操作,直接使用imshow可能会报错,或者图像一片白,因为HDR图像的单个像素点的亮度值非常高,早就超出了0-255的这个范围,比如如下代码:

import cv2
# 读取照片
img = cv2.imread('gt.hdr',cv2.IMREAD_UNCHANGED)
# 显示照片
cv2.imshow('Photo', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述
这时候展示出的图像一片白

如果不用opencv,用一些自带色调映射的图像查看编辑器也是可以的,比如我自己用的是2345看图王,可以打开HDR,EXR等文件

二、经典的色调映射技术以及opencv代码实现

这些色调映射方法的提出时间是不同的,大致如下:

Reinhard:2001年

Drago:2003年

Durand:2005年

Mantiuk:2008年

这些方法的提出都是为了解决数字图像处理中的色调映射问题,但是它们的具体实现方式和效果略有不同。在实际应用中,可以根据需要选择适合的色调映射方法。

2.1、Reinhard

1)Reinhard

import cv2

# 读取HDR图像
src_img = cv2.imread('gt.hdr', cv2.IMREAD_ANYDEPTH | cv2.IMREAD_COLOR)

# 创建Reinhard色调映射对象
Reinhard = cv2.createTonemapReinhard()

# 对HDR图像进行色调映射
dst_img = Reinhard.process(src_img)

# 保存输出图像
cv2.imwrite('Reinhard.jpg', dst_img * 255)
img=cv2.imread('Reinhard.jpg')
cv2.imshow('Reinhard', img)

# 等待按键按下
cv2.waitKey(0)

# 释放窗口
cv2.destroyAllWindows()

2.2、Drago

2)Drago

import cv2

# 读取HDR图像
src_img = cv2.imread('gt.hdr', cv2.IMREAD_ANYDEPTH | cv2.IMREAD_COLOR)

# 创建Reinhard色调映射对象
Drago = cv2.createTonemapDrago()

# 对HDR图像进行色调映射
dst_img = Drago.process(src_img)

# 保存输出图像
cv2.imwrite('Drago.jpg', dst_img * 255)
img=cv2.imread('Drago.jpg')
cv2.imshow('Drago', img)

# 等待按键按下
cv2.waitKey(0)

# 释放窗口
cv2.destroyAllWindows()

2.3、Durand

3)Durand

import cv2

# 读取HDR图像
src_img = cv2.imread('gt.hdr', cv2.IMREAD_ANYDEPTH | cv2.IMREAD_COLOR)

# 创建Reinhard色调映射对象
Durand = cv2.createTonemapDurand()

# 对HDR图像进行色调映射
dst_img = Durand.process(src_img)

# 保存输出图像
cv2.imwrite('Durand.jpg', dst_img * 255)
img=cv2.imread('Durand.jpg')
cv2.imshow('Durand', img)

# 等待按键按下
cv2.waitKey(0)

# 释放窗口
cv2.destroyAllWindows()

2.4、Mantiuk

4)Mantiuk

import cv2

# 读取HDR图像
src_img = cv2.imread('gt.hdr', cv2.IMREAD_ANYDEPTH | cv2.IMREAD_COLOR)

# 创建Reinhard色调映射对象
Mantiuk = cv2.createTonemapMantiuk()

# 对HDR图像进行色调映射
dst_img = Mantiuk.process(src_img)
print(dst_img)

# 保存输出图像
cv2.imwrite('Mantiuk.jpg', dst_img * 255)
img=cv2.imread('Mantiuk.jpg')
cv2.imshow('Mantiuk', img)

# 等待按键按下
cv2.waitKey(0)

# 释放窗口
cv2.destroyAllWindows()

值得注意的是,使用cv2.createToneXXXX函数时,返回的是一个归一化到0-1的numpy数组,所以后续的展示imshow中需要乘上255。当然如果不乘上255也是可以显示的:虽然像素值被归一化到[0,1]的浮点数范围内,但在显示图像时,imshow函数会自动将像素值转换为[0,255]的整数,然后再进行显示。这是因为在显示图像时,需要将像素值映射到显示设备的亮度范围内,而通常情况下,显示设备的亮度范围是[0,255]的整数。因此,即使像素值已经归一化到[0,1]的浮点数范围内,imshow函数仍然可以正常显示图像。

2.5、对比

我们来看一下三种算法对比效果(Durand报错了 这里不展示):
在这里插入图片描述
从左到右依次为Reinhard Drago Mantiuk

代码如下:

import cv2
import numpy as np

# 加载HDR图像
src_img = cv2.imread('gt.hdr', cv2.IMREAD_ANYDEPTH | cv2.IMREAD_COLOR)
xianxing = cv2.normalize(src_img, None, 0, 255, cv2.NORM_MINMAX, cv2.CV_8UC3)
# 创建色调映射对象
Reinhard = cv2.createTonemapReinhard()
Drago = cv2.createTonemapDrago()
Mantiuk = cv2.createTonemapMantiuk()

# 对HDR图像进行色调映射
Reinhard_img = Reinhard.process(src_img)
Drago_img = Drago.process(src_img)
Mantiuk_img = Mantiuk.process(src_img)

# 将四幅图像拼接为2×2的矩阵
result = np.hstack((Reinhard_img, Drago_img, Mantiuk_img))


# 显示结果
cv2.imshow('Result', result)
cv2.waitKey()
cv2.destroyAllWindows()

2.6、线性映射

我们再来看看线性映射的结果(强行弄成0-255):
在这里插入图片描述
可以看出效果非常不好
代码如下,主要靠的是这句话:ldr_image = cv2.normalize(hdr_image, None, 0, 255, cv2.NORM_MINMAX, cv2.CV_8UC3)

import cv2

# 读取HDR图像
hdr_image = cv2.imread('gt.hdr', cv2.IMREAD_ANYDEPTH | cv2.IMREAD_COLOR )
print(hdr_image.shape)
# 转换图像格式
ldr_image = cv2.normalize(hdr_image, None, 0, 255, cv2.NORM_MINMAX, cv2.CV_8UC3)

# 显示图像
cv2.imshow('HDR Image', ldr_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

三.u律压缩(u律色调映射)

在目前很多的HDR图像生成的国内硕士论文里,大多提到了这种方法:
μ律本身是用于压缩音频信号动态范围的算法,但是它也可以用于压缩 HDR 图像的动态范围。μ律色调映射公式如下:
在这里插入图片描述
其中,
H 表示被归一化到 [0,1] 范围的 HDR 图像,T 表示色调映射后的图像。
这里u的取值论文里都不太一样 ,有些是500,5000

以下是chatgpt生成的代码:

import cv2
import numpy as np

def mu_law_tonemap(hdr_img, mu=5000):
    hdr_img = np.float32(hdr_img)
    L = np.log(1 + mu * hdr_img) / np.log(1 + mu)
    L = np.uint8(L * 255)
    return L

# 读取HDR图像
hdr_img = cv2.imread('gt.hdr', cv2.IMREAD_ANYDEPTH|cv2.IMREAD_COLOR)

# 进行μ律色调映射
tonemapped_img = mu_law_tonemap(hdr_img)

# 显示结果
cv2.imshow('HDR Image', hdr_img)
cv2.imshow('Tonemapped Image', tonemapped_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/430944.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Web 攻防之业务安全:密码找回流程绕过测试.(利用链接跳到后面去)

Web 攻防之业务安全:密码找回流程绕过测试 业务安全是指保护业务系统免受安全威胁的措施或手段。广义的业务安全应包括业务运行的软硬件平台(操作系统、数据库,中间件等)、业务系统自身(软件或设备)、业务所…

MATLAB | 优化工具箱(optimization toolbox)改版后的live editor工具咋用

优化工具箱(optimization toolbox)改版后的live editor工具咋用?本来是不咋想讲这玩意的,但奈何问的人还不少,这里简单讲一下咋用哈。 很多人下了比较新版本MATLAB就顺手像往常一样点开了优化工具箱,但是熟悉的优化APP界面却并没…

网络安全学习路线,小白必备

前言: 趁着今天下班,我花了几个小时整理了下学习路以及我的学习心得,非常不易,希望大家可以点赞收藏支持一波,谢谢。 我的经历: 我 19 年毕业,大学专业是物联网工程,我相信很多人在…

BPM流程引擎升级,让流程管理更简单!

BPM是Business Process Management的缩写,即业务流程管理。 它是一种以构造端到端的业务流程为中心,以持续提高组织业务绩效为目的的系统化方法。通常,BPM也指流程管理的信息化系统。 BPM对企业很多应用场景都有价值,总的来说&am…

Web 攻防之业务安全:验证码绕过测试.(修改数据包中 res_code 的值 实现绕过.)

Web 攻防之业务安全:验证码绕过测试. 业务安全是指保护业务系统免受安全威胁的措施或手段。广义的业务安全应包括业务运行的软硬件平台(操作系统、数据库,中间件等)、业务系统自身(软件或设备)、业务所提供…

【Linux系统管理进程,运行,挂起,杀死进程和crontab计划任务表的使用以及实验的心得体会】

实验 (1)显示本用户的进程,重定向到file1 top命令如果不加限制,默认是查看所有用户的进程情况top -u [用户名] 可以查看该用户名的所有进程 (2)显示本用户所有进程,重定向到file2 top命令如果…

扩展c盘时,如何删除恢复分区

目录 一、前言 二、操作步骤 一、前言 有没有和小编一样想要扩展自己c盘容量时遇到问题的? 就是发现c盘和自己扩展的容量之间有个恢复分区,主要是磁盘管理器那里还删不掉? 就不知道怎么办了,小编摸索了一下最终解决了现在分享…

网络IO(non-blocking io)基础

BIO(blocking io) 传统的网络io模式,面向流,一个线程对接一个会话,因此高并发时会因线程阻塞而性能低效 Java代码: public class BIO implements Connector {private Integer port 8080;Overridepublic v…

前端学习:HTML颜色(什么是RGB、HEX、HSL)

一、什么是RGB、HEX、HSL? 无论是RGB、HEX、HSL,它们的作用只有一个:用数字表达出一种颜色。 1.RGB RGB通过输入的数值,将红色、绿色和蓝色的光源以一定的量混合在一起,形成颜色。 软件中通常让你输入Red、Green、B…

Unity编写Shader基本知识

返回目录 大家好,我是阿赵。 这里通过手写一个最简单的shader,来介绍一下在Unity里面编写Shader的一些基础知识。 一、Shader基本结构 新建一个shader,把里面的内容都删掉,然后输入下面这些内容 shader "testShader"…

GeoIP2:检验IP地址位置识别的实用性

文章目录前言安装环境软件版本说明libmaxminddb 环境安装ngx_http_geoip2_module 安装GeoLite2 数据库下载定时更新测试定位安装模块应用场景重点仅限中国访问,国外禁止仅限中国访问,但放开国外部分IP不同国家展示不同页面IP地址解析总结前言 GeoIP2是一…

我好像发现了PMP通关密码,这14页纸直接背!

备考PMP的宝子们一定要用上这份通关口诀哦! 一周就能背完的PMP考试技巧只有14页纸,共分成了4大模块,完全不用担心看不懂,需要的朋友可以戳下面的卡片在群文件下载,直接打印出来就能背哦,没有任何套路&…

Java每日一练(20230415)

目录 1. 扰乱字符串 🌟🌟🌟 2. 单词拆分 🌟🌟 3. 模拟计算器 ※ 🌟 每日一练刷题专栏 🌟 Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 1. 扰乱字符…

Improved Knowledge Distillation via Teacher Assistant小陈读paper系列

算是经典了吧哈哈 1.他们发现了学生性能下降了,什么时候呢?就是老师模型和学生模型差的太多的时候有了很大gap(一个学生不能请一个维度跨越巨大的老师)(老师可以有效地将其知识转移到一定大小的学生,而不是…

Java导入导出

目录前端Apache POI引依赖导入导出工具类EasyExcel引依赖读Excel指定列名多个Sheet使用提供的转换器或自定义格式转换器对读取到的数据进行格式转换行头即列名写Excel指定导出列复杂头写入日期、数字或自定义格式转换对导出数据进行处理自定义样式合并单元格动态列表头自定义拦…

关于el-input-number 计数器 只能点击一次,之后点击没有效果

哈喽 大家好啊,今天使用计数器发现,点击一次了后就显示不了了 这里怎么点击都点击不了,只能点击一次 然后我发现我代码是这样写的: gitem是一个对象 gitem.saleNum gitem.reduceQuantity || 1;// 剩余可以编辑的数量 因为我这…

【SSL】ssl证书简介、ssl证书生成工具与ssl证书生成步骤

ssl证书简介、ssl证书生成工具与ssl证书生成步骤一、ssl证书是什么?二、ssl证书生成工具有哪些?2.1、工具一:CFSSL2.2、工具二:OpenSSL2.3、工具三:XCA三、ssl证书有什么用?四、ssl证书生成步骤4.1 步骤1&a…

01-SpringBoot入门应用

入门程序:使用SpringBoot开发一个web应用,浏览器发起请求/hello后,给浏览器返回字符串“Hello World ~” 1. 创建springboot工程,并勾选web开发相关依赖 由于我的idea没有Spring Initializr选项,所以我选择使用Maven…

ChatGPT常见术语清单;大厂ChatGPT混战汇总;提示工程技巧完全指南(中译);真机会VS假机会 | ShowMeAI日报

👀日报&周刊合集 | 🎡生产力工具与行业应用大全 | 🧡 点赞关注评论拜托啦! 🤖 『OpenAI/ChatGPT 高频常见词解释清单』一份速查表搞懂最热门 AI 术语 OpenAI 和 ChatGPT 的爆火,以超高的频率将大量AI术…

ISE的仿真库编译步骤

Modelsim10.4与ISE14.7联合仿真 1、指定modelsim的安装位置 2、编译安装仿真库 (1)编译仿真库 点击“开始菜单 -> Xilinx ISE Design Suite 13.2 -> ISE Design Tools -> 64-bit Tools -> Simulation Library Compilation Wizard”&#xff…