拉普拉斯金字塔在多图HDR算法中的应用以及多曝光图像的融合算法简介。
在SSE图像算法优化系列二十九:基础的拉普拉斯金字塔融合用于改善图像增强中易出现的过增强问题(一) 一文中我们曾经描述过基于几种高频融合法则的拉普拉斯金字塔融合算法,那里是主要针对2副图像的。实际的应用中,我们可能会遇到多帧图像的融合过程(图像都是对齐后的),特别是多帧不同曝光度的图像的融合问题,在相机的应用中较为广泛,我们同时也可以认为这是另外一种的HDR算法。
这方面最经典的文章是2007年Tom Mertens等人发表的《Exposure Fusion》一文,用简单的篇幅和公式描述了一个非常优异的合成过程,虽然在2019年Charles Hessel发表了一篇《Extended Exposure Fusion》的文章中,提出了比Exposure Fusion更为优异的合成效果,但是代价是更高昂的计算成本,而Exposure Fusion也已经相当优秀了,本文主要简单记录下个人的Exposure Fusion优化过程。
Exposure Fusion的思路也非常之简单,输入是一系列图像对齐后的大小格式相同的图像,输出是一张合成的多细节图。那么在进行计算之前,他需要做以下的准备。
1、对每副图像按照某些原则计算每融合的权重。文章里提出了3种权重。
(1) 对比度:
Contrast: we apply a Laplacian filter to the grayscale version of each image, and take the absolute value of the filter response [16]. This yields a simple indicator C for contrast. It tends to assign a high weight to important elements such as edges and texture.
对应的matlab代码非常简单:
% contrast measure
function C = contrast(I)
h = [0 1 0; 1 -4 1; 0 1 0]; % laplacian filter
N = size(I,4);
C = zeros(size(I,1),size(I,2),N);
for i = 1:N
mono = rgb2gray(I(:,:,:,i));
C(:,:,i) = abs(imfilter(mono,h,'replicate'));
end
我们可以认为就是个边缘检测。
(2)饱和度
Saturation: As a photograph undergoes a longer exposure, the resulting colors become desaturated and eventually clipped. Saturated colors are desirable and make the image look vivid. We include a saturation measure S, which is computed as the standard deviation within the R, G and B channel, at each pixel。
% saturation measure
function C = saturation(I)
N = size(I,4);
C = zeros(size(I,1),size(I,2),N);
for i = 1:N
% saturation is computed as the standard deviation of the color channels
R = I(:,:,1,i);
G = I(:,:,2,i);
B = I(:,:,3,i);
mu = (R + G + B)/3;
C(:,:,i) = sqrt(((R - mu).^2 + (G - mu).^2 + (B - mu).^2)/3);
end
也是非常简单的过程。
(3)曝光度
Well-exposedness: Looking at just the raw intensities within a channel, reveals how well a pixel is exposed. We want to keep intensities that are not near zero (underexposed) or one (overexposed). We weight each intensity i based on how close it is to 0.5 using a Gauss curve: exp - (i-0.5)*(i-0.5)/(2*σ *σ), where σ equals 0.2 in our implementation. To account for multiple color channels, we apply the Gauss curve to each channel separately, and multiply the results, yielding the measure E。
% well-exposedness measure
function C = well_exposedness(I)
sig = .2;
N = size(I,4);
C = zeros(size(I,1),size(I,2),N);
for i = 1:N
R = exp(-.5*(I(:,:,1,i) - .5).^2/sig.^2);
G = exp(-.5*(I(:,:,2,i) - .5).^2/sig.^2);
B = exp(-.5*(I(:,:,3,i) - .5).^2/sig.^2);
C(:,:,i) = R.*G.*B;
end
每副图像得到三个指标(对比度C、饱和度S以及曝光度E),将他们相乘得到这幅图像的综合权重W。
2、根据每副图像的权重,计算在序列中图像的每副图像的归一化权重,原文表述如下:
To obtain a consistent result, we normalizethe values of the N weight maps such that they sum to one at each pixel (i, j):
注意,这是单个像素进行的处理,也就是说对于一个序列的图像,每个对应像素位置的权重先计算好后,再累加得到总权重,然后在每个对应像素的权重除以总权重得到归一化的值。
3、理论上讲,得到了这些权重,就可以对N个图像进行直接融合,即使用下述公式:
但是如果真的这样做,得到的结果惨不忍睹,即使我们对归一化后的权重进行高斯模糊、保边模糊等等也是解决不了问题的。所以这个文章的最核心的精华部分就在下面的过程中了。
4、我们并不是直接用这些权重进行合成,而是对原序列图像进行高斯拉普拉斯金字塔分解(利用其中的拉普拉斯数据),对各序列对应的归一化权重做高斯金字塔分解。 然后重构拉普拉斯金字塔,重构的规则为:
即对合成后各层拉普拉斯金字塔数据,用每个序列的权重的高斯金字塔数据乘以对应的拉普拉斯金字塔数据,然后累加。就如此简单。
关于这个算法的原理性说明,CSDN这个作者讲的也比较好: 【HDR】曝光融合(Exposure Fusion),有兴趣可以参考。
这个算法的效果通过测试确实还是可以的,原始的作者提供了MATLAB版本的代码,但是实际测试速度是非常慢的,这个也不怪这些论文的作者,他们的重点是实现算法本身,而不是工程化。
为了能提高算法的实用性,我们使用C++结合SIMD指令对该过程进行优化。优化的方式主要有以下几个方面:
1、通过适当的改变数据类型来提高速度。
M版本的代码是全程是使用的浮点类型的来计算各种数据的,为了效率,有些过程我们可以使用整形来代替。比如获取各个特征的权重的时,我们可以用byte来记录就可以了。在比如金字塔的分解和重构时,高斯金字塔我们也用byte类型记录,拉普拉斯金字塔考虑到有负数以及数据的范围,可以用signed short类型来记录。
2、通过改变数据类型后,使用对应的SIMD指令可以起到更大的步长,浮点数一般一次性只能处理4个数,如果是signed short则可以同时处理8个数据了。
3、对于金字塔分解和重构,要从原理上进行优化,详见:SSE图像算法优化系列二十六:和时间赛跑之优化高斯金字塔建立的计算过程。
我们以计算饱和的过程为例,看看SSE的优化步骤:
简简单单的M代码,需要大概10倍以上行数的C代码和SIMD指令进行优化。
实际上,我们在优化时,归一化的那个权重矩阵我也用byte类型来保存数据,原本以为这样每个图的权重有可能会比较小,存在精度损失,不过实际测试,和M代码的结果也没啥特别大的视觉区别。
另外,还有内存方面的优化问题,如果建立所有图像的金字塔序列,然后再计算特征合成,这样会占用比较多的内存,特别是图像序列比较多时,实际上我们可以边分解边进行计算,这样带来的好处时速度有适当加速(应该还是cache miss较小的原因),当然如果每个序列都分配金字塔的内存,有一个好处就是,可以使用omp进行并行,适当的通过占用资源提高速度。
原始论文的作者在获取了各个特征的权重后,是使用的乘法来统计特征,我这里也使用了加法进行测试,测试结果是加法的结果比乘法的要稍微暗一点。区别也不是很大,但是要注意如果是使用乘法,有的时候有些特征的权重为0,为了不让其他特征的权重被淹没掉,建议加一后再乘。
效果:
其中第一个图是使用4副752*500的图合成,M代码大约耗时1600ms,我这里优化后的速度大概是25ms,有64倍的提速。
第二个图使用的是9副1024*683的图合成,M代码大约耗时5000ms,我这里优化后的速度大概是80ms,也有约60倍的提速。
从两幅图的合成结果来看,至少视觉上是非常不错的。不过在第一幅的中间靠上的部分的天空,以及第二副的右下角的台灯的中间部分还是有过曝的现象,这两个部分在原图中实际上是可以找到比较好的底图的,但是合成结果并没有吸收他们,这个可以适当的通过改变金字塔的数量来调节,但是没有啥理论依据去支持他,比如我们把他们的金字塔分别调整为6和7时效果如下两图所示:
这个现象在有些论文里也有提到,即金字塔层数太深,可能导致结果出现out-of-range的瑕疵,金字塔太少了,会有low-frequency halos出现。
这个算法还有一个应用场景,在2019年的另外一篇论文里有提及: Simulated Exposure Fusion, 他的输入只有一张图片,然后通过某些手段生成一个序列的图像,然后在把这序列的图像予以使用EF算法合成,从而得到不错的结果,这个待我有空了也来研究一下,这也是个不错的主意。
这个算法也应该非常适合使用GPU进行优化,那可能会获得更为客观的提速比,对于某些应用从而得到实时级别的效果。
在SSE图像算法优化系列二十九:基础的拉普拉斯金字塔融合用于改善图像增强中易出现的过增强问题(一)一文中使用的融合方法,实际上也是可以应用于多图的融合的,只不过这个时候低频的融合方式就不能是选择哪一个图了,此时可以使用平均值、最大值、最大值等策略,而高频融合一般只能使用AbsMax策略, 那个3*3 AbsMax方法也不可以使用了(因为一致性检测哪里无法实现)。
不过这种融合对于多图来说一般效果不是很好,但是不排除也有其应用场景,他的一个优势就是速度能够做到更快,通常是本文放大的1/3耗时左右,而且内存的占用也很少。
另外,对于这个算法,还有一个现象就是其对图像的合成结果和用光度立体法对那些图的合成结果似乎很像,当然,仅仅是合成结果类似,广地立体能获得的其他信息这个算法是无法获取的。
提供一个测试DEMO供有兴趣的朋友玩玩:https://files.cnblogs.com/files/Imageshop/Exposure_Fusion.rar?t=1694501148&download=true
或者有兴趣的朋友也可以在ipol网站中找到一个在线的DEMO以及代码,详见地址:https://ipolcore.ipol.im/demo/clientApp/demo.html?id=278
如果想时刻关注本人的最新文章,也可关注公众号或者添加本人微信: laviewpbt
翻译
搜索
复制
拉普拉斯金字塔在多图HDR算法中的应用以及多曝光图像的融合算法简介。的更多相关文章
- 【笔记】KNN之网格搜索与k近邻算法中更多超参数
网格搜索与k近邻算法中更多超参数 网格搜索与k近邻算法中更多超参数 网络搜索 前笔记中使用的for循环进行的网格搜索的方式,我们可以发现不同的超参数之间是存在一种依赖关系的,像是p这个超参数,只有在 ...
- SSE图像算法优化系列二十九:基础的拉普拉斯金字塔融合用于改善图像增强中易出现的过增强问题(一)
拉普拉斯金字塔融合是多图融合相关算法里最简单和最容易实现的一种,我们在看网络上大部分的文章都是在拿那个苹果和橙子融合在一起,变成一个果橙的效果作为例子说明.在这方面确实融合的比较好.但是本文我们主要讲 ...
- SSE图像算法优化系列二十八:深度优化局部拉普拉斯金字塔滤波器。
基于局部拉普拉斯金字塔的Edge-aware滤波器是在2011年由Adobe 公司的研究员Sylvain Paris(大神级人物,写了很多文章)提出的,我在4年前曾经参考有关代码实现过这个算法,但是速 ...
- OpenCV图像金字塔:高斯金字塔、拉普拉斯金字塔与图片尺寸缩放
这篇已经写得很好,真心给作者点个赞.题目都是直接转过来的,直接去看吧. Reference Link : http://blog.csdn.net/poem_qianmo/article/detail ...
- 【OpenCV新手教程之十三】OpenCV图像金字塔:高斯金字塔、拉普拉斯金字塔与图片尺寸缩放
本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/26157633 作者:毛星云(浅墨) ...
- 学习 opencv---(12)OpenCV 图像金字塔:高斯金字塔,拉普拉斯金字塔与图片尺寸缩放
在这篇文章里,我们一起学习下 图像金字塔 的一些基本概念,如何使用OpenCV函数pyrUp和pyrDown 对图像进行向上和向下采样,以及了解专门用于缩放图像尺寸的resize函数的用法.此博文一共 ...
- OpenCV笔记(3)(Canny边缘检测、高斯金字塔、拉普拉斯金字塔、图像轮廓、模板匹配)
一.Canny边缘检测 Canny边缘检测是一系列方法综合的结果.其中主要包含以下步骤: 1.使用高斯滤波器,平滑图像,滤除噪声. 2.计算图像中每个像素点的梯度强度和方向. 3.应用非极大值抑制(N ...
- opencv —— resize、pyrUp 和 pyrDown 图像金字塔(高斯金字塔、拉普拉斯金字塔)与尺寸缩放(向上采样、向下采样)
我们经常会将某种尺寸的图像转化为其他尺寸的图像,如果需要放大或者缩小图像的尺寸,在 OpenCV 中可以使用如下两种方法: resize 函数,最直接的方法. pyrUp 和 pyrDown 函数,即 ...
- OpenCV计算机视觉学习(7)——图像金字塔(高斯金字塔,拉普拉斯金字塔)
如果需要处理的原图及代码,请移步小编的GitHub地址 传送门:请点击我 如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractice 本节 ...
- KMP算法中next函数的理解
首先要感谢http://blog.csdn.net/v_july_v/article/details/7041827以及http://blog.chinaunix.net/uid-27164517-i ...
随机推荐
- 【LeetCode双向链表】LRU详解,双向链表实战
LRU缓存 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构. 实现 LRUCache 类: LRUCache(int capacity) 以 正整数 作为容量 capacity ...
- opencv图像显示问题
opencv 的图像类型都是numpy array.dtype = uint8. 如果是默认的python的int类型的numpy array,即使每个整数都在范围0-255, 图像也不会显示,必须转 ...
- C++面试八股文:什么是RAII?
某日二师兄参加XXX科技公司的C++工程师开发岗位第13面: 面试官:什么是RAII? 二师兄:RAII是Resource Acquisition Is Initialization的缩写.翻译成中文 ...
- RabbitMQ快速使用代码手册
本篇博客的内容为RabbitMQ在开发过程中的快速上手使用,侧重于代码部分,几乎没有相关概念的介绍,相关概念请参考以下csdn博客,两篇都是我找的精华帖,供大家学习.本篇博客也持续更新~~~ 内容代码 ...
- 如何在Databricks中使用Spark进行数据处理与分析
目录 <如何在Databricks中使用Spark进行数据处理与分析> 随着大数据时代的到来,数据处理与分析变得越来越重要.在数据处理与分析过程中,数据的存储.处理.分析和展示是不可或缺的 ...
- 图像处理_Retinex图像增强
单尺度SSR (Single Scale Retinex) 图像 S ( x , y ) S(x,y) S(x,y)分解为两个不同的图像:反射图像 R ( x , y ) R(x,y) R(x,y), ...
- ARM Trusted Firmware——编译选项(二)
@ 目录 1. 常用部分 2. 安全相关 2.1 签名 2.2 加密 2.3 哈希 2.4 中断 3.GICv3驱动程序选项 4. 调试选项 1. 常用部分 编译选项 解释 BL2 指定生成fip文件 ...
- Spring-Bean(二)
环境在spring-Bean(一)的配置下 https://www.cnblogs.com/doubleconquer/p/15603706.html 来查看ApplicationContext的执行 ...
- boinc使用笔记
安装 yum install -y epel-release yum install -y boinc-client boinc-manager 启动 在图形界面开启终端 boinc boincmgr
- ch-manager.sh
[root@dev-clickhouse1 ~]# cat ch-manager.sh #!/bin/bash ch_arr=(ch1-shard1-main ch1-shard2-sub ch2-s ...