1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 基于白点检测的数码相机自动白平衡算法实现(Opencv+vs)

基于白点检测的数码相机自动白平衡算法实现(Opencv+vs)

时间:2023-11-26 02:38:26

相关推荐

基于白点检测的数码相机自动白平衡算法实现(Opencv+vs)

1 白平衡

白平衡(White Balance)实现对白色物体的还原。人的大脑可以侦测并且更正不同光照下的色彩变更,因此不论在阳光、室内、阴影、或荧光下,人们所看到的白色物体仍旧为白色。但是,图像传感器没有这种适应性,传感器输出的图像可能会出现色彩失真,图像偏红或偏蓝。因此传感器采集到的图像需要经过白平衡处理。

2 基于白点检测的数码相机自动白平衡算法[1].

白平衡有三个基本的操作:色温估计,即估计出图像在YCbCr颜色空间的平均色差 ,其中图像按式(1.1)由RGB颜色空间转YCbCr颜色空间;增益计算,计算出图像R和B通道的增益(校正因子)u,v;色温校正,将图像每个像素的R和B通道分别乘上u,v,实现白平衡。

有部分色温算法是计算整个图像的平均色差,而基于白点检测的色温估计可以减少计算量,通过一定的约束条件挑选出合适的像素(白像素)来计算色差

文献[1]中按式(1.2)挑选白像素,论文中给出的phi值为180

将满足该条件的像素点认为是白色的。对于白色点有R=B=G,从式(1.1)可以看出其对应的蓝色和红色分量色差Cb=Cr=0。所以白平衡后满足式(1.2)的像素(白像素)的色差应接近0。

(1) 色温估计流程图见图1

(2) 增益u,v计算过程见图2,初始值u=v=1。lamda为调整u,v的步长,文献中lamada=0.05。

(3) 色温校正

将图像每个像素的R和B通道分别乘上u,v。重新计算色温校正后图像的色差,若色差Cb,C没有足够的小,则 返回(2)。通过不断的迭代获得图像白平衡的增益,该迭代过程见图3

在试验中发现更多次的迭代不一定能改善图像效果,这是因为步长lama固定设为0.05。所以对lama做了调整

当迭代次数大于25时,lama=0.02;当迭代次数大于40时,lama=0.005;当迭代次数大于55时,lama=0.001。

3 相应代码

#include <opencv2/core/core.hpp> #include<opencv2/highgui/highgui.hpp>#include<opencv2/imgproc/imgproc.hpp>#include<iostream>using namespace cv;using namespace std;void myBGR2YUV(const Mat image,Mat &result){Mat_<Vec3b>::const_iterator it=image.begin<Vec3b>();Mat_<Vec3f>::iterator rit=result.begin<Vec3f>();Mat_<Vec3b>::const_iterator itend=image.end<Vec3b>();//遍历所有像素 并转为YUV,注意在opencv中每个彩色像素是按BGR顺序存储的for(;it!=itend;++it,++rit){(*rit)[0]=0.114*(*it)[0]+0.587*(*it)[1]+0.299*(*it)[2];//Y(*rit)[1]=0.5*(*it)[0]-0.331264*(*it)[1]-0.168736*(*it)[2];//Cb (*rit)[2]=-0.081312*(*it)[0]-0.418688*(*it)[1]+0.5*(*it)[2];//Cr}}//估计图像result的色温为Temperature,阈值phi默认为180void CountTemperature(const Mat result,Mat &Temperature ,const short phi=180){Mat_<Vec3f>::const_iterator rit=result.begin<Vec3f>();Mat_<Vec3f>::const_iterator ritend=result.end<Vec3f>();//遍历所有像素 估计色温float Y=0,Cb=0,Cr=0,n=0,Z=0,Y1=0,Cb1=0,Cr1=0;//const int phi=180;for(;rit!=ritend;++rit,++n){Y1=(*rit)[0];Cb1=(*rit)[1];Cr1=(*rit)[2];Z=Y1-abs(Cb1)-abs(Cr1);if (Z>phi){Y+=Y1;Cb+=Cb1;Cr+=Cr1;}}//所有像素处理完了Temperature.at<Vec3f>(0,0)[0]=Y/n;Temperature.at<Vec3f>(0,0)[1]=Cb/n;Temperature.at<Vec3f>(0,0)[2]=Cr/n;}//增益计算void gain(Mat Temperature,float &u,float&v,float lamda=0.05){float Y_T=Temperature.at<Vec3f>(0,0)[0];float Cb_T=Temperature.at<Vec3f>(0,0)[1];float Cr_T=Temperature.at<Vec3f>(0,0)[2];//增益计算// float u=1,lamda=0.05,v=1;//u是B通道增益,v是R通道增益if(abs(Cb_T)>abs(Cr_T))if(Cb_T>0)u-=lamda;elseu+=lamda;elseif(Cr_T>0)v-=lamda;elsev+=lamda;}//色温校正void correctionImage(const Mat image,Mat &result,const float u ,const float v){Mat_<Vec3b>::const_iterator it=image.begin<Vec3b>();Mat_<Vec3b>::const_iterator itend=image.end<Vec3b>();Mat_<Vec3b>::iterator rit=result.begin<Vec3b>();Mat_<Vec3b>::iterator ritend=result.end<Vec3b>();//遍历所有像素 改变B和R通道的值for(;it!=itend;++it,++rit){(*rit)[0]=saturate_cast<uchar>(u*(*it)[0]);//B(*rit)[1]=saturate_cast<uchar>((*it)[1]);//G(*rit)[2]=saturate_cast<uchar>(v*(*it)[2]);//R}}int main(){Mat image=imread("F:\\opencv\\exercise\\example_images\\building.jpg"); if(!image.data){ cout<<"图像加载失败"<<endl;return -1;} Mat result;//YUV格式result.create(image.rows,image.cols,CV_32FC3);Mat final;//白平衡后的BGR图像final.create(image.rows,image.cols,image.type());Mat Temperature(1,1, CV_32FC3,Scalar(100));//初始化色温为100//BGR转为YUVmyBGR2YUV(image,result);//估计色温CountTemperature(result,Temperature);float Cb_T=Temperature.at<Vec3f>(0,0)[1];float Cr_T=Temperature.at<Vec3f>(0,0)[2];float C=sqrt(Cb_T*Cb_T+Cr_T*Cr_T);float u=1,lamda=0.05,v=1;//u是B通道增益,v是R通道增益int index=0;//迭代次数while (C>0.1&&index<80){//增益计算 u,vif (index>25)//lamda=0.02;if (index>40)//lamda=0.005;if (index>55)//lamda=0.001;gain(Temperature,u,v,lamda);//色温校正后图像为finalcorrectionImage(image,final,u ,v);//BGR转为YUVmyBGR2YUV(final,result);//估计色温 CountTemperature(result,Temperature);//cb,cr是否足够小Cb_T=Temperature.at<Vec3f>(0,0)[1];Cr_T=Temperature.at<Vec3f>(0,0)[2];C=sqrt(Cb_T*Cb_T+Cr_T*Cr_T);++index;cout<<"index="<<index<<" u="<<u<<" v="<<v<<endl;}if(!index) image.copyTo(final);//拷贝cout<<"C="<<C<<" Cb="<<Cb_T<<" Cr="<<Cr_T<<endl;//cout<<"图像加载成功"<<result.type()<<endl;namedWindow("OriginalImage");imshow("OriginalImage",image);namedWindow("WhiteBalance");imshow("WhiteBalance",final);waitKey();return 0;}

运行的结果为

[1]:周荣政, 何捷, 洪志良. 自适应的数码相机自动白平衡算法[J]. 计算机辅助设计与图形学学报, , 17(3): 529-533.

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。