• Gamma校正及其OpenCV实现


    參考:[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. 人眼对外界光源的感光值与输入光强不是呈线性关系的,而是呈指数型关系的。在低照度下,人眼更easy分辨出亮度的变化,随着照度的添加,人眼不易分辨出亮度的变化。而摄像机感光与输入光强呈线性关系。如图2所看到的:

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

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

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

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

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

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

    三、利用OpenCV实现的Gamma校正

    void MyGammaCorrection(Mat& src, Mat& dst, float fGamma)
    {
    	CV_Assert(src.data);
    
    	// accept only char type matrices
    	CV_Assert(src.depth() != sizeof(uchar));
    
    	// build look up table
    	unsigned char lut[256];
    	for( int i = 0; i < 256; i++ )
    	{
    		lut[i] = saturate_cast<uchar>(pow((float)(i/255.0), fGamma) * 255.0f);
    	}
    
    	dst = src.clone();
    	const int channels = dst.channels();
    	switch(channels)
    	{
    		case 1:
    			{
    
    				MatIterator_<uchar> it, end;
    				for( it = dst.begin<uchar>(), end = dst.end<uchar>(); it != end; it++ )
    					//*it = pow((float)(((*it))/255.0), fGamma) * 255.0;
    					*it = lut[(*it)];
    
    				break;
    			}
    		case 3: 
    			{
    
    				MatIterator_<Vec3b> it, end;
    				for( it = dst.begin<Vec3b>(), end = dst.end<Vec3b>(); it != end; it++ )
    				{
    					//(*it)[0] = pow((float)(((*it)[0])/255.0), fGamma) * 255.0;
    					//(*it)[1] = pow((float)(((*it)[1])/255.0), fGamma) * 255.0;
    					//(*it)[2] = pow((float)(((*it)[2])/255.0), fGamma) * 255.0;
    					(*it)[0] = lut[((*it)[0])];
    					(*it)[1] = lut[((*it)[1])];
    					(*it)[2] = lut[((*it)[2])];
    				}
    
    				break;
    
    			}
    	}
    }
    
    
    
    
    
    
    
    
    
    
    
  • 相关阅读:
    修改root密码
    环境的搭建(四)--------samba服务
    16.统一异常处理(上)编写自定义处理函数
    15.集成限流功能到我们的服务中(花操作必看)
    14.go内置的rate包学习2(有花操作,必看)
    13.go内置的rate包学习1
    12.使用负载均衡的方式调用服务(随机方式)
    11.使用负载均衡的方式调用服务(轮询方式)
    10.根据命令行参数注册多个服务
    9.consul获取服务实例,调用测试
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/3877155.html
Copyright © 2020-2023  润新知