一种自动阈值白平衡算法实现

1.算法原理

白平衡是图像处理的一个极重要概念。所谓白平衡(英文名称为White Balance),就是对白色物体的还原。当我们用肉眼观看这大千世界时,在不同的光线下,对相同的颜色的感觉基本是相同的,比如在早晨旭日初升时,我们看一个白色的物体,感到它是白的;而我们在夜晚昏暗的灯光下,看到的白色物体,感到它仍然是白的。这是由于人类从出生以后的成长过程中,人的大脑已经对不同光线下的物体的彩色还原有了适应性。但是,作为拍摄设备,如数码相机,可没有人眼的适应性,在不同的光线下,由于CCD输出的不平衡性,造成数码相机彩色还原失真。一般情况下,我们习惯性地认为太阳光是白色的,已知直射日光的色温是5200K左右,白炽灯的色温是3000K左右。用传统相机的日光片拍摄时,白炽灯光由于色温太低,所以偏黄偏红。所以通常现场光线的色温低于相机设定的色温时,往往偏黄偏红,现场光线的色温高于相机设定时,就会偏蓝。

为了解决不同色温下,引起的白色漂移现象。由于白色对色温变化的响应最大,通常用白色来作为调整的基色。通常的白平衡技术有:自动白平衡、钨光白平衡、荧光白平衡、室内白平衡、手动调节。本文仅介绍其中的一种自动白平衡。

白平衡算法通常分为两步:白色点的检测,白色点的调整。本方法采用一个动态的阀值来检测白色点。详细算法过程为:

1.  把图像w*h从RGB空间转换到YCrCb空间。

2.  选择参考白色点:

a. 把图像分成宽高比为4:3个块(块数可选)。

b. 对每个块,分别计算Cr,Cb的平均值Mr,Mb。

c. 对每个块,根据Mr,Mb,用下面公式分别计算Cr,Cb的方差Dr,Db。

d. 判定每个块的近白区域(near-white region)。

判别表达式为:

设一个“参考白色点”的亮度矩阵RL,大小为w*h。

若符合判别式,则作为“参考白色点”,并把该点(i,j)的亮度(Y分量)值赋给RL(i,j);

若不符合,则该点的RL(i,j)值为0。

3.  选取参考“参考白色点”中最大的10%的亮度(Y分量)值,并选取其中的最小值Lu_min.

4.  调整RL,若RL(i,j)<Lu_min,  RL(i,j)=0; 否则,RL(i,j)=1;

5.  分别把R,G,B与RL相乘,得到R2,G2,B2。  分别计算R2,G2,B2的平均值,Rav,Gav,Bav;

6.  得到调整增益:  Ymax=double(max(max(Y)))/5;
                                    Rgain=Ymax/Rav;
                                    Ggain=Ymax/Gav;
                                    Bgain=Ymax/Bav;

7.  调整原图像:Ro= R*Rgain; Go= G*Ggain; Bo= B*Bgain;

2.关键实现代码

int RGB2YCbCr(IMAGE_TYPE *bmp_img,T_U8*Y_img,double *Cb_img,double *Cr_img,DWORD width,DWORD height)
{T_U32 lineByte,Source_linebyte,source_index,dst_index;T_U16 i,j,Y;T_U16 k = 0;T_U8 *Source_img,R,G,B;double Cr;double Cb;lineByte = (width * 8 / 8 + 3) / 4 * 4; Source_img = bmp_img+54;Source_linebyte = WIDTHBYTES(width*24);for (i = 0; i < height;i++){for (j = 0;j < width;j++){source_index = Source_linebyte*i+3*j;dst_index = lineByte*i+j;R = Source_img[source_index+2];G = Source_img[source_index+1];B = Source_img[source_index];Y = 0.299*R+0.587*G+0.114*B;Cr = 0.5*R-0.419*G-0.081*B;Cb = -0.169*R-0.331*G+0.5*B;Y_img[dst_index] = (T_U8)Y;Cr_img[dst_index] = Cr;Cb_img[dst_index] = Cb;}}return 0;
}int AutoWhiteBalance_Optimi(IMAGE_TYPE *bmp_img,DWORD width,DWORD height)
{T_U8*Y_img,*Ydata_img,*SignData,R,G,B,*bmp_data,*Dstbmp_img,*Dstbmp_data;T_U16 height_step = height/3,witdth_step = width/4;DWORD  PixNum = height_step*witdth_step,i,j,m,n,Threshold =0,YLumi[256] = {0};DWORD line_width,source_line_width,source_index,CbCr_indx,index,WhitePoint = 0,WhitePointCount = 0,WhitePoint10 = 0;int arrindex=0,YMax = -999;double Mr,Mb,Dr,Db,b1,b2,b,c,*Cb_img,*Cr_img,*Cbdata_img,*Crdata_img;double MeanSumr,MeanSumb;double absSumr,absSumb,Rave,Gave,Bave,RGain,GGain,BGain;FILE *AutoWhiteBalance_fp = fopen("AutoBalance.bmp","wb");if(NULL == AutoWhiteBalance_fp){printf("Can't open AutoBalance.bmp\n");return -1;}line_width = (width * 8 / 8 + 3) / 4 * 4; //8位深的BMP图像输入图像source_line_width = ((width * 24 / 8 + 3) / 4 * 4 );Cb_img = (double*)malloc(width*height*sizeof(double));Cr_img = (double*)malloc(width*height*sizeof(double));Y_img = (T_U8*)malloc(line_width*height);Dstbmp_img = (T_U8*)malloc(source_line_width*height+BMPHEADSIZE);SignData = (T_U8*)malloc(line_width*height);memcpy(Dstbmp_img,bmp_img,source_line_width*height+BMPHEADSIZE);RGB2YCbCr(bmp_img,Y_img,Cb_img,Cr_img,width,height);Cbdata_img = Cb_img;Crdata_img = Cr_img;Ydata_img = Y_img;WhitePoint = 0;for (i= 0;i < height; i += height_step){for (j = 0; j <width; j += witdth_step){Mb = 0;Mr = 0;MeanSumr = 0;MeanSumb = 0;absSumr = 0;absSumb = 0;for (m = 0; m < height_step;m++){for (n = 0; n <witdth_step;n++){index = (m+i)*width+n+j;MeanSumr += (Crdata_img[index]);MeanSumb += (Cbdata_img[index]);}}//计每个块Cb,Cr的均值Mr = MeanSumr/(double)PixNum;Mb = MeanSumb/(double)PixNum;for (m = 0; m < height_step;m++){for (n = 0; n <witdth_step;n++){index = (m+i)*width+n+j;absSumr += abs(Crdata_img[index]-Mr);absSumb += abs(Cbdata_img[index]-Mb);}}//计算每个块绝对差累加值Dr = absSumr / PixNum;Db = absSumb / PixNum;if (Mb<0)//计算mb+db*sign(mb)  {   b=Mb+Db*(-1);  }  else  b=Mb+Db;  if (Mr<0)//计算1.5*mr+dr*sign(mb);  {  c=1.5*Mr+Dr*(-1);  }  else  c=1.5*Mr+Dr;  //候选白点像素计算for (m = 0; m < height_step;m++){for (n = 0; n <witdth_step;n++){index =(m+i)*line_width+n+j;CbCr_indx = (m+i)*width+n+j;if(abs(Cbdata_img[CbCr_indx]-b)<(1.5*Db) && abs(Crdata_img[CbCr_indx]-c)<(1.5*Dr)){YLumi[Ydata_img[index]]++;SignData[index] = Ydata_img[index];WhitePoint++;}}}}}//选取候选白点数的最亮10%确定为最终白点,并选择其前10%中的最小亮度值WhitePointCount = 0;for(i = 255; i >0; i--){WhitePointCount += YLumi[i];if(WhitePointCount >= (double)WhitePoint/10){Threshold  = i;break;}}WhitePoint10 = 0;for(i = 0; i < height;i++){for(j = 0;j < width;j++){index = i*line_width+j;if(SignData[index] >= Threshold){SignData[index] = 1;WhitePoint10++;}elseSignData[index] = 0;}}bmp_data = bmp_img+54;Dstbmp_data = Dstbmp_img + 54;Rave = 0;Gave = 0;Bave = 0;//白点的RGB三分量的平均值for(i = 0;i < height;i++){for(j = 0; j <width;j++){source_index = i*source_line_width+3*j;index = i*line_width+j;Dstbmp_data[source_index+0] = bmp_data[source_index]*SignData[index];Dstbmp_data[source_index+1] = bmp_data[source_index+1]*SignData[index];Dstbmp_data[source_index+2] = bmp_data[source_index+2]*SignData[index];Rave += Dstbmp_data[source_index+2];Gave += Dstbmp_data[source_index+1];Bave += Dstbmp_data[source_index+0];}}Rave = Rave / (WhitePoint10);Gave = Gave / (WhitePoint10);Bave = Bave / (WhitePoint10);for(i = 0; i < height;i++){for(j = 0; j < width;j++){index = i*line_width+j;if(YMax < Ydata_img[index])YMax = Ydata_img[index];}}//增益调整YMax = YMax / 3.0;RGain = YMax / Rave;GGain = YMax / Gave;BGain = YMax / Bave;//白平衡校正for(i = 0; i <height; i++){for(j = 0; j < width;j++){source_index = i*source_line_width+3*j;bmp_data[source_index] = (T_U8)(BGain* bmp_data[source_index]);bmp_data[source_index+1] = (T_U8)(GGain* bmp_data[source_index+1]);bmp_data[source_index+2] = (T_U8)(RGain* bmp_data[source_index+2]);}}fwrite(bmp_img, source_line_width*height+BMPHEADSIZE, 1, AutoWhiteBalance_fp);fclose(AutoWhiteBalance_fp);  free(Cb_img);free(Cr_img);free(Y_img);return 0;}

3.图像效果

A色温校正对比图

TL84色温校正对比图

D65色温校正对比图

参考文献:

1.http://www.cnblogs.com/haar/articles/1392227.html

2.基于灰度世界、完美反射、动态阈值等图像自动白平衡算法的原理、实现及效果

3.https://www.cnblogs.com/Imageshop/archive/2013/04/20/3032062.html

一种动态阈值白平衡算法实现相关推荐

  1. 阈值Java_亲测有效!一种完美动态阈值白平衡算法 Java实现。

    几年没发文了,重新拿起技术! 最近做图像处理,要自动处理颜色平衡问题,很多什么直方图优化之类的,都不完美.所以在博客园找到了这个前辈的文章. http://www.cnblogs.com/Images ...

  2. matlab 自动阈值白平衡算法 程序可编译实现

    一种效果很好的自动白平衡技术(WhiteBalance) 白平衡是图像处理的一个极重要概念.所谓白平衡(英文名称为White Balance),就是对白色物体的还原.当我们用肉眼观看这大千世界时,在不 ...

  3. 两种动态灰狼优化算法

    文章目录 一.理论基础 1.灰狼优化算法 2.第一种动态灰狼优化算法(DGWO1) 3.第二种动态灰狼优化算法(DGWO2) 二.仿真实验与分析 三.参考文献 一.理论基础 1.灰狼优化算法 请参考这 ...

  4. 各种存储分配算法java代码实现_Java实现操作系统中四种动态内存分配算法:BF+NF+WF+FF...

    1 概述 本文是利用Java实现操作系统中的四种动态内存分配方式 ,分别是:BF NF WF FF 分两部分,第一部分是介绍四种分配方式的概念以及例子,第二部分是代码实现以及讲解. 2 四种分配方式 ...

  5. Java实现操作系统中四种动态内存分配算法:BF+NF+WF+FF

    1 概述 本文是利用Java实现操作系统中的四种动态内存分配方式 ,分别是: BF NF WF FF 分两部分,第一部分是介绍四种分配方式的概念以及例子,第二部分是代码实现以及讲解. 2 四种分配方式 ...

  6. 词向量与词向量拼接_动态词向量算法—ELMo

    传统的词向量模型,例如 Word2Vec 和 Glove 学习得到的词向量是固定不变的,即一个单词只有一种词向量,显然不适合用于多义词.而 ELMo 算法使用了深度双向语言模型 (biLM),只训练语 ...

  7. java动态分区分配_操作系统动态分区分配算法课程设计java版解析.doc

    湖 南 文 理 学 院 实 验 报 告 课程名称 操作系统课程设计 实验名称 存储管理--动态分区分配算法的模拟 成绩 学生姓名 曹乐 专业 计算机 班级.学号 13101 18 同组者姓名 实验日期 ...

  8. java动态分区分配算法,操作系统_动态分区分配算法课程设计_java版

    <操作系统_动态分区分配算法课程设计_java版>由会员分享,可在线阅读,更多相关<操作系统_动态分区分配算法课程设计_java版(13页珍藏版)>请在人人文库网上搜索. 1. ...

  9. java动态分区分配_操作系统 动态分区分配算法课程设计 java版.pdf

    操作系统 动态分区分配算法课程设计 java版 湖 南 文 理 学 院 实 验 报 告 课程名称 操作系统课程设计 实验名称 存储管理--动态分区分配算法的模拟 成绩 学生姓名 曹乐 专业 计算机 班 ...

  10. 基于灰度世界、完美反射、动态阈值等图像自动白平衡算法的原理、实现及效果...

    原文:http://www.cnblogs.com/Imageshop/archive/2013/04/20/3032062.html 白平衡是电视摄像领域一个非常重要的概念,通过它可以解决色彩还原和 ...

最新文章

  1. 未来智能社会的一砖一瓦都需要今天我们一点点的探索发现!
  2. [每日一题] 11gOCP 1z0-052 :2013-09-1 RMAN-- repair failure........................................A20...
  3. Java基础——Java NIO详解(二)
  4. 「雕爷学编程」Arduino动手做(18)---太阳能电池模块
  5. jQuery 图片放大预览插件
  6. scrapy tool 命令
  7. dp算法求解矩阵连乘的问题
  8. 微信小程序 计算导航高度、设置浮层位置
  9. Creo二次开发:参数化设计
  10. web学生网页设计作业源码——国际足联世界杯(HTML+CSS)
  11. java秒杀源码_Java秒杀系统实战系列~商品秒杀代码实战
  12. 跨境电商系列 | 防范第三方脚本对数据隐私与安全的侵蚀
  13. aws没有免费套餐服务数据可用
  14. Aspose.Words模板创建Word【一】
  15. OUC_2022年夏季《移动软件开发》实验报告-实验2
  16. 怎么给电脑安装window7系统呢
  17. 2021 年使用 WordPress 作为 CMS 的 25 个热门网站
  18. 计算机网络安全面试问题,2016计算机信息安全工程师面试题及答案
  19. 2021.11.06总结
  20. exercises of nginx and images,more efforts, more happiness

热门文章

  1. CSS文字加粗,字体,颜色渐变,消失总结
  2. 做了多年开发的你发现自己的水平一直上不去,一篇文章教你如何提高开发水平的方法
  3. 【IT项目管理】第4章 控制项目范围
  4. STM32--舵机(SG90)
  5. React通用解决方案——浮层容器
  6. RTL8111E datasheet中提到的术语
  7. mysql pxc介绍_MySQL高可用之PXC简介
  8. 画 ArcFace 中的 margin 曲线
  9. Android同步时出错,Android Studio中的Gradle给出错误项目同步失败
  10. Bat文件的创建及其命令大全