光线补偿

原文讲解不清,特修改一下。。
    在图片的整体颜色偏暗或偏亮时,需要采用光线补偿的方法调整图片颜色。普遍采用光线补偿方法的是HsuRL在《Face detection in color images》中提出的可变光照及复杂背景下的肤色检测算法。
    具体做法是检测图像中亮度在前5%的像素(参考白),按一定公式计算出调整值,则对图像的RGB三个分量进行线性调整,如果整张图片较暗,前5%平均灰度值会比255较小,调整值较大,把整个图片的颜色调亮.

HsuRL《Face detection in color images》论文下载地址 http://www.51xuewen.com/res/show.aspx?resid=2453 = 0;
unsigned char RedTemp,GreenTemp,BlueTemp;

for (j=y1; j<y2; j++) {
    for (i=x1; i<x2; i++) {
      index = VL_RGB_PIXEL * (j*width + i);
    
   //得到rgb值
    RedTemp=input[index];
          GreenTemp=input[index+1];
          BlueTemp=input[index+2];
   //计算灰度值
   int gray = (RedTemp * 299 + GreenTemp * 587 + BlueTemp * 114)/1000;
   histogram[gray]++;
}
}
int calnum =0;
  int total = x2 * y2;
  int num;
  //下面的循环得到满足系数thresholdco的临界灰度级
  for(i =0;i<256;i++)
  {
   if((float)calnum/total < thresholdco) //得到前5%的高亮像素
   {
    calnum+= histogram[255-i];//histogram保存的是某一灰度值的像素个数,calnum是边界灰度之上的像素数
    num = i;
   }
   else
    break;
  }
  int averagegray = 0;
  calnum =0;
  //得到满足条件的象素总的灰度值
  for(i = 255;i>=255-num;i--)
  {
   averagegray += histogram[i]
*i;//总的像素的个数*灰度值
   calnum += histogram[i]
;//总的像素数
  }
  averagegray /=calnum;
  //得到光线补偿的系数
  float co = 255.0/(float)averagegray
;
  //下面的循环对图象进行光线补偿
for (j=y1; j<y2; j++) {
      for (i=x1; i<x2; i++)
   {
    //得到数据偏移
       index = VL_RGB_PIXEL * (j*width + i);
    //得到分量
       for(int n=0;n<3;n++)
    {
    int nTemp=input[index+n]*co;
    output[index+n]=(nTemp>255)?255:nTemp;
    
    }  }  }


核心代码:
const float thresholdco = 0.05;
//象素个数的临界常数
const int thresholdnum = 100;
//灰度级数组
int histogram[256];
for(i =0;i<256;i++)
  histogram
至此,我还有一点疑问:这个的数学原理是什么呢?虽然的确有效果。。
原文解释:


另外一种补偿方法是东南大学夏思宇博士在一种改进的自适应肤色检测算法》(链接中提供此论文的万方站点下载地址,免费的没找到。呵呵中提出的用白平衡算法代替HsuRl的光线补偿方法,能较好的解决由光照引起的图像彩色偏移,使得检测结果更加稳健。白平衡会按目前图像中的图像特性,调整整个图像红绿蓝强度,以修正外部光线所造成的误差,平衡就是不考虑环境光线,让系统默认“白色”,就是让他能认出白色,而平衡其他颜色在有色光线下的色调。计算步骤如下:
1.计算图像的R,G,B分量的各自平均值R',G',B',并令图像的平均灰度值avgGray=(G'+R'+B')/3.
2.令Kr=avgGray/R',Kg=avgGray/G',Kb=avgGray/B',调整每个像素点的RGB值R=R*Kr,G=G*Kg,B=B*Kb,并处理越界情况,将大于255的值置为255
代码:
int RedTotal=0,GreenTotal=0,BlueTotal=0,NumTotal,GrayTotal,RedTemp,GreenTemp,BlueTemp;
  unsigned char RedAverage,GreenAverage,BlueAverage,GrayAverage;
  
  float Kr,Kg,Kb;
  for (j=y1; j<y2; j++) {
    for (i=x1; i<x2; i++) {
      index = VL_RGB_PIXEL * (j*width + i);
     //得到rgb值
    RedTotal+=input[index];
          GreenTotal+=input[index+1];
          BlueTotal+=input[index+2];
   //计算灰度值
    //GrayTotal = (input[index] * 299 + input[index+1] * 587 + input[index+2] * 114)/1000;
  
}
}
    NumTotal=x2 * y2;
    RedAverage=RedTotal/NumTotal;
GreenAverage=GreenTotal/NumTotal;
BlueAverage=BlueTotal/NumTotal;
GrayAverage=(RedAverage+GreenAverage+BlueAverage)/3;
Kr=(float)GrayAverage/(RedAverage);
Kg=(float)GrayAverage/(GreenAverage);
Kb=(float)GrayAverage/(BlueAverage);
for (j=y1; j<y2; j++) {
    for (i=x1; i<x2; i++) {
      index = VL_RGB_PIXEL * (j*width + i);
      RedTemp=input[index] * Kr;
   GreenTemp=input[index+1] * Kg;
   BlueTemp=input[index+2] * Kb;
    output[index]=(RedTemp>255) ? 255 : RedTemp;
    output[index+1]=(GreenTemp>255) ? 255 : GreenTemp;
    output[index+2]=(BlueTemp>255) ? 255 : BlueTemp;
    
}
}
它的补偿效果有待进一步验证

 

posted on 2009-07-31 21:48  oskycar  阅读(2472)  评论(0编辑  收藏  举报

导航