Gamma校正

Gamma校正

gamma校正(幂律变换)是一种重要的非线性变换,其是对输入图像灰度值进行指数变换,进而校正亮度偏差,通常应用于扩展暗调的细节。一般情况下,当Gamma校正的值大于1时,图像的高光部分被压缩而暗调部分被扩展;当Gamma校正的值小于1时,图像的高光部分被扩展而暗调部分被压缩,在最简单的情况下,gamma校正通过以下的幂律表达式来定义:
这里写图片描述
函数图像如下:
Gamma校正_第1张图片
其中c是常数,输入及输出均为非负值,当r=1时,输入与输出的取值范围为0到1,直线变换;当r<1时,低灰度值区域的动态范围扩大,进而图像对比度增强,高灰度值区域动态范围缩小,图像对比度降低,图像整体灰度值变大;当r>1时,低灰度值区域的动态范围缩小,进而图像对比度降低,高灰度值区域动态范围扩大,图像对比度增加,图像整体灰度值变小。Gamma校正主要运用在图像增强,目标检测及图像分析等领域。

示例代码如下:

#include   
#include         
#include  
#include  
using namespace std;
using namespace cv;
// Gamma变换函数实现
cv::Mat gammaTransform(cv::Mat& srcImage, float kFactor)
{
    // 建立查表文件LUT
    unsigned char LUT[256];
    for( int i = 0; i < 256; i++ )
    {
        // Gamma变换表达式
        LUT[i] = saturate_cast(pow( ( float)( 
               i / 255.0 ), kFactor ) * 255.0f );
    }
    cv::Mat resultImage = srcImage.clone();
    // 输入通道为单通道时 直接进行变换
    if(srcImage.channels() == 1)
    {
        cv::MatIterator_ iterator = 
                 resultImage.begin();
        cv::MatIterator_ iteratorEnd = 
                 resultImage.end();
        for( ; iterator != iteratorEnd; iterator ++ )
            *iterator = LUT[(*iterator)];
    }else
    {
        // 输入通道为三通道时 需对每个通道分别进行变换
        cv::MatIterator_::Vec3b> iterator = 
               resultImage.begin<Vec3b>();
        cv::MatIterator_::Vec3b> iteratorEnd = 
               resultImage.end<Vec3b>();
       //  通过查找表进行转换
        for( ; iterator != iteratorEnd; iterator++ )
        {
            (*iterator)[0] = LUT[((*iterator)[0])];
            (*iterator)[1] = LUT[((*iterator)[1])];
            (*iterator)[2] = LUT[((*iterator)[2])];
        }
    }
    return resultImage;
}
int main()
{
     cv::Mat srcImage =  imread("..\\images\\lakeWater.jpg");
     if( !srcImage.data ) 
          return -1;
     // 初始化两种不同参数 对比分析效果
     float kFactor1 =  0.3;
     float kFactor2 =  3.0;
     cv::Mat result1 = gammaTransform(srcImage, kFactor1);
     cv::Mat result2 = gammaTransform(srcImage, kFactor2);
     cv::imshow("srcImage", srcImage);
     cv::imshow("result1", result1);
     cv::imshow("result2", result2);
     cv::waitKey(0);
     return 0;
}

结果如下:
原图:

r=0.3:

r=3.0:

你可能感兴趣的:(open,cv,c++)