参考文献:数字图像处理(第三版) 美Rafael,C.,Gonzalez(拉斐尔,C.,冈萨雷斯) 著
什么是gamma变换呢?gamma变换其实就是一条数学公式
属于灰度处理的一种,r是输入的灰度值,c一般设置为1,幂r就是gamma的系数对应变换值如下:它更具gamma值的不同,来实现图像的对比度增强。
这里对于C++实现而言有意思的一点就是图像要归一化。归一化什么意思呢?就是每个像素值除以255,它的结果就一定是0到1之间,归一化的好处是,这点我也没明白,但0到1之间,可能数字那些没那么大吧。注意这里你需要进行强制类型转换。而且你要学会查找表的思想。查找表就是一个空间换时间的操作。如果gamma值定了,那么对于每个灰度值0到255它的对应的变换值就是确定的。那么你就不用每个像素都算一次,因为求幂操作非常的消耗运算时间,你只需要开辟一段内存空间,提前存好结果,然后遍历每一个像素查找值就行。
我使用了两个函数进行实现,对应代码如下:
void bmp::build_table(byte *lut,double gamma)
{
double temp;
for(int i=0;i<=255;++i)
{
temp=double(i)/255;
temp=pow(temp,gamma);
lut[i]=unsigned char(temp*255);
//printf("%d ", unsigned char(lut[i]));
}
}
void bmp::produce_gamma_bmp_file(double gamma)
{
string gamma_file_name;
for(int i=0;i<file_name.length()-4;++i)
{
gamma_file_name+=file_name[i];
}
gamma_file_name+="_gamma.bmp";
byte *lut=new byte[256];
build_table(lut,gamma);
for(int i=0;i<image_heigth;++i)
for (int j = 0; j < image_width; ++j)
for(int k=0;k<byte_count;++k)
{
//printf("%d_", pixel[i][j][k]);
pixel[i][j][k]=lut[pixel[i][j][k]];
//printf("%d ", pixel[i][j][k]);
}
produce_bmp_file(pixel,image_width,image_heigth,byte_count,gamma_file_name);
delete[]lut;
}
展示:
原图像
当我把gamma值设置为0.4时
你会发现黑色的值变白了,这说明什么呢,说明黑色的值变大了,即小的值变大了,小的值被放大了。
再来看一个实用的例子:
原图像
设置为0.4后,产生的图像
你发现图像暗的地方明显被放大了。证明对比度增强了。