自动对比度灰阶调整
1.自动对比度调整
自动对比度调整,主要作用是把一定范围内的像素值,映射到整个图像灰度范围内。比如对于每个像素都是8Bit的图像而言,整个灰度范围即为[0,255]。实现方式是把一定范围内的像素灰度最小值映射到整个图像所能表示灰度值的最小值,把范围内的最大值灰度映射到整幅图像所能表示灰度值的最大值。如下如所示:
假设某一幅图像灰度值范围为[Amin,Amax],图像所能表示的最大灰度范围为[aMin,Amax]。为了把一定灰度范围的图像映射到最大灰度范围,首先必须把Amin映射到aMin,然后在乘以系数(aMax-aMin)/(Amax-Amin),最后通过增加aMin,使得一定范围灰度值映射到最大目标灰度范围。因此,自动对比度调整可以用公式表示为:
Amin不等于Amax。对于每个像素为8Bit的图像而言,aMin=0,aMax=255,因此,上式可以改写为:
自动色阶调整相关资料暂时还未查阅,待后续添加。
2.代码实现
主要参考调整图像-自动对比度、自动色阶算法中所描述的算法改写而成。
#define THRESHOLD 0.03
int Auto_Contrast_Gradation(IMAGE_TYPE *bmp_img,double dlowcut ,double dhighcut )
{
DWORD width,height,dst_index,index;
WORD biBitCount;
T_U8 *bmp_data,R,G,B,*Result_img,BytePerPixel = 3;
T_U32 line_byte,TmpR,TmpG,TmpB,Sum,PixCount;
T_U16 i,j,MinBlue,MaxBlue,MinRed,MaxRed,MinGreen,MaxGreen,Max,Min,Y;
int newX,newY;
double Tmp;
double HistRed[256]={0};
double HistGreen[256]={0};
double HistBlue[256]={0};
int bluemap[256]={0};
int redmap[256]={0};
int greenmap[256]={0};
int Map[256] = {0};
BITMAPFILEHEADER bf;
BITMAPINFOHEADER bi;
FILE *Auto_Contrast_Gradation_fp = fopen("Auto_Contrast_Gradation.bmp","wb");
if(NULL == Auto_Contrast_Gradation_fp)
{
printf("Can't open Auto_Contrast_Gradation.bmp\n");
return -1;
}
memset(&bf, 0, sizeof(bf));
memset(&bi, 0, sizeof(bi));
memcpy(&bf,bmp_img,14);
memcpy(&bi,&bmp_img[14],40);
height = bi.biHeight;
width = bi.biWidth;
biBitCount = bi.biBitCount;//每一个像素由24 bits表示,即RGB分量每一个分量用8 bits表示
line_byte =(width*3+3) & ~0x3;
fwrite(&bf,sizeof(BITMAPFILEHEADER),1,Auto_Contrast_Gradation_fp);
fwrite(&bi,sizeof(BITMAPINFOHEADER),1,Auto_Contrast_Gradation_fp);
bmp_data = bmp_img + BMPHEADSIZE;
for(i =0;i < height;i++)
{
dst_index = i*line_byte;
for(j = 0;j < width;j++)
{
R = bmp_data[dst_index+2];
G = bmp_data[dst_index+1];
B = bmp_data[dst_index];
HistRed[R]++;
HistGreen[G]++;
HistBlue[B]++;
dst_index += BytePerPixel;
}
}
PixCount = height*width;
//For Blue Channel
Sum = 0;
for(Y = 0; Y < 256;Y++)
{
Sum += HistBlue[Y];
if(Sum >= PixCount*dlowcut*THRESHOLD)
{
MinBlue = Y;
break;
}
}
Sum = 0;
for(Y = 255;Y >=0;Y--)
{
Sum += HistBlue[Y];
if(Sum >= PixCount*dhighcut*THRESHOLD)
{
MaxBlue = Y;
break;
}
}
//For Green Channel
Sum = 0;
for(Y = 0; Y < 256;Y++)
{
Sum += HistGreen[Y];
if(Sum >= PixCount*dlowcut*THRESHOLD)
{
MinGreen = Y;
break;
}
}
Sum = 0;
for(Y = 255;Y >=0;Y--)
{
Sum += HistGreen[Y];
if(Sum >= PixCount*dhighcut*THRESHOLD)
{
MaxGreen = Y;
break;
}
}
//For Red Channel
Sum = 0;
for(Y = 0; Y < 256;Y++)
{
Sum += HistRed[Y];
if(Sum >= PixCount*dlowcut*THRESHOLD)
{
MinRed = Y;
break;
}
}
Sum = 0;
for(Y = 255;Y >=0;Y--)
{
Sum += HistRed[Y];
if(Sum >= PixCount*dhighcut*THRESHOLD)
{
MaxRed = Y;
break;
}
}
for(Y = 0;Y < 256;Y++)
{
if(Y <= MinBlue)
bluemap[Y] = 0;
else if(Y >=MaxBlue)
bluemap[Y] = 255;
else
{
Tmp = (double)(Y-MinBlue)/(MaxBlue-MinBlue);
bluemap[Y] = (int)(Tmp*255);
}
}
for(Y = 0;Y < 256;Y++)
{
if(Y <= MinGreen)
greenmap[Y] = 0;
else if(Y >=MaxGreen)
greenmap[Y] = 255;
else
{
Tmp = (double)(Y-MinGreen)/(MaxGreen-MinGreen);
greenmap[Y] = (int)(Tmp*255);
}
}
for(Y = 0;Y < 256;Y++)
{
if(Y <= MinRed)
redmap[Y] = 0;
else if(Y >=MaxRed)
redmap[Y] = 255;
else
{
Tmp = (double)(Y-MinRed)/(MaxRed-MinRed);
redmap[Y] = (int)(Tmp*255);
}
}
//Auto Gradation
for(i =0;i < height;i++)
{
dst_index = i*line_byte;
for(j = 0;j < width;j++)
{
bmp_data[dst_index] = bluemap[bmp_data[dst_index]];
bmp_data[dst_index+1] = greenmap[bmp_data[dst_index+1]];
bmp_data[dst_index+2] = redmap[bmp_data[dst_index+2]];
dst_index += BytePerPixel;
}
}
//Auto Contrast
if(MinBlue < MinGreen)
Min = MinBlue;
else
Min = MinGreen;
if(Min > MinRed)
Min = MinRed;
if(MaxBlue > MaxGreen)
Max = MaxBlue;
else
Max = MaxGreen;
if(Max < MaxRed)
Max = MaxRed;
for(Y = 0;Y < 256;Y++)
{
if(Y <= Min)
Map[Y] = 0;
else if(Y >Max)
Map[Y] = 255;
else
{
Tmp = (double)(Y-Min)/(Max-Min);
Map[Y] = (int)(Tmp*255);
}
}
for(i =0;i < height;i++)
{
dst_index = i*line_byte;
for(j = 0;j < width;j++)
{
bmp_data[dst_index] = Map[bmp_data[dst_index]];
bmp_data[dst_index+1] = Map[bmp_data[dst_index+1]];
bmp_data[dst_index+2] = Map[bmp_data[dst_index+2]];
dst_index += BytePerPixel;
}
}
fwrite(bmp_data, line_byte*height*sizeof(T_U8), 1, Auto_Contrast_Gradation_fp);
fclose(Auto_Contrast_Gradation_fp);
return 0;
}
3.图像效果
参考资料:
1..http://www.cnblogs.com/Imageshop/archive/2011/11/13/2247614.html