Gamma校正及其OpenCV实现

转载:http://blog.csdn.net/lichengyu/article/details/8457425

参考:[1]http://www.cambridgeincolour.com/tutorials/gamma-correction.htm

[2]http://en.wikipedia.org/wiki/Gamma_correction

 

一、什么是Gamma校正?

Gamma校正是对输入图像灰度值进行的非线性操作,使输出图像灰度值与输入图像灰度值呈指数关系:

[2]

这个指数即为Gamma.

经过Gamma校正后的输入和输出图像灰度值关系如图1所示:横坐标是输入灰度值,纵坐标是输出灰度值,蓝色曲线是gamma值小于1时的输入输出关系,红色曲线是gamma值大于1时的输入输出关系。可以观察到,当gamma值小于1时(蓝色曲线),图像的整体亮度值得到提升,同时低灰度处的对比度得到增加,更利于分辩低灰度值时的图像细节。

                                                                                图1 Gamma校正.

 

二、为什么进行Gamma校正?

1. 人眼对外界光源的感光值与输入光强不是呈线性关系的,而是呈指数型关系的。在低照度下,人眼更容易分辨出亮度的变化,随着照度的增加,人眼不易分辨出亮度的变化。而摄像机感光与输入光强呈线性关系。如图2所示:

图2 人眼和摄像机的感光与实际输入光强的关系[1]。

为方便人眼辨识图像,需要将摄像机采集的图像进行gamma校正。

 

2. 为能更有效的保存图像亮度信息,需进行Gamma校正。

未经gamma校正和经过gamma校正保存图像信息如图3所示:

图3 未经gamma校正和经过gamma校正保存图像信息.

可以观察到,未经gamma校正的情况下,低灰度时,有较大范围的灰度值被保存成同一个值,造成信息丢失;同时高灰度值时,很多比较接近的灰度值却被保存成不同的值,造成空间浪费。经过gamma校正后,改善了存储的有效性和效率。

 

三、利用OpenCV实现的Gamma校正

[cpp]  view plain copy
  1. Mat& MyGammaCorrection(Mat& I, float fGamma)  
  2. {  
  3.     CV_Assert(I.data);  
  4.   
  5.     // accept only char type matrices  
  6.     CV_Assert(I.depth() != sizeof(uchar));  
  7.   
  8.     // build look up table  
  9.     unsigned char lut[256];  
  10.     forint i = 0; i < 256; i++ )  
  11.     {  
  12.         lut[i] = pow((float)(i/255.0), fGamma) * 255.0;  
  13.     }  
  14.   
  15.   
  16.     const int channels = I.channels();  
  17.     switch(channels)  
  18.     {  
  19.         case 1:  
  20.             {  
  21.   
  22.                 MatIterator_<uchar> it, end;  
  23.                 for( it = I.begin<uchar>(), end = I.end<uchar>(); it != end; it++ )  
  24.                     //*it = pow((float)(((*it))/255.0), fGamma) * 255.0;  
  25.                     *it = lut[(*it)];  
  26.   
  27.                 break;  
  28.             }  
  29.         case 3:   
  30.             {  
  31.   
  32.                 MatIterator_<Vec3b> it, end;  
  33.                 for( it = I.begin<Vec3b>(), end = I.end<Vec3b>(); it != end; it++ )  
  34.                 {  
  35.                     //(*it)[0] = pow((float)(((*it)[0])/255.0), fGamma) * 255.0;  
  36.                     //(*it)[1] = pow((float)(((*it)[1])/255.0), fGamma) * 255.0;  
  37.                     //(*it)[2] = pow((float)(((*it)[2])/255.0), fGamma) * 255.0;  
  38.                     (*it)[0] = lut[((*it)[0])];  
  39.                     (*it)[1] = lut[((*it)[1])];  
  40.                     (*it)[2] = lut[((*it)[2])];  
  41.                 }  
  42.   
  43.                 break;  
  44.   
  45.             }  
  46.     }  
  47.   
  48.     return I;  
  49.       
  50. }  


四、实现结果

第一幅图是原图,第二幅图是用gamma=0.45做的校正,第三幅图是用gamma=2.2进行校正。可以观察到,第二幅图的整体亮度提高,同时低灰度时的对比度提高。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值