FreeImage库HDR转JPEG

来源:互联网 发布:matlab矩阵怎么运算 编辑:程序博客网 时间:2024/06/05 20:45

前言

使用语言C++。
HDR格式图片转换JPEG格式图片,可选的图片处理库有devil,freeImage,oiio。本篇使用FreeImage库中的Tone Mapping Operators来转换图片格式,讲HDR图片转LDR图片。本篇内容大多数翻译自FreeImage3170文档

色调映射操作(Tone Mapping Operator)

色调映射运算符用于将大范围的像素亮度压缩为一个较小的范围,压缩后的图像适合于在具有有限动态范围的设备上显示(显示设备,诸如CRT或LCD的设备和打印介质)。
原则上这个问题很简单:我们需要转一个数字范围很大的图像,转换为包含0到255范围内的整数的图像,以便我们可以在一个上显示打印机或显示器。 这表明线性缩放是一种可能的解决方案。 不过这个方法有缺陷,因为图像的亮或暗区域的细节将由于丢失。因此,随后的量化,并且所显示的图像将不会被感知为相同被拍摄的场景。 因此,更精细的算法,称为色调映射运算,用来准确的渲染HDR。(高动态范围图像)

这是我的HDR图像,1.33MB
这里写图片描述

下面来介绍可用的几个方法。

1.FreeImage_ToneMapping

函数声明:

DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ToneMapping(    FIBITMAP *dib,    FREE_IMAGE_TMO tmo,     double first_param FI_DEFAULT(0),     double second_param FI_DEFAULT(0));

转换HDR图像(48位RGB图像,或96位RGBF图像)到一个24位RGB图像,适应显示。

tmo,参数指定一个色调映射操作用于转换操作。方法首先把输入图片转化为96位RGBF图像(使用FreeImage_ConvertToRGBF),然后,使用以下方法的其中一个转换位图dib。

first_param 和 second_param 所代表的含义,取决于算法的选择(之后有每个色调映射操作的定义)。当两个参数都设置为0,那么将使用所选择算法的默认参数值。

parameter tone mapping operator FITMO_DRAGO03 自适应对数映射(F.Derago,2003) FITMO_REINHARD05 动态范围减少灵感来自光感受器生理学(E. Reinhard,2005) FITMO_FATTAL02 梯度域高动态范围压缩(R. Fattal,2002)
// HdrConvertJpeg.cpp : 定义控制台应用程序的入口点。#include "stdafx.h"#include "FreeImage.h"#include <iostream>using namespace std;#pragma comment(lib,"FreeImage.lib")//错误处理void FreeImageErrorHandler(FREE_IMAGE_FORMAT fif,const char *message){    printf("_n*** ");    printf("%s Format_n", FreeImage_GetFormatFromFIF(fif));    printf(message);    printf(" ***_n ");}int main(){    FreeImage_Initialise(true);    // 错误处理    FreeImage_SetOutputMessage(FreeImageErrorHandler);    // 文件选择    char* filename = "E:\\123\\HDR_512_nMips_Default.HDR";    // 获得位图    FIBITMAP *bitmap = FreeImage_Load(FIF_HDR, filename, 0);    // 之后的代码都是替换这一句,用不同的方法转换    // 之后的代码都是替换这一句,用不同的方法转换    // 之后的代码都是替换这一句,用不同的方法转换    FIBITMAP *bitmapNew = FreeImage_ToneMapping(bitmap, FITMO_DRAGO03);    // 保存文件    FreeImage_Save(FIF_JPEG, bitmapNew, "E:\\123\\TestTMO.jpeg", 0);    FreeImage_Unload(bitmap);    FreeImage_Unload(bitmapNew);    FreeImage_DeInitialise();    system("pause");    return 0;}

在这里随便选择一个方法,FITMO_DRAGO03,使用其默认值,转换效果(右边)如下。
这里写图片描述

2.FreeImage_TmoDrago03

函数声明:

DLL_API FIBITMAP *DLL_CALLCONV FreeImage_TmoDrago03(    FIBITMAP *src,     double gamma FI_DEFAULT(2.2),     double exposure FI_DEFAULT(0));

使用基于亮度值的算法压缩,将HDR转换到24bit RGB图像,模仿人类对光的反应。引入偏置功率函数以自适应地改变对数基,导致细节和对比度的良好保存。

gamma,伽马,取值范围>0,是在色调之后应用的伽马校正映射。 值1表示无更正。 默认的2.2值,用于原来的作者的论文被推荐为一个很好的起始价值。
exposure ,曝光参数范围,取值区间[-8,8],是允许用户使用的曝光比例因子将输出图像的亮度调整到显示条件。 默认值(0)意味着不应用校正。 较高的值将使图像更亮,而较低值使图像变暗。

FIBITMAP *bitmapNew = FreeImage_TmoDrago03(bitmap,2.2,-2.5);

效果(右侧)一般,勉强能接受吧,亮度不好调整。
这里写图片描述

3.FreeImage_TmoReinhard05

函数声明:

DLL_API FIBITMAP *DLL_CALLCONV FreeImage_TmoReinhard05(    FIBITMAP *src,    double intensity FI_DEFAULT(0),    double contrast FI_DEFAULT(0));

使用全局运算符将高动态范围图像转换为24位RGB图像,灵感来自人体视觉系统的感光体生理学。

intensity,强度参数,范围[-8,8],控制整体图像强度。默认值0表示无更正。 较高的值将使图像更轻,而较低的值使图像更暗。
contrast,对比度参数,范围[0.3,1.0],控制整体图像对比度。 什么时候使用默认值(0),此参数自动计算。

FIBITMAP *bitmapNew = FreeImage_TmoReinhard05(bitmap,1.5,0.41);

感觉颜色的多样性降低的蛮厉害的,效果(右侧)一般。
这里写图片描述

4.FreeImage_TmoReinhard05Ex

函数声明:

DLL_API FIBITMAP *DLL_CALLCONV FreeImage_TmoReinhard05Ex(    FIBITMAP *src,    double intensity FI_DEFAULT(0),    double contrast FI_DEFAULT(0),    double adaptation FI_DEFAULT(1),    double color_correction FI_DEFAULT(0));

使用全局/本地算子将高动态范围图像转换为24位RGB图像,灵感来自人体视觉系统的感光体生理学。用户控制强度,对比度,适应度,色彩自适应水平,这4个参数。

intensity,强度参数,范围[-8,8]。默认值0表示无校正。较高的值会使图像更亮,而较低的值会使图像变暗。
contrast,对比度参数,范围[0.3,1.0]。 使用默认值(0)时,将自动计算此参数。
adaptation,适应度,范围[0:1]。 当使用默认值(1)时,自适应是局部的,并且基于像素强度。 当使用值0时,自适应是全局的,并且基于平均信道强度。
color_correction,色彩自适应水平参数,在范围[0:1]。使用默认值(0)表示没有色彩适配,即所有3个色彩通道的自适应水平相同。 将此值设置为1表示每个R,G,B通道被独立处理。

FIBITMAP *bitmapNew = FreeImage_TmoReinhard05Ex(bitmap, 1.9, 0.39, 0.3, 0.5);

上面代码的效果,慢慢调整,感觉效果(右侧)不错。
这里写图片描述

5.FreeImage_TmoFattal02

函数声明:

DLL_API FIBITMAP *DLL_CALLCONV FreeImage_TmoFattal02(    FIBITMAP *src,    double color_saturation FI_DEFAULT(0.5),    double attenuation FI_DEFAULT(0.85));

使用本地操作将高动态范围图像转换为24位RGB图像,该局部算法通过衰减大梯度的幅度来操纵亮度图像的梯度场。 然后通过求解修正梯度场上的泊松方程获得新的低动态范围图像。(反正我是看不懂的QVQ)

color_saturation,色彩饱和度参数,在[0.4,0.6]范围。
attenuation,衰减量,在[0.8,0.9]的范围内。

注意:
该算法通过使用基于多网格算法的泊松求解器来解决与图像中的像素一样多的部分微分方程式。 因此,该算法可能需要很长时间(最多5个或更多)才能完成。

FIBITMAP *bitmapNew = FreeImage_TmoFattal02(bitmap,0.6,0.9);

这个效果(右侧)就不尽如人意了。
这里写图片描述

原创粉丝点击