1. 基于RGB颜色空间的偏色检测
http://blog.csdn.net/q339659207/article/details/20053249
对全图的RGB进行均值统计。
对于偏红、绿、蓝而言
RGB的公式为
R: dmax = (ave_r - max(ave_g, ave_b)) / ave_r;
dave = (ave_r - (ave_g+ave_b)/2) / ave_r;
d = (dmax + dave) / 2;
GB也类似。
对于偏黄而言
则: d = ((ave_g+ave_r)/2 - ave_b) / max(ave_g, ave_r);
统计完后,再将图片分割成N片,然后对N片进行色彩统计。
如果是全面偏色,则所有求出来的值都比较大(0-1)。
当然在进行比对的时候还有比对比值。
用了一些图来进行测试。如下。
2. 基于LAB颜色空间的偏色检测
http://blog.csdn.net/lengwuqin/article/details/26606785
网上常用的一种方法是将RGB图像转变到CIE L*a*b*空间,其中L*表示图像亮度,a*表示图像红/绿分量,b*表示图像黄/蓝分量。通常存在色偏的图像,在a*和b*分量上的均值会偏离原点很远,方差也会偏小;通过计算图像在a*和b*分量上的均值和方差,就可评估图像是否存在色偏。计算CIE L*a*b*空间是一个比较繁琐的过程,好在OpenCV提供了现成的函数,因此整个过程也不复杂。
- /********************************************************************************************
- *函数描述: calcCast 计算并返回一幅图像的色偏度以及,色偏方向
- *函数参数: InputImg 需要计算的图片,BGR存放格式,彩色(3通道),灰度图无效
- * cast 计算出的偏差值,小于1表示比较正常,大于1表示存在色偏
- * da 红/绿色偏估计值,da大于0,表示偏红;da小于0表示偏绿
- * db 黄/蓝色偏估计值,db大于0,表示偏黄;db小于0表示偏蓝
- *函数返回值: 返回值通过cast、da、db三个应用返回,无显式返回值
- *********************************************************************************************/
- void colorException(Mat InputImg,float& cast,float& da,float& db)
- {
- Mat LABimg;
- cvtColor(InputImg,LABimg,CV_BGR2Lab);//参考http://blog.csdn.net/laviewpbt/article/details/9335767
- //由于OpenCV定义的格式是uint8,这里输出的LABimg从标准的0~100,-127~127,-127~127,被映射到了0~255,0~255,0~255空间
- float a=0,b=0;
- int HistA[256],HistB[256];
- for(int i=0;i<256;i++)
- {
- HistA[i]=0;
- HistB[i]=0;
- }
- for(int i=0;i<LABimg.rows;i++)
- {
- for(int j=0;j<LABimg.cols;j++)
- {
- a+=float(LABimg.at<cv::Vec3b>(i,j)[1]-128);//在计算过程中,要考虑将CIE L*a*b*空间还原 后同
- b+=float(LABimg.at<cv::Vec3b>(i,j)[2]-128);
- int x=LABimg.at<cv::Vec3b>(i,j)[1];
- int y=LABimg.at<cv::Vec3b>(i,j)[2];
- HistA[x]++;
- HistB[y]++;
- }
- }
- da=a/float(LABimg.rows*LABimg.cols);
- db=b/float(LABimg.rows*LABimg.cols);
- float D =sqrt(da*da+db*db);
- float Ma=0,Mb=0;
- for(int i=0;i<256;i++)
- {
- Ma+=abs(i-128-da)*HistA[i];//计算范围-128~127
- Mb+=abs(i-128-db)*HistB[i];
- }
- Ma/=float((LABimg.rows*LABimg.cols));
- Mb/=float((LABimg.rows*LABimg.cols));
- float M=sqrt(Ma*Ma+Mb*Mb);
- float K=D/M;
- cast = K;
- return;
- }