伽玛校正也称为伽玛变换,或幂变换。 Gamma校正主要用于图像校正,校正漂白或过黑的图像。 Gamma校正也常用于显示屏的校正。 这是一个非常常用的转换。 使用的公式如下:
伽玛校正使用的公式
上式中,C为常数,s为输入像素值,t为变换后的像素值,γ为幂变换的指标值。 如果将数字图像的值归一化为[0,1],则输出值也在[0,1]范围内。 对于不同的gamma值,对应的变换曲线如下图所示:
Gamma变换响应曲线(C=1)
从上图可以看出,当γ1时,高亮度部分被拉伸,低亮度部分被压缩。 因此,当需要显示图像暗部的细节时,可以使用伽玛值小于1的伽玛变换; 如果需要图像亮部的细节,可以使用gamma值大于1的gamma变换。
gamma校正的意义:
1) 方便人眼对图像的识别
人眼对外界光源的敏感度值与输入光强不是线性关系,而是指数关系 . 在低照度下,人眼更容易分辨亮度的变化,但随着照度的增加,人眼就很难分辨亮度的变化。 相机灵敏度与输入光强度成线性关系。 如下图所示:
人眼和摄像头的感光度与实际输入光强的关系
2)更有效的保存图像亮度信息
未经授权的Gamma校正和伽马校正后保存的图像信息如下图所示:
未经伽马校正和伽马校正后保存的图像信息
可以 从上图可以观察到,在不进行gamma校正的情况下,当灰度值较低时,大范围的灰度值都保存为同一个值,导致信息丢失; 同时,当灰度值高的时候,将很多接近的灰度值保存为不同的值,造成空间的浪费。 经过伽马校正后,提高了存储的有效性和效率。
gamma校正函数可以用OpenCV代码描述如下。 这里采用搜索的方式计算变换后的值,可以大大减少计算量:
自定义伽玛校正函数
void MyGammaCorrection(const Mat& src, Mat& dst, float fGamma)
{
CV_Assert(src.data);
//只处理位深为8位的图像
CV_Assert(src.depth() != sizeof(uchar));
//创建查找表
无符号字符 [256];
对于 (int i = 0; i < 256; i ){
lut[i] = saturate_cast(pow((float)(i / 255.0),
f伽玛) * 255.0f);
}
dst = 源。 克隆();
const int 通道 = dst。 频道();
切换(频道){
case 1: //单通道灰度图
MatIterator_ 它; //使用迭代器访问像素值
for (it = dst.begin(); it != dst.end(); it )
*it = lut[(*it)];
休息;
case 3: //3通道彩色图像
MatIterator_ 它; //使用迭代器访问像素值
对于(它= dst.begin();它!=dst.end();它){
(*it)[0] = lut[((*it)[0])];
(*it)[1] = lut[((*it)[1])];
(*it)[2] = lut[((*it)[2])];
}
休息;
}
}