代码编织梦想

F. Drago等人在《Adaptive Logarithmic Mapping For Displaying High Contrast Scenes》中提到了一种HDR增强算法,本文尝试对其进行复现。

在这个亮度映射解决方案中的对数关系使用Stockham提出的转换方式作为图像处理的基础,Stockham使用如下公式作为低照度图像增强的方法:
在这里插入图片描述
其中,Ld为输出的亮度值,Lw为输入的亮度值,Lmax为最大的亮度值。

我曾以YUV简单实现这个算法逻辑:
YUV颜色空间介绍,低照度图像增强算法。

由于该算法应用于场景照明特征不明显的情况下,所以需要对 RGB 和 CIE XYZ 进行相互转换,以便提取出Y应用于该算法。之后在Stockham的基础上乘以一个用户可设置的曝光因子。

附:Yxy、XYZ空间介绍及与RGB的相互转换公式

最终得出的增强公式为:

在这里插入图片描述
其中,Ld为输出的亮度值,Lw为输入的亮度值,Lmax为最大的亮度值。L dmax是设定的一个比例因子,根据不同的显示器需要进行调整,CRT显示器可以取100,也可以取到更大值,此处默认设置为100。

b可以理解为增强强度的参数。

b的值在0.7到0.9之间对于生成感知良好的图像最有用。与b=1.0的图像相比,b=0.85的图像亮度大约是两倍,b=0.7的图像亮度大约是三倍。这影响了图像的真实性,即使由于偏差值的减少而增加的对比度自然会导致更亮的图像。原作者提出0.85作为默认参数设置。

最后再对其做一个校正,以补偿观看环境。此处实现先做ITU-R BT.709gamma校正,原作者给出了一个调整后的校正,实际可根据场景以下面的公式进行调整。

在这里插入图片描述

实现:

#include <iostream>
#include <opencv2/opencv.hpp>

#include "detect.h"
#include "enhance.h"

using namespace std;
using namespace cv;


double Transform(double x)
{
	if (x <= 0.018)return x * 4.5;
	return 1.099*pow(x,0.45) - 0.099;
}
struct zxy {
	double x, y, z;
}s[2500][2500];

//sR, sG and sB (Standard RGB) input range = 0 ÷ 255
//X, Y and Z output refer to a D65/2° standard illuminant.

double rgbValueTrans(double value)
{
    double output;
    if(value > 0.04045)
    {
        output = pow( ((value + 0.055)/1.055),2.4);
    }
    else
    {
        output = value / 12.92;
    }

    output = output * 100 ;

    return output;
}
//X, Y and Z input refer to a D65/2° standard illuminant.
//sR, sG and sB (standard RGB) output range = 0 ÷ 255
double xyzValueTrans(double value)
{

    double output;
    if(value > 0.0031308)
    {
        output = 1.055 * pow(value,1/2.4) - 0.055;
    }
    else
    {
        output = value * 12.92;
    }

    if (output < 0)output = 0; if (output>1)output = 1;
    output = output * 255 ;

    return output;
}


int test(cv::Mat input_img, cv::Mat out_img) {
	int rows = input_img.rows;
	int cols = input_img.cols;
	double r, g, b;
	double lwmax = -1.0, base = 0.73;

    int Ldmax = 100;

	//1.BGR转XYZ
	for (int i = 0; i < rows; i++) {
		for (int j = 0; j < cols; j++) {
			b = rgbValueTrans( (double)input_img.at<Vec3b>(i, j)[0] / 255.0 );
			g = rgbValueTrans( (double)input_img.at<Vec3b>(i, j)[1] / 255.0 );
			r = rgbValueTrans( (double)input_img.at<Vec3b>(i, j)[2] / 255.0 );

			s[i][j].x = (0.4124*r + 0.3576*g + 0.1805*b);
			s[i][j].y = (0.2126*r + 0.7152*g + 0.0722*b);
			s[i][j].z = (0.0193*r + 0.1192*g + 0.9505*b);
			lwmax = max(lwmax, s[i][j].y);
		}
	}

	for (int i = 0; i < rows; i++) {
		for (int j = 0; j < cols; j++) {
			//XYZ转Yxy
			double xx = s[i][j].x / (s[i][j].x + s[i][j].y + s[i][j].z);
			double yy = s[i][j].y / (s[i][j].x + s[i][j].y + s[i][j].z);
			double tp = s[i][j].y;
			
			s[i][j].y = 0.01 * Ldmax* log(s[i][j].y + 1) / log(2 + 8.0*pow((s[i][j].y / lwmax), log(base) / log(0.5))) / log10(lwmax + 1);
			s[i][j].y = Transform(s[i][j].y);
            double x = s[i][j].y / yy*xx;
			double y = s[i][j].y;
			double z = s[i][j].y / yy*(1 - xx - yy);

			r = 3.2410*x - 1.5374*y - 0.4986*z;
			g = -0.9692*x + 1.8760*y + 0.0416*z;
			b = 0.0556*x - 0.2040*y + 1.0570*z;

            r = xyzValueTrans(r);
            g = xyzValueTrans(g);
            b = xyzValueTrans(b); 

			out_img.at<Vec3b>(i, j)[0] = int(b);
			out_img.at<Vec3b>(i, j)[1] = int(g);
			out_img.at<Vec3b>(i, j)[2] = int(r);
		}
	}
	return 0;
}


int main()
{
	Mat src = imread("/home/seeking/Documents/0706/1.png");
	Mat src1, dst;

	resize(src,src1,Size(0,0),0.5,0.5);

	dst = src1.clone();

    imshow("src1",src1);
    test(src1, dst);
    imshow("dst",dst);

    //Enhance gamma = Enhance();
    //Mat output = gamma.gammaWithParameter(src1,2.2);
    //imshow("gamma",output);
    waitKey(0);
}

HDR介绍

高动态范围(High-Dynamic Range,简称HDR),又称宽动态范围技术,是在非常强烈的对比下让摄像机看到影像的特色而运用的一种技术。 当在强光源(日光、灯具或反光等)照射下的高亮度区域及阴影、逆光等相对亮度较低的区域在图像中同时存在时,摄像机输出的图像会出现明亮区域因曝光过度成为白色,而黑暗区域因曝光不足成为黑色,严重影响图像质量。摄像机在同一场景中对最亮区域及较暗区域的表现是存在局限的,这种局限就是通常所讲的“动态范围“。HDR图片是使用多张不同曝光的图片,然后再用软件组合成一张图片。它的优势是最终你可以得到一张无论在阴影部分还是高光部分都有细节的图片。在正常的摄影当中,或许你只能选择两者之一。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_48846514/article/details/126983564

Tone Mapping算法系列二:一种自适应对数映射的高对比度图像显示技术及其速度优化-爱代码爱编程

办公室今天停电,幸好本本还有电,同事们好多都去打麻将去了,话说麻将这东西玩起来也还是有味的,不过我感觉我是输了不舒服,赢了替输的人不舒服,所以干脆拜别麻坛四五年了,在办公室一个人整理下好久前的一片论文的思想,和万千世界里有缘人共同分享下资源了。 论文的名字是,相关的PDF文档可以在百度上下载到,翻译成中文的意思是一种显示高对比度场景的自适应对数映射算法,

HDR 色调映射线性压缩(matlab)-爱代码爱编程

HDR 色调映射线性压缩(matlab) 目录 HDR 色调映射学习(matlab) 1、介绍 2、matlab在HDR上的应用  参考文章: 1、介绍 即使在引入数码相机之后,多年来,专业摄影师还是更喜欢使用基于胶片的SLR相机进行摄影。 主要原因是与胶片相比,数码相机图像传感器的像素数更少。 如今,在半导体制造的较新技术中,此问题已被较小

毕设—高动态范围图像渲染算法之基于对数变换的色调映射技术(三)-爱代码爱编程

这个算法是我第一个实现的色调映射算法,也是五种算法中原理最清晰,实现最简单的。(原理见:一种自适应对数映射的高对比度图像显示技术) 这个算法来源于论文《Adaptive Logarithmic Mapping For Displaying High Contrast Scenes》是一篇2003年的古老算法。其实这个算法OpenCV 3.0已经实现了,但

图像增强算法Python实现之Retinex(含代码)-爱代码爱编程

Retinex是一种常用的建立在科学实验和科学分析基础上的图像增强方法,它是Edwin.H.Land于1963年提出的。就跟Matlab是由Matrix和Laboratory合成的一样,Retinex也是由两个单词合成的一个词语,他们分别是retina 和cortex,即:视网膜和皮层。Land的retinex模式是建立在以下三个假设之上的: 1.真实世

基于自适应对数映射方法的高对比度场景展现(论文及代码复现)-爱代码爱编程

开篇介绍 由于先前在课程当中听说了低照度视频增强算法及其应用,在课程结束后,我做了一个学习标记未完成,打算往后再深入。于是最近又开始重新搜刮此类文章,无意中找到了发表于2003年的一篇欧洲图形学协会的古董级别的期刊——《Adaptive Logarithmic Mapping For Displaying High Contrast Scenes》 先从

ALTM算法简谈-爱代码爱编程

ALTM算法简谈 CSDN创作小白,这几天接触了很多新的东西,觉得有一些深度,也很有价值,想记录一下,有需要的朋友也可以对这方面了解的更加深入一些。 从ALTM的全名入手 Adaptive Local Tone Mapping Based on Retinex for High Dynamic Range Images 翻译一下大致就是自适应的局部色

[论文阅读] ALM-HCS(高对比场景自适应对数映射)-爱代码爱编程

[论文阅读] ALM-HCS(高对比场景自适应对数映射) 文章: Adaptive Logarithmic Mapping for Displaying High Contrast Scenes 1. 论文目的 将高动态范围图像映射到机器可以显示的动态范围, 作者提出了几个要求: The design of our tone mapping

色调映射(Tone Mapping)-爱代码爱编程

一、概述         虽然HDR 图像有较大的动态范围,能更细致地反映真实场景,但他的缺点也很明显。一是同尺寸的数据比低动态范围图像大,需要更大的存储空间与传输带宽。二是难以输出,目前大多数显示器、打印机等图形输出设备的动态范围要比普通的高动态范围图像小得多。。因此,色调映射技术在这样的背景下,就显得尤为重要。HDR 图像处理的一个重要方面就是色调映