一、色彩均衡算法
二、基于参考白的算法
一、色彩均衡算法
1.求出3个通道各个平均值,以及灰度的平均值grayAvg,修改每个原像素值
2.求出像素值最大值maxNum,如果factor=maxNum/255,factor>1,则每个通道像素都除以factor以修改像素值
void Illumination_compensation(V_Image** img)
{
int col=0,index=0;
int rows=(*img)->mRow,cols=(*img)->mCol,cns=(*img)->mChannels;
unsigned char *bArr=(unsigned char *) calloc(rows*cols,sizeof(unsigned char));
unsigned char *gArr=(unsigned char *) calloc(rows*cols,sizeof(unsigned char));
unsigned char *rArr=(unsigned char *) calloc(rows*cols,sizeof(unsigned char));
float bTotal=0,gTotal=0,rTotal=0;
float bAvg=0.0,gAvg=0.0,rAvg=0.0;
float bRatio=0,gRatio=0,rRatio=0,grayAvg=0.0;
//分成三个数组,一个通道一个,并求和
for(col=0; col<rows*cols*cns; col++)
{
bArr[index]=(*img)->mData[col];
gArr[index]=(*img)->mData[++col];
rArr[index]=(*img)->mData[++col];
bTotal+=bArr[index];
gTotal+=gArr[index];
rTotal+=rArr[index];
index++;
}
bAvg=bTotal/(rows*cols);
gAvg=gTotal/(rows*cols);
rAvg=rTotal/(rows*cols);
grayAvg=(bAvg+gAvg+rAvg)/3;
bRatio=grayAvg/bAvg;
gRatio=grayAvg/gAvg;
rRatio=grayAvg/rAvg;
int maxNum=0;
for(index=0; index<rows*cols; index++)
{
bArr[index]=floor(bArr[index]*bRatio);
gArr[index]=floor(gArr[index]*gRatio);
rArr[index]=floor(rArr[index]*rRatio);
if( bArr[index]>maxNum)
maxNum=bArr[index];
if( gArr[index]>maxNum)
maxNum=gArr[index];
if( rArr[index]>maxNum)
maxNum=rArr[index];
}
int factor=maxNum/255,blue,green,red;
index=0;
for(col=0; col<cns*rows*cols; col++)
{
if(factor>1)
{
blue=bArr[index]/factor;
green=gArr[index]/factor;
red=rArr[index]/factor;
index++;
}
else
{
blue=bArr[index];
green=gArr[index];
red=rArr[index];
index++;
}
(*img)->mData[col]=detectNum(blue);
(*img)->mData[++col]=detectNum(green);
(*img)->mData[++col]=detectNum(red);
}
}
二、基于参考白的算法
1.统计每个灰度值的像素个数
2.求出值前大5%的像素灰度像素最为参考白,然后可以获得参考白的平均灰度值avgGray=参考白总像素值totalPixel/参考白像素个数total。则光照
void Illumination_compensation(V_Image** img)
{
int col=0,index=0;
int rows=(*img)->mRow,cols=(*img)->mCol,cns=(*img)->mChannels;
unsigned char *grayArr=(unsigned char *) calloc(rows*cols,sizeof(unsigned char));
///计算原像素的灰度值
for(col=0; col<rows*cols*cns; col++)
grayArr[index++]=((*img)->mData[col] * 0.114 + (*img)->mData[++col] * 0.587 + (*img)->mData[++col] * 0.299);
int num=floor(rows*cols*0.05);
int *refIndexArr=(int *) calloc(num,sizeof(int));//参考白数列
int *avgRefIndexArr=(int *) calloc(num,sizeof(int));//参考白数列
float *pixelNum=(float *) calloc(256,sizeof(float));//像素数数列
///初始化数组为0
for(index=0; index<256; index++)
pixelNum[index]=0;
///统计像素灰度个数
for(col=0; col<rows*cols; col++ )
pixelNum[grayArr[col]]++;
///求出灰度值从大到小前百分之五的灰度值是哪个灰度值maxPixel
int total=0,maxPixel;
for(index=255; index>=0; index--)
{
if(total<num)
{
total+=pixelNum[index];
maxPixel=index;
}
else break;
}
///求出参考白的总灰度数
int totalPixel=0;
for(index=maxPixel; index<255; index++)
totalPixel+=index*pixelNum[index];
///参考白的平均灰度数
float avgGray=totalPixel/total;
///光照补偿系数
float coe=255/avgGray;
///原像素值乘以光照补偿系数
for(index=0; index<rows*cols; index++)
{
(*img)->mData[index*3]=detectNum((*img)->mData[index*3]*coe);
(*img)->mData[index*3+1]=detectNum((*img)->mData[index*3+1]*coe);
(*img)->mData[index*3+2]=detectNum((*img)->mData[index*3+2]*coe);
}
}