【图像处理】一种低光照图像的亮度提升方法(Adaptive Local Tone Mapping Based on Retinex for High Dynam

 2023-09-07 阅读 17 评论 0

摘要:【fishing-pan:https://blog.csdn.net/u013921430 转载请注明出处】 前言   在实际的拍照过程中,常常会遇到,光线不足的情况。这时候单反用户一般会调大感光度,调大光圈,以让照片整体更清晰,更亮。那么如果照片已经被拍的很暗了&

【fishing-pan:https://blog.csdn.net/u013921430 转载请注明出处】

前言

  在实际的拍照过程中,常常会遇到,光线不足的情况。这时候单反用户一般会调大感光度,调大光圈,以让照片整体更清晰,更亮。那么如果照片已经被拍的很暗了,怎么办呢?这时候我们可以利用算法来提升图像整体的光照情况,让图像更清晰。

  2013年这篇《Adaptive Local Tone Mapping Based on Retinex for High Dynamic Range Images》发表在了IEEE上,如题目所说,文章提到将高动态图像在低动态范围显示设备上进行显式时,会面临信息丢失的问题。因此结合传统的CENTER/SURROUND RETINEX 技术提出了全局自适应和局部自适应的HDR实现过程,对HDR image 进行色调映射。而文中的全局自适应方法对于低照度图像具有很好的照度提升效果。作者将他的Matlab脚本上传到了Github,有兴趣的可以点击这里去查看。

全局自适应原理

  全局自适应方法的原理很简单,就是两个公式;
Lg(x,y)=log(Lw(x,y)/Lwˉ+1)log(Lwmax/Lwˉ+1)L_{g}(x,y)=\frac{log(L_{w}(x,y)/\bar{L_{w}}+1)}{log(L_{wmax}/\bar{L_{w}}+1)} Lg(x,y)=log(Lwmax/Lwˉ+1)log(Lw(x,y)/Lwˉ+1)
  上述式子中,Lg(x,y)L_{g}(x,y)Lg(x,y) 代表全局自适应处理的输出结果;Lw(x,y)L_{w}(x,y)Lw(x,y) 表示输入图像的亮度值;LwmaxL_{wmax}Lwmax 表示输入图像亮度的最大值;Lwˉ\bar{L_{w}}Lwˉ 表示输入图像的亮度值的对数平均值;由以下公式求得;
Lwˉ=exp(1m∗n∑log(σ+Lw(x,y)))\bar{L_{w}}=exp\left ( \frac{1}{m*n}\sum log(\sigma +L_{w}(x,y))\right ) Lwˉ=exp(mn1log(σ+Lw(x,y)))
  其中,m∗nm*nmn 代表图像的尺寸。σ\sigmaσ 是一个很小的值,为了防止遇到图像中亮度为0的黑点的情况;

怎么提亮照片亮度,  文中提到“随着对数均值趋近于高值,函数的形状从对数趋势转换为线性趋势,因此对低对数均值的图像具有更好的提升效果。”这个方法利用到了图像的对数均值,这就是自适应的体现。

  我在Matlab中分别简单的画了一下曲线,发现在对数均值比较大的时候曲线确实非常接近直线。
在这里插入图片描述

代码&结果

   我根据自己的理解以及作者的Matlab脚本,分别利用OpenCV实现了全局自适应方法。两者有很多细节不一样,结果也有一些差异;
   首先是作者的matlab 代码;

function outval = ALTM_Retinex(I)
II = im2double(I);
Ir=double(II(:,:,1)); Ig=double(II(:,:,2)); Ib=double(II(:,:,3));
% Global Adaptation
Lw = 0.299 * Ir + 0.587 * Ig + 0.114 * Ib;% input world luminance values
Lwmax = max(max(Lw));% the maximum luminance value
[m, n] = size(Lw);
Lwaver = exp(sum(sum(log(0.001 + Lw))) / (m * n));% log-average luminance
Lg = log(Lw / Lwaver + 1) / log(Lwmax / Lwaver + 1);
gain = Lg ./ Lw;
gain(find(Lw == 0)) = 0;
outval = cat(3, gain .* Ir, gain .* Ig, gain .* Ib);
figure;
imshow(outval)

   接着是我参考作者提供的脚本实现的C++ 代码

//-------------------------------
//函数名:adaptHDR;参照作者脚本实现
//函数功能:全局自适应光照度提升
//参数:Mat &scr,输入图像
//参数:Mat &dst,输出图像
//------------------------------
bool adaptHDR(Mat &scr, Mat &dst)
{if (!scr.data)  //判断图像是否被正确读取;{cerr << "输入图像有误"<<endl;return false;}int row = scr.rows;int col = scr.cols;Mat ycc;                        //转换空间到YUV;cvtColor(scr, ycc, COLOR_RGB2YUV);vector<Mat> channels(3);        //分离通道,取channels[0];split(ycc, channels);Mat Luminance(row, col, CV_32FC1);for (int i = 0; i < row; i++){for (int j = 0; j < col; j++){Luminance.at<float>(i, j) =(float)channels[0].at<uchar>(i, j)/ 255;}}double log_Ave = 0;double sum = 0;for (int i = 0; i < row; i++)                 //求对数均值{for (int j = 0; j < col; j++){sum += log(0.001 + Luminance.at<float>(i, j));}}log_Ave = exp(sum / (row*col));double MaxValue, MinValue;      //获取亮度最大值为MaxValue;minMaxLoc(Luminance, &MinValue, &MaxValue);Mat hdr_L (row,col,CV_32FC1);for (int i = 0; i < row; i++){for (int j = 0; j < col; j++){hdr_L.at<float>(i, j) = log(1 + Luminance.at<float>(i, j) / log_Ave) / log(1 + MaxValue / log_Ave);if (channels[0].at<uchar>(i, j) == 0)   //对应作者代码中的gain = Lg ./ Lw;gain(find(Lw == 0)) = 0;	{hdr_L.at<float>(i, j) = 0;}else{hdr_L.at<float>(i, j) /= Luminance.at<float>(i, j);}}}vector<Mat> rgb_channels;        //分别对RGB三个通道进行提升split(scr, rgb_channels);for (int i = 0; i < row; i++){for (int j = 0; j < col; j++){int r = rgb_channels[0].at<uchar>(i, j) *hdr_L.at<float>(i, j); if ( r> 255){r = 255; }rgb_channels[0].at<uchar>(i, j) = r;int g = rgb_channels[1].at<uchar>(i, j) *hdr_L.at<float>(i, j); if (g> 255){ g = 255; }rgb_channels[1].at<uchar>(i, j) = g;int b = rgb_channels[2].at<uchar>(i, j) *hdr_L.at<float>(i, j); if (b> 255){ b = 255; }rgb_channels[2].at<uchar>(i, j) = b;}}merge(rgb_channels, dst); return true;
}

光线暗的照片怎么调亮并好看,  最后是我自己根据自己的理解实现代码

//-------------------------------
//函数名:my_AdaptHDR;自己理解实现
//函数功能:全局自适应光照度提升
//参数:Mat &scr,输入图像
//参数:Mat &dst,输出图像
//------------------------------bool my_AdaptHDR(Mat &scr, Mat &dst)
{if (!scr.data)  //判断图像是否被正确读取;{cerr << "输入图像有误" << endl;return false;}int row = scr.rows;int col = scr.cols;Mat ycc;                        //转换空间到YUV;cvtColor(scr, ycc, COLOR_RGB2YUV);vector<Mat> channels(3);        //分离通道,取channels[0];split(ycc, channels);double log_Ave = 0;double sum = 0;for (int i = 0; i < row; i++)   //求对数均值{for (int j = 0; j < col; j++){sum += log(0.001 + channels[0].at<uchar>(i, j));}}log_Ave = exp(sum / (row*col));double MaxValue, MinValue;      //获取亮度最大值为MaxValue;minMaxLoc(channels[0], &MinValue, &MaxValue);Mat hdr_L(row, col, CV_32FC1);for (int i = 0; i < row; i++){for (int j = 0; j < col; j++){hdr_L.at<float>(i, j) = log(1 + channels[0].at<uchar>(i, j) / log_Ave) / log(1 + MaxValue / log_Ave);}}double L_MaxValue, L_MinValue;            //获取亮度最大值为MaxValue;minMaxLoc(hdr_L, &L_MinValue, &L_MaxValue);for (int i = 0; i < row; i++)            //对亮度通道进行提升;{for (int j = 0; j < col; j++){channels[0].at<uchar>(i, j) = floor(0.5 + 255 * (hdr_L.at<float>(i, j) - L_MinValue) / (L_MaxValue - L_MinValue));}}merge(channels, ycc);cvtColor(ycc, dst, COLOR_YUV2RGB);return true;}

   两种思路的区别主要在于,我的方法是先把图像重RGB空间转换到YUV空间,然后对亮度进行提升,然后转换回RGB空间。这样做有一个问题,只提升了图像的亮度,而没有提高色度和浓度,图像会显得很亮,但是色彩不够鲜艳。而从作者提供的代码的思路来看,他用新得到的图像亮度除以原始图像亮度,得到一个亮度增益,然后将这个增益附加在每个颜色通道上。这样做三通道可以得到同样程度的亮度增强,但是这种方法可能会让图像色彩过饱和。

  来看看结果;
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

总结

   到底谁的思路好,我觉得我还是尊重作者的思路。但是也许有些情况下,我的方法会取得更好的效果,也可能存在更好的思路。但是最主要的方法还是在上面的两个公式中。而作者在文中主要介绍的是局部的映射方法,全局自适应是为后面做局部自适应进行铺垫的,当然,这篇博客中,不会讲到局部的方法了。

照片局部调暗、   对于低照度图像的计处理,我并不在行,这也是第一次接触,有些原理上面的东西还没摸清楚,只是觉得有意思就去实现了一下,有些不足的地方,还请大家指针(指正)。

参考

  1. Ahn H, Keum B, Kim D, et al. Adaptive local tone mapping based on retinex for high dynamic range images[C]//Consumer Electronics
    (ICCE), 2013 IEEE International Conference on. IEEE, 2013:
    153-156.

  2. https://github.com/IsaacChanghau/OptimizedImageEnhance/tree/master/matlab/ALTMRetinex

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/5/12630.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息