在OpenCV环境下对图像做Gamma校正

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

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

​​
为什么要进行Gamma校正?
人眼对外界光源的感光值与输入光强不是呈线性关系的,而是呈指数型关系的。在低照度下,人眼更容易分辨出亮度的变化,随着照度的增加,人眼不易分辨出亮度的变化。而摄像机感光与输入光强呈线性关系。OpenCV环境下对图像进行Gamma校正的源代码如下:

图像处理开发资料、图像处理开发需求、图像处理接私活挣零花钱,可以搜索公众号"qxsf321",并关注!
源码中用到的图像下载链接:http://pan.baidu.com/s/1miIGyqW 密码:bz9r

//opencv版本:OpenCV3.0
//VS版本:VS2013
//Author:qxsf321.net
 
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>    
#include <opencv2/imgproc/types_c.h>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/highgui/highgui_c.h>
 
#include <iostream>
 
using namespace cv;
using namespace std;
 
void MyGammaCorrection(Mat& src, Mat& dst, float fGamma)  
{  
 
    // 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;  
 
            }  
    }  
}  
 
int main()
{
        Mat image = imread("gamma_pending.jpg");
        if (image.empty())
        {
                cout << "Error: Could not load image" << endl;
                return 0;
        }
 
        Mat dst;
        float fGamma=1/2.2;
        MyGammaCorrection(image, dst, fGamma);
 
        imshow("Source Image", image);
        imshow("Dst", dst);
 
        waitKey();
 
        return 0;
}
--------------------- 
作者:清溪算法 
来源:CSDN 
原文:https://blog.csdn.net/lehuoziyuan/article/details/84067207 
版权声明:本文为博主原创文章,转载请附上博文链接!

运行结果截图如下:


从运行结果中我们可以看出:
最左边的图为原图,中图为gamma = 1/2.2时的校正结果,原图中左半侧的灰度值较高,右半侧的灰度值较低,经过gamma=1/2.2校正后(中图),左侧的对比度降低(见胡须),右侧在对比度提高(明显可以看清面容),同时图像在的整体灰度值提高。
最右边的图为gamma = 2.2在校正结果,校正后,左侧的对比度提高(见胡须),右侧在对比度降低(面容更不清楚了),同时图像在的整体灰度值降低。

值得一提的是:人眼是按照gamma<1的曲线对自己看到的图像进行校正的。
--------------------- 
作者:清溪算法 
来源:CSDN 
原文:https://blog.csdn.net/lehuoziyuan/article/details/84067207 
版权声明:本文为博主原创文章,转载请附上博文链接!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值