检测色卡饱和度和色彩偏差

news/2024/11/8 4:31:57/

简介

  本篇讲解如何测24色卡的饱和度和色彩偏差。

实现原理

  主要是模仿imatest来实现,详细资料请参考:http://www.imatest.com/docs/colorcheck/
具体做法:1、首先鼠标框选出色卡中24色所在位置,然后分别在对应色块中再取出小块矩形。这24个小矩形中色彩数据,就是之后用来处理计算的数据。2、接着将24个小矩形的图像,转换为Lab格式。3、饱和度计算公式:Chroma = 100% mean((a*i_meas2 + b*i_meas2)1/2 ) / mean((a*i_ideal2 + b*i_ideal2)1/2 ) ;a*i_meas2:被计算的色块对应色块的平均a。b*i_meas2:被计算的色块对应色块的平均b。a*i_ideal2:作为计算模板色块对应的平均a。b*i_ideal2:作为计算模板色块对应的平均b。4、不包含亮度的色彩偏差Cab:a*i_corr = 100 a*i_meas / Sat ; b*i_corr  = 100 b*i_meas / SatΔCi_corr = |Ci_corr – Ci_ideal | = ( (a*i_corr – a*i_ideal )2 + (b*i_corr – b*i_ideal )2 )1/25、包含亮度的色彩偏差Eab:ΔE*ab = ( (L2*-L1*)2+ (a2*-a1*)2+ (b2*-b1*)2 )1/2; ΔC* = ( (a2*-a1*)2+ (b2*-b1*)2 )1/2
          6、模板测卡对应的数据信息:http://xritephoto.com/documents/literature/en/ColorData-1p_EN.pdf

具体实现

框选出24色块数据

  首先鼠标框选出一个矩形框,然后使用函数mccRectAddr,在矩形框中,分别选中24色块数据。
void mccRectAddr(Mat mat1, Mat mat2, int* rectAddr){int i, j;for(j=0; j<4; j++){for(i=0; i<6; i++){ccm_rect[i+6*j][0] = rectAddr[0] + (rectAddr[2] - rectAddr[0]) * (12 + 6*i + 34 * i )/ 234;ccm_rect[i+6*j][1] = rectAddr[1] + (rectAddr[3] - rectAddr[1]) * (10 + 6*j + 34 * j) / 151;ccm_rect[i+6*j][2] = rectAddr[0] + (rectAddr[2] - rectAddr[0]) * (22 + 6*i + 34 * i)/ 234;ccm_rect[i+6*j][3] = rectAddr[1] + (rectAddr[3] - rectAddr[1]) * (20 + 6*j + 34 * j) / 151;rectangle(mat1, Point(ccm_rect[i+6*j][0], ccm_rect[i+6*j][1]), Point(ccm_rect[i+6*j][2], ccm_rect[i+6*j][3]), Scalar(255,0,0), 2);}}mccRoiGet(mat2);
}
  注意,这里mat1和mat2都是需要被计算的色卡图片,rectAddr保存的书鼠标矩形框坐标信息。函数中,接着在mat1中,选中的24色块数据位置
分别画出小矩形到mat1中,用来显示。接着使用函数mccRoiGet将选中的24色块数据,在mat2使用ROI扣去出来。
void mccRoiGet(Mat mat1){char str[10];int i=0, j=0;for(i=0; i<4; i++){for(j=0; j<6; j++){mccROI[j+i*6] = mat1(cv::Rect(ccm_rect[j+6*i][0], ccm_rect[j+6*i][1],ccm_rect[j+6*i][2] - ccm_rect[j+6*i][0], ccm_rect[j+6*i][3] - ccm_rect[j+6*i][1]));}}
}
  这样,选中的24色块数据,就分别保存到了mccROI[24]中了。对应的效果演示如下:

Sat计算

void mccSat(){IplImage pI_1;CvScalar s;int width, height;int i, j, k;double ab_meas=0, ab_idea=0;for(k=0; k< 18; k++){pI_1 = mccROI[k];cvCvtColor(&pI_1, &pI_1, CV_BGR2Lab);width = mccROI[k].rows;height = mccROI[k].cols;for(i=0; i<width; i++){for(j=0; j< height; j++){s = cvGet2D(&pI_1, i, j);if(i==0 && j==0){mccLab[k][0] = s.val[0];    mccLab[k][1] = s.val[1];    mccLab[k][2] = s.val[2];    }else{mccLab[k][0] = (s.val[0] + mccLab[k][0]) / 2;mccLab[k][1] = (s.val[1] + mccLab[k][1]) / 2;   mccLab[k][2] = (s.val[2] + mccLab[k][2]) / 2;}}}mccLab[k][0] = mccLab[k][0] * 100 / 255;mccLab[k][1] = mccLab[k][1] - 128;mccLab[k][2] = mccLab[k][2] - 128;ab_meas = sqrt((mccLab[k][1] * mccLab[k][1])+(mccLab[k][2] * mccLab[k][2])) + ab_meas;ab_idea = sqrt((mccLabModel[k][1] * mccLabModel[k][1])+(mccLabModel[k][2] * mccLabModel[k][2])) + ab_idea;cvCvtColor(&pI_1, &pI_1, CV_Lab2BGR);}ab_meas = ab_meas / 18;ab_idea = ab_idea / 18;Sat = ab_meas / ab_idea;printf("Sat:%lf\n", Sat);
}
  将之前mccROI[24]中保存的色块数据分别进行处理。首先是将数据转换为Lab的格式。接着计算出色块L a b的平均值,保存到对应的mccLab中。
需要注意:1、这里计算色彩相关,所以只需要处理前18块数据,后面6块灰阶图像不用处理。2、在opencv中L a b,都被转换为0 - 255的数据存储。所以进行计算之前,需要将L a b数据先转换回来。
		mccLab[k][0] = mccLab[k][0] * 100 / 255;mccLab[k][1] = mccLab[k][1] - 128;mccLab[k][2] = mccLab[k][2] - 128;
  最后就是根据之前提到的计算饱和度公式,将饱和度计算出来,保存到Sat中。

Cab计算

void mccCab(){IplImage pI_1;CvScalar s;int width, height;int i, j, k;double a_err=0, b_err=0;Cab_sum = 0;Cab_max = 0;for(k=0; k< 18; k++){pI_1 = mccROI[k];cvCvtColor(&pI_1, &pI_1, CV_BGR2Lab);width = mccROI[k].rows;height = mccROI[k].cols;for(i=0; i<width; i++){for(j=0; j< height; j++){s = cvGet2D(&pI_1, i, j);if(i==0 && j==0){mccLab[k][0] = s.val[0];    mccLab[k][1] = s.val[1];    mccLab[k][2] = s.val[2];    }else{mccLab[k][0] = (s.val[0] + mccLab[k][0]) / 2;mccLab[k][1] = (s.val[1] + mccLab[k][1]) / 2;   mccLab[k][2] = (s.val[2] + mccLab[k][2]) / 2;}}}mccLab[k][0] = mccLab[k][0] * 100 / 255;mccLab[k][1] = mccLab[k][1] - 128;mccLab[k][2] = mccLab[k][2] - 128;a_err = mccLab[k][1] / Sat;b_err = mccLab[k][2] / Sat;Cab[k] = (a_err - mccLabModel[k][1]) * (a_err - mccLabModel[k][1]) + \(b_err - mccLabModel[k][2]) * (b_err - mccLabModel[k][2]);Cab[k] = sqrt(Cab[k]);if(Cab_max < Cab[k]){Cab_max = Cab[k];	}cvCvtColor(&pI_1, &pI_1, CV_Lab2BGR);Cab_sum = Cab_sum + Cab[k];printf("Cab[%d]:%lf\n", k, Cab[k]);}Cab_sum = Cab_sum / 18;printf("Cab_sum:%lf\n", Cab_sum);
}

Eab计算

void mccEab(){IplImage pI_1;CvScalar s;int width, height;int i, j, k;Eab_sum = 0;Eab_max = 0;for(k=0; k< 18; k++){pI_1 = mccROI[k];cvCvtColor(&pI_1, &pI_1, CV_BGR2Lab);width = mccROI[k].rows;height = mccROI[k].cols;for(i=0; i<width; i++){for(j=0; j< height; j++){s = cvGet2D(&pI_1, i, j);if(i==0 && j==0){mccLab[k][0] = s.val[0];    mccLab[k][1] = s.val[1];    mccLab[k][2] = s.val[2];    }else{mccLab[k][0] = (s.val[0] + mccLab[k][0]) / 2;mccLab[k][1] = (s.val[1] + mccLab[k][1]) / 2;   mccLab[k][2] = (s.val[2] + mccLab[k][2]) / 2;}}}mccLab[k][0] = mccLab[k][0] * 100 / 255;mccLab[k][1] = mccLab[k][1] - 128;mccLab[k][2] = mccLab[k][2] - 128;Eab[k] = (mccLab[k][0] - mccLabModel[k][0]) * (mccLab[k][0] - mccLabModel[k][0]) + \(mccLab[k][1] - mccLabModel[k][1]) * (mccLab[k][1] - mccLabModel[k][1]) + \(mccLab[k][2] - mccLabModel[k][2]) * (mccLab[k][2] - mccLabModel[k][2]);Eab[k] = sqrt(Eab[k]);if(Eab_sum==0){Eab_sum = Eab[k];	}else{Eab_sum = (Eab[k] + Eab_sum) / 2;}if(Eab_max < Eab[k]){Eab_max = Eab[k];	}printf("mccLab[%d]->Eab:%lf\n", k, Eab[k]);cvCvtColor(&pI_1, &pI_1, CV_Lab2BGR);}printf("Eab_sum:%lf\n", Eab_sum);
}

结果显示[编辑 | 编辑源代码]

  最后在另一张空白图片上,将得到的Sat\Cab\Eab数据都显示出来。
        sprintf(showSat, "Sat:%.1lf", Sat* 100);sprintf(showCab, "Cab: mean=%.1lf, max=%.1lf", Cab_sum, Cab_max);sprintf(showEab, "Eab: mean=%.1lf, max=%.1lf", Eab_sum, Eab_max);cvPutText(&pI_barPic, showSat ,cvPoint(10, 15),&font,CV_RGB(255,0,0));cvPutText(&pI_barPic, showCab ,cvPoint(10, 30),&font,CV_RGB(255,0,0));cvPutText(&pI_barPic, showEab ,cvPoint(10,45),&font,CV_RGB(255,0,0));cv::imshow(barPic, src2);

效果演示[编辑 | 编辑源代码]

  结果发现,除了饱和度之外,Cab和Eab都和imatest有不小的差距。对应的效果演示如下:
        
代码下载:http://download.csdn.net/detail/u011630458/8793681

http://www.ppmy.cn/news/311506.html

相关文章

亮度对比度色调饱和度最佳_色彩三要素之—— “饱和度”

今天是色彩三要素最后一篇了,学起学起! 何为饱和度? 饱和度:色彩饱和度,可以理解为色彩的纯度,纯度越高,表现越鲜艳,纯度越低,表现越暗淡,简单来说就是色彩中灰色成分多少,这将直接影响了色彩的饱和度 。 再来看一张图⬇️

Android色彩特效处理之色调、饱和度、亮度、ColorMatrix精炼详解

一、前期基础知识储备 Bitmap&#xff08;位图文件&#xff09;&#xff0c;扩展名可以是.bmp或者.dib。位图是Windows标准格式图形文件&#xff0c;它将图像定义为由点(像素)组成&#xff0c;每个点可以由多种色彩表示&#xff0c;包括2、4、8、16、24和32位色彩。想象一下你…

色彩,饱和度,强度和对比度(HSIC)

Hue, Saturation, Intensity, and Contrast (HSIC) 色彩&#xff0c;饱和度&#xff0c;强度和对比度&#xff08;HSIC&#xff09; 1、Sunlight visibility improvement Improved contrast for multimedia content at the same power (backlight) level 阳光能见度提高 …

OpenCV - C++实战(07) — 色调、饱和度和亮度的色彩空间

目录 第7章 色调、饱和度和亮度的色彩空间 7.1 色度、饱和度和亮度的概念 7.2 图像HSV模型 7.3 通过HSV生成色彩特效 7.4 颜色用于肤色检测 7.5 完整代码 Github代码地址&#xff1a;GitHub - Qinong/OpenCV 第7章 色调、饱和度和亮度的色彩空间 RGB 是一种被广泛接受…

关于色彩饱和度调整

处理前效果图&#xff1a; 处理后效果&#xff1a;因为原图色彩饱和度实在太低&#xff0c;因此我传入了2次参数&#xff1a;numberN255 protected override void Adjust(ref byte BValue, ref byte GValue, ref byte RValue) {//郑斯彬原创算法&#xff0c;numberN表…

【OpenCV 例程300篇】205. 调节色彩平衡/饱和度/明度

OpenCV 例程200篇 总目录 201. 图像的颜色空间转换 202. 查表快速替换&#xff08;cv.LUT&#xff09; 203. 伪彩色图像处理 204. 图像的色彩风格滤镜 205. 调节色彩平衡/饱和度/明度 文章目录 【youcans 的 OpenCV 例程300篇】205. 调节色彩平衡/饱和度/明度4.3 自己调节色彩平…

高通平台camera客观项测试之色彩偏差白平衡饱和度

高通camera测试项之色彩篇 一.色彩还原度&#xff0c;饱和度&#xff0c;白平衡测试二.使用步骤1.拍图。2.打开Imatest选择“ColorCheck”选项&#xff0c;导入图片后选择ROI3.选定后&#xff0c;工具中有一些可供改变的选择项&#xff0c;具体如下图4.色彩偏差&饱和度测试…

图像的对比度、亮度、色彩饱和度调节以及灰度化

对比度的调节&#xff1a; 将图像转化到HSV格式下&#xff0c;先选出所有亮度的中值。当要增加对比度的时候&#xff0c;则降低亮度值比中值小的值&#xff0c;增加亮度值比中值更大的值&#xff1b;当要减少对比度的时候&#xff0c;则增加亮度值比中值小的值&#xff0c;降低…