何 春,宋国琴
(西华师范大学 教育信息技术中心,四川 南充 637002)
一种基于双边滤波的HDR算法
何 春,宋国琴
(西华师范大学 教育信息技术中心,四川 南充 637002)
为了能让高动态范围图像显示在低动态范围输出设备上,需对高动态范围图像进行压缩处理.算法根据双边滤波的原理对输入的图像信息进行分解,得到保留图像亮度信息的基础层和表示图像反射率信息的细节层,然后降低基础层的对比度,保留细节层的信息,最后再将两层的数据进行合并,输出最终的图像.实验表明,算法较好地还原了图像细节,有效地调节了图像亮度,使之更好地适应了人眼视觉系统的感知范围.
HDR图像;双边滤波;色调映射;图像压缩
高动态范围成像(High Dynamic Range Imaging,HDRI)是一种能够比普通数字成像技术曝光更大动态范围的技术,该技术能够记录更加真实的场景,通过该技术得到的图像称为高动态范围(High Dynamic Range)图像[1].HDR图像可以通过光谱记录仪器或多幅同一场景不同曝光时间的图像序列合成而获得.相对于HDR图像的动态范围,当前的输出设备(显示器、打印机等)的动态范围极其有限,所以要将HDR图像在输出设备上显示出来,必须将其高动态范围转换至输出设备能够接受的低动态范围内,该转换过程称为色阶重建(Tone Reproduction)或色调映射(Tone Mapping).
目前色调映射算法(Tone Mapping Operator,TMO)分为两类:全局映射算法和局部映射算法[2].全局映射算法通过像素间点到点的对应函数对HDR图像中的每个像素进行映射,其优点在于计算速度快,能够保持良好的整体明暗的视觉效果,但是全局映射会造成细节信息的严重丢失.局部映射算法对图像的不同区域使用不同的比例因子进行映射,映射中对较小的对比度进行增强,对较大的对比度进行压缩,从而保留了图像分细节信息.算法的优点在于映射后可以产生细节丰富的图像,但该类算法需要对图像进行分层处理,处理不好会在分层合成后的图像边缘处出现光晕现象或局部削弱.
本文采用Durand等提出基于双边滤波技术的HDR图像色调映射算法[3],在计算HDR图像的像素亮度值后,利用双边滤波将图像分为基础层和细节层,然后降低基础层的对比度,保留细节层的信息,最后再将两层的数据进行合并,输出最终的图像.
1.1 双边滤波技术
双边滤波器是Tomasi和Manduchi于1998年提出的图像滤波算法[4],该算法结合邻域空间信息和像素值相似性对图像进行滤波处理,在平滑滤波的同时能够保留图像的边缘特征.
双边滤波器由2个高斯核函数组成:邻域滤波和值域滤波.邻域滤波可以对邻域空间上相近的像素点进行加权平均,加权的系数随着像素点距离的增大而减小.值域滤波是对像素值相近的点进行加权平均,加权系数随着像素点值差的增大而减小.
双边滤波定义如下:
(1)
k(b)=∑p∈Ωf(p-b)g(Ip-Ib)
(2)
其中,I为输入图像,b为输出图像,Ω为邻域窗口,f和g分别为2个高斯核函数,f为邻域范围内滤波,g为像素值领域内滤波,Ip和Ib分别为p点和b点的像素值.
高斯核函数在图像处理中定义如下:
(3)
(4)
其中d(p,d)为2个像素点的欧几里得距离,δ(Ip,Ib)为2个像素点灰度差值,σd为空间邻域标准差,σr为像素亮度标准差.
由以上定义可知,双边滤波的权系数由空间邻域标准差σd和像素亮度标准差σr组成,这两个参数值的选择非常重要,直接影响到双边滤波的输出效果.多次实验表明,σd取值0.02×max(width, height)、σr取值0.4时较为合适.
1.2 算法设计
算法首先将HDR图像分成两层:基础层和细节层.基础层保留图像亮度信息,细节层表示图像反射率信息[5].根据Durand等人提出的快速双向滤波器原理对输入的图像信息进行分解如下:
I(x, y)=log(max(Lw(x, y),0.0001)
(5)
Ibase(x,y)=bil_filter(I(x, y))
(6)
Idetail(x,y)=I(x, y)-Ibase(x, y)
(7)
其中,Lw(x, y)为输入HDR图像的亮度值,I(x, y)是对输入图像取对数(以10为底),Ibase(x,y)为双向滤波器的输出结果,该结果即为图像基本层,Idetail(x,y)作为图像细节层被定义为原图像与基本层之差.
根据以上分解,算法的完整过程如下:
(1)将原始图像每个像素的R、G、B值进行分解,并按照以下公式求出原始图像的光照强度(即亮度信息),该结果保存在基础层里[6]:Lw(x, y)= (R*20+G*40+B) /61.
(2)按以下方法求出R、G、B分量各自占光照强度的比例,得到相应的比例值r、g、b.r=R/Lw (x, y), g=G/Lw (x, y), b=B/Lw (x, y).
(3)对原始图像的亮度信息进行双边滤波处理,处理后得到基础层的图像信息:Ibase(x,y)=bil_filter(I(x, y)).
(4)计算原图像与基本层之差,即图像细节层:Idetail(x,y)=I(x, y)-Ibase(x, y).
(5)通过以下计算公式得到图像经过处理后的细节信息[7]:Iresult(x, y)=Ibase(x, y)*compressionfactor+
Idetail(x,y)-log_absolute_scale.
(6)分别求出图像经过处理后得到的R、G、B分量值:Rresult= r*10^Iresult(x, y)),Gresult=g*10^Iresult(x, y)),Bresult= b*10^Iresult(x, y)).
其中,compressionfactor=targetContrast/(max
(Ibase(x,y))-min(Ibase(x,y))),targetContrast取值log(5)较为理想;log_absolute_scale=max(Ibase(x, y))*compressionfactor.
1.3 算法代码
根据上述算法设计,下面提供该算法的部分C语言代码:
public Bitmap LoadHdrFormFreeImage(string FileName)
{ Bitmap Bmp = null;
FREE_IMAGE_FORMAT fif = FREE_IMAGE_FORMAT.FIF_UNKNOWN;
if (FreeImage.IsAvailable() == true)
{ fif = FreeImage.GetFileType(FileName, 0);
if (fif != FREE_IMAGE_FORMAT.FIF_HDR)
{
MessageBox.Show(“不是HDR格式的图像.”);
return null;
}
fif = FreeImage.GetFIFFromFilename(FileName);
FIBITMAP Dib = FreeImage.Load(fif, FileName, FREE_IMAGE_LOAD_FLAGS.DEFAULT);
uintBpp = FreeImage.GetBPP(Dib);
if (Bpp != 96)
{
MessageBox.Show(“无法支持的HDR格式.”);
FreeImage.Unload(Dib);
return null;
}
uint Width = FreeImage.GetWidth(Dib); // 图像宽度
uint Height = FreeImage.GetHeight(Dib); // 图像高度
uint Stride = FreeImage.GetPitch(Dib);
IntPtr Bits = FreeImage.GetBits(Dib);
float* Data = (float*)Bits;
int Speed, Index;
byte* Pixel;
float Value;
if (RawData != null) Marshal.FreeHGlobal((IntPtr)RawData);
RawData = (float*)Marshal.AllocHGlobal((int)Width * (int)Height * 3 * sizeof(float));
CopyMemory(RawData, Data, (int)Width * (int)Height * 3 * sizeof(float));
Bmp = new Bitmap((int)Width, (int)Height, PixelFormat.Format24bppRgb);
BitmapDataBmpData = Bmp.LockBits(new Rectangle(0, 0, Bmp.Width, Bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
Pixel = (byte*)BmpData.Scan0;
for (int Y = 0; Y < Height; Y++)
{
Speed = Y * BmpData.Stride;
Index = Y * (int)Width * 3;
for (int X = 0; X < Width; X++)
{
Value = (Data[Index + 2] * 255);
if (Value > 255)
Value = 255;
else if (Value < 0)
Value = 0;
Pixel[Speed] = (byte)Value;
Value = (Data[Index + 1] * 255);
if (Value > 255)
Value = 255;
else if (Value < 0)
Value = 0;
Pixel[Speed + 1] = (byte)Value;
Value = (Data[Index + 0] * 255);
if (Value > 255) then Value = 255;
else if (Value < 0)then Value = 0;
Pixel[Speed + 2] = (byte)Value;
Index += 3;
Speed += 3;
}
}
FreeImage.Unload(Dib);
Bmp.UnlockBits(BmpData);
Bmp.RotateFlip(RotateFlipType.RotateNoneFlipY);
return Bmp;
}
else
return null;
}
为了验证本算法的有效性以及细节保持特性,实验对多张图像进行了处理.如图1、图2所示.
图1 实验效果1
虽然目前对HDR图像的色调映射算法及结果的评价方法还没有客观标准体系,但从算法处理的效果图中我们可以看到本算法对于图像的处理能够
图2 实验效果2
得到基本满意的结果.图1、图2的黑暗部分都得到了有效的亮度调整以及细节还原,通过色阶的对比也可以发现处理后效果图的色阶相比原图在暗调、中间调、亮调区域分布更均匀,图像不再有过曝或曝光不足的现象.但仍然可以发现,处理后的图像整体缺乏一定的层次感,局部细节信息仍有不同程度的丢失,这也是本算法需要进一步改进的地方.
本文算法根据双边滤波的原理对输入的图像信息进行分解,得到保留图像亮度信息的基础层和表示图像反射率信息的细节层,然后降低基础层的对比度,保留细节层的信息,最后再将两层的数据进行合并,输出最终的图像.通过实验表明,算法对图像的局部和整体实现了较好的结合,对于暗部图像及亮部图像的细节也实现了很好的还原,图像的亮度得到了有效的调节,图像的动态范围大大提高,使之更好地适应了人眼视觉系统的感知范围.算法需要改进的是,进一步降低计算复杂度,图像处理后的效果也需进一步完善.
[1]李晓光,沈兰荪,林健文.一种高动态范围图像可视化算法[J].计算机应用研究,2007(11).
[2]Qiu G,Duan J.An optimal tone reproduction curve operator for the display high dynamic range images. Proceedings-IEEE International Symposium on Circuits and Systems,2005,ISCAS2005.
[3]Durand F, Dorsey J.Fast Bilateral Filtering for the Display of High-Dynamic-Range Images[J].ACM Transaction on Graphics,2002,21(3):257-266.
[4]Yue Dong,Xin Tong,Fabio Pellacini,BainingGuo. Printing spatially-varying reflectance for reproducing HDR images [J]. ACM Transactions on Graphics (TOG),2012 (4).
[5]朱明,刘真,李晓春.HDR图像阶调复制的非线性蒙版改进算法[J].武汉大学学报(信息科学版),2014(08).
[6]刘冬梅,赵宇明.高动态范围图像梯度压缩算法[J].计算机工程,2009(20).
[7]舒妮,陈孝威.HDRI合成中新的相机响应曲线算法[J].计算机工程与设计,2012(03).
(责任编辑:王前)
2016-06-10
何春,女,四川南充人,讲师.
TP391
A
1008-7974(2016)05-0051-03
10.13877/j.cnki.cn22-1284.2016.10.017