幂律变换也属于非线性变换,幂律变换也称伽马变换或指数变换,是另一种常用的灰度非线性变换,主要用于图像的校正,对漂白的图片或者过黑的图片进行修正,也就是对灰度过高或者灰度过低的图片进行修正,增强对比度。
幂律变换公式:
其中c和γ为正常数,当γ >1时,低灰度区间压缩,高灰度区间拉伸;当γ <1时,低灰度区间拉伸,高灰度区间压缩,当γ =1时,恒等变换。
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
// Gamma变换函数实现
Mat gammaTransform(Mat& src, float kFactor)
{
// 建立查表文件LUT
unsigned char LUT[256];
for( int i = 0; i < 256; i++ )
{
// Gamma变换表达式
LUT[i] = saturate_cast<uchar>(pow((float)(i / 255.0 ), kFactor ) * 255.0f);
}
Mat resultImage = src.clone();
// 输入通道为单通道时 直接进行变换
if(src.channels() == 1)
{
MatIterator_<uchar> iterator = resultImage.begin<uchar>();
MatIterator_<uchar> iteratorEnd = resultImage.end<uchar>();
for( ; iterator != iteratorEnd; iterator++)
{
*iterator = LUT[(*iterator)];
}
}
else
{
// 输入通道为三通道时 需对每个通道分别进行变换
MatIterator_<Vec3b> iterator = resultImage.begin<Vec3b>();
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(int argc, char** argv)
{
Mat src= imread("E:/work/images/2010_005754.jpg");
if( !src.data ) return -1;
// 初始化两种不同参数 对比分析效果
float kFactor1 = 0.3;
float kFactor2 = 3.0;
Mat result1 = gammaTransform(src, kFactor1);
Mat result2 = gammaTransform(src, kFactor2);
imshow("src", src);
imshow("result1", result1);
imshow("result2", result2);
waitKey();
return 0;
}
输入输出结果: