1、 色温的数值到处都可以看到,是对应标准黑体辐射同样频谱时的温度就是色温。有多种计算方法,原理自行找度娘。
实现的过程,首先要把RGB信号转换成色坐标,如下图,
然后根据色坐标的坐标(x,y),转换成色温。
2. 具体色度RGB转色坐标公式如下,无感就赶紧跳过。源文件来自,https://blog.csdn.net/qq_45207442/article/details/105031491,只是方便大家晕菜,先粘过来了。
先假设:RGB、XYZ分别为两种颜色空间的三原色的单位,分别为三刺激值,rgb、xyz为归一化后的值,
由于XYZ可分别由RGB混合得到,所以:
其中:
在RGB得到的偏马蹄形图中,为了满足提出的三个条件,我们可以分析得到
1.取Y的刺激值表示混合光的亮度,则X、Z都只表示色相而无亮度,即X、Z处于无亮度线上,即:
又因为:
联立两个式子就可以得到第一张RGB图像中的直线XZ的方程:
2.由于要使三刺激值都为正,所以新组成的三角形XYZ要包含图中所有的彩色点,所以可以分别取XY、YZ直线为:
联立三条直线的方程就可以解得XYZ在RGB色度图中的坐标:
由于上面的得到的是在色度图中的坐标,是经过了归一化的,所以真实的XYZ用RGB表示的三刺激值应该乘上C,即:
对上面的矩阵求一个逆矩阵就可以将RGB用XYZ表示,即:
其中A是相应的C的倒数。
由于任意一种颜色C都可以用RGB和XYZ颜色空间进行表示,所以可以得到以下的关系:
所以XYZ和RGB的三刺激值之间的关系为:
接下来我们要做的就是求出A了!
由前面得要求二可知Y的刺激值表示的是混合色的亮度,且已知当
时的混合色为等能白光,亮度L=5.6505,带入
可解得:
又由于要求三知等能白光时XYZ空间也有三刺激值相等,所以此时还有:
带入
可解得:
所以两种颜色空间三刺激值之间得关系为:
因为色坐标图是经过归一化得,所以归一化后的关系为:
到这一步,我们就可以把之前RGB色坐标图中的色坐标(r,g)带入上面的式子中得到XYZ色坐标图中的色坐标(x,y),就完成了最前面两幅图之间的转换了
3. 色坐标转换成色温,
这个感觉略好。
4. 那么就简言之,首先换算成rgb,
虽然不大精确,但是可以对照上表,
取
r= F8
g=(F5+F6)/2
b= F3
这样的算法还没太整明白,不过,用来做程序测试是可以的了。希望砖家能拍砖。
然后换成求出x,y,z
x=2.7689R+1.7517G+1.1302B
Y=1.0000R+4.9507G+0.0601B
Z=.... 暂时不用
最后求出色温,
n=(0.3320-x)(0.1858-y)
CDC=437 *n^3+ 3601 *n^2 +_6831 *n+ 5517
5. 代码如下,
/*!
*/
#include "DFRobot_AS7341.h"
DFRobot_AS7341 as7341;
void setup(void)
{
Serial.begin(115200);
//Detect if IIC can communicate properly
while (as7341.begin() != 0) {
Serial.println("IIC init failed, please check if the wire connection is correct");
delay(1000);
}
}
void loop(void)
{
DFRobot_AS7341::sModeOneData_t data1;
DFRobot_AS7341::sModeTwoData_t data2;
float R,G,B,x,y,n,cdc;
//Start spectrum measurement
//Channel mapping mode: 1.eF1F4ClearNIR,2.eF5F8ClearNIR
as7341.startMeasure(as7341.eF1F4ClearNIR);
//Read the value of sensor data channel 0~5, under eF1F4ClearNIR
data1 = as7341.readSpectralDataOne();
Serial.print("F1(405-425nm):");
Serial.println(data1.ADF1);
Serial.print("F2(435-455nm):");
Serial.println(data1.ADF2);
Serial.print("F3(470-490nm):");
Serial.println(data1.ADF3);
Serial.print("F4(505-525nm):");
Serial.println(data1.ADF4);
as7341.startMeasure(as7341.eF5F8ClearNIR);
data2 = as7341.readSpectralDataTwo();
Serial.print("F5(545-565nm):");
Serial.println(data2.ADF5);
Serial.print("F6(580-600nm):");
Serial.println(data2.ADF6);
Serial.print("F7(620-640nm):");
Serial.println(data2.ADF7);
Serial.print("F8(670-690nm):");
Serial.println(data2.ADF8);
Serial.print("Clear:");
Serial.println(data2.ADCLEAR);
Serial.print("NIR:");
Serial.println(data2.ADNIR);
delay(1000);
R=data2.ADF8 / 256;
G=(data2.ADF5 +data2.ADF6) / 256;
B=data1.ADF3/ 256 ;
x=2.7689*R+1.7517*G+1.1302*B;
y=1.0000*R+4.9507*G+0.0601*B;
n=(0.3320-x)*(0.1858-y);
cdc=437*n*n*n+ 3601 *n*n +6831 *n+ 5517;
Serial.print("CDC: ");
Serial.println(cdc);
Serial.print(" ");
delay(1000);
}
显示结果,涂黄的就是结果,不过好像不大对的。日光灯色温是6000K吗?不过从程序的角度和传感器的测试角度,这个过程是Pass的。
本帖最后由 北方 于 2020-12-30 10:49 编辑一看就说研究过颜色的大佬!