概述
為了更好地利用VD6283TX傳感器的特點和功能,本章專門用于捕獲光強度和相關(guān)色溫值。VD6283TX,作為ST的高級色感器,具有并行感測多個通道的能力,這使得它成為光強和色溫測量的理想選擇。
最近在弄ST的課程,需要樣片的可以加群申請:615061293 。
硬件準備
首先需要準備一個開發(fā)板,這里我準備的是自己繪制的開發(fā)板:
視頻教學(xué)
https://www.bilibili.com/video/BV1xu4y1t75n/
樣品申請
https://www.wjx.top/vm/OhcKxJk.aspx#](
源碼下載
https://download.csdn.net/download/qq_24312945/88391797
參考源碼
這里使用的參考為STM32CUBEMX配置的X-CUBE-ALS軟件包。
設(shè)置增益
增益是用來調(diào)整傳感器對光的敏感度。高的增益值意味著傳感器對光更敏感,而低的增益值則相反。
CH1 到 CH6 代表六個不同的通道或色道,所以需要設(shè)置六個通道的增益,地址為0x25到0x2A。
每個通道都可以設(shè)置16種增益,如下所示。
這里設(shè)置增益為1,配置如下。
//通道增益設(shè)置
//0000: reserved
//0001: AGAIN = 66.6x
//0010: AGAIN = 50x
//0011: AGAIN = 33x
//0100: AGAIN = 25x
//0101: AGAIN = 16x
//0110: AGAIN = 10x
//0111: AGAIN = 7.1x
//1000: AGAIN = 5x
//1001: AGAIN = 3.33x
//1010: AGAIN = 2.5x
//1011: AGAIN = 1.67x
//1100: AGAIN = 1.25x
//1101: AGAIN = 1x
//1110: AGAIN = 0.83x
//1111: AGAIN = 0.71x
VD6283TX_setALSGainCH1(VD6283TX_ID, 0x0D);
VD6283TX_setALSGainCH2(VD6283TX_ID, 0x0D);
VD6283TX_setALSGainCH3(VD6283TX_ID, 0x0D);
VD6283TX_setALSGainCH4(VD6283TX_ID, 0x0D);
VD6283TX_setALSGainCH5(VD6283TX_ID, 0x0D);
VD6283TX_setALSGainCH6(VD6283TX_ID, 0x0D);
設(shè)置VD6283TX傳感器中不同通道的模擬增益值函數(shù)如下。
// ALS Gain Registers for Channels
#define VD6283TX_ALS_GAIN_CH1 0x25
#define VD6283TX_ALS_GAIN_CH2 0x26
#define VD6283TX_ALS_GAIN_CH3 0x27
#define VD6283TX_ALS_GAIN_CH4 0x28
#define VD6283TX_ALS_GAIN_CH5 0x29
#define VD6283TX_ALS_GAIN_CH6 0x2A
/**
* @brief 設(shè)置VD6283的ALS通道2模擬增益
*
* @param add 設(shè)備地址
* @param gain 模擬增益值,對應(yīng)于上述描述中的AGAIN[4:0]
* @retval 操作的返回狀態(tài)
*/
uint8_t VD6283TX_setALSGainCH2(uint8_t add, uint8_t gain)
{
if (gain > 0x0F || gain == 0x00) {
// 輸入的增益值無效或保留,返回錯誤碼
return 0xFF;
}
// 如果用I2C等其他通信協(xié)議,可以調(diào)用相應(yīng)的寫入函數(shù)。
// 假設(shè)VD6283TX_write_reg是一個函數(shù),它寫入一個字節(jié)到指定的寄存器。
return VD6283TX_write_reg(add, VD6283TX_ALS_GAIN_CH2, &gain, 1);
}
/**
* @brief 設(shè)置VD6283的ALS通道3模擬增益
*
* @param add 設(shè)備地址
* @param gain 模擬增益值,對應(yīng)于上述描述中的AGAIN[4:0]
* @retval 操作的返回狀態(tài)
*/
uint8_t VD6283TX_setALSGainCH3(uint8_t add, uint8_t gain)
{
if (gain > 0x0F || gain == 0x00) {
// 輸入的增益值無效或保留,返回錯誤碼
return 0xFF;
}
// 如果用I2C等其他通信協(xié)議,可以調(diào)用相應(yīng)的寫入函數(shù)。
// 假設(shè)VD6283TX_write_reg是一個函數(shù),它寫入一個字節(jié)到指定的寄存器。
return VD6283TX_write_reg(add, VD6283TX_ALS_GAIN_CH3, &gain, 1);
}
/**
* @brief 設(shè)置VD6283的ALS通道4模擬增益
*
* @param add 設(shè)備地址
* @param gain 模擬增益值,對應(yīng)于上述描述中的AGAIN[4:0]
* @retval 操作的返回狀態(tài)
*/
uint8_t VD6283TX_setALSGainCH4(uint8_t add, uint8_t gain)
{
if (gain > 0x0F || gain == 0x00) {
// 輸入的增益值無效或保留,返回錯誤碼
return 0xFF;
}
// 如果用I2C等其他通信協(xié)議,可以調(diào)用相應(yīng)的寫入函數(shù)。
// 假設(shè)VD6283TX_write_reg是一個函數(shù),它寫入一個字節(jié)到指定的寄存器。
return VD6283TX_write_reg(add, VD6283TX_ALS_GAIN_CH4, &gain, 1);
}
/**
* @brief 設(shè)置VD6283的ALS通道5模擬增益
*
* @param add 設(shè)備地址
* @param gain 模擬增益值,對應(yīng)于上述描述中的AGAIN[4:0]
* @retval 操作的返回狀態(tài)
*/
uint8_t VD6283TX_setALSGainCH5(uint8_t add, uint8_t gain)
{
if (gain > 0x0F || gain == 0x00) {
// 輸入的增益值無效或保留,返回錯誤碼
return 0xFF;
}
// 如果用I2C等其他通信協(xié)議,可以調(diào)用相應(yīng)的寫入函數(shù)。
// 假設(shè)VD6283TX_write_reg是一個函數(shù),它寫入一個字節(jié)到指定的寄存器。
return VD6283TX_write_reg(add, VD6283TX_ALS_GAIN_CH5, &gain, 1);
}
/**
* @brief 設(shè)置VD6283的ALS通道6模擬增益
*
* @param add 設(shè)備地址
* @param gain 模擬增益值,對應(yīng)于上述描述中的AGAIN[4:0]
* @retval 操作的返回狀態(tài)
*/
uint8_t VD6283TX_setALSGainCH6(uint8_t add, uint8_t gain)
{
if (gain > 0x0F || gain == 0x00) {
// 輸入的增益值無效或保留,返回錯誤碼
return 0xFF;
}
// 如果用I2C等其他通信協(xié)議,可以調(diào)用相應(yīng)的寫入函數(shù)。
// 假設(shè)VD6283TX_write_reg是一個函數(shù),它寫入一個字節(jié)到指定的寄存器。
return VD6283TX_write_reg(add, VD6283TX_ALS_GAIN_CH6, &gain, 1);
}
基準配置
寄存配置可以通過寄存器0x32進行配置。
這里配置為默認值。
//光源的閃爍 默認為3
VD6283TX_setPedestalValue(VD6283TX_ID,0x03);
具體操作如下所示。
// Pedestal Value Register
#define VD6283TX_PEDESTAL_VALUE 0x32
/**
* @brief 設(shè)置VD6283的pedestal值
*
* @param add 設(shè)備的I2C地址
* @param pdst_val 要設(shè)置的pedestal值 (位于[2:0]范圍內(nèi))
* @retval 操作的返回狀態(tài)(例如:成功或失敗)
*/
uint8_t VD6283TX_setPedestalValue(uint8_t add, uint8_t pdst_val)
{
// 驗證輸入參數(shù)的有效性
if (pdst_val > 0x07) {
return 0xFF; // 錯誤碼,表示無效的參數(shù)
}
// 假設(shè)有一個函數(shù)VD6283TX_write_reg,用于向給定的地址寫入一個字節(jié)
return VD6283TX_write_reg(add, VD6283TX_PEDESTAL_VALUE, &pdst_val, 1);
}
設(shè)置ALS曝光時間
VD6283給出了曝光時間的配置,寄存器位0x1d-0x1e。
配置100ms為0x003f(63),時間為(63+ 1) x 16384/10.24M=102.4ms。
//設(shè)置VD6283的ALS曝光時間
//EXTIME: exposure time = (EXTIME[9:0] + 1) x 16384/Fosc
//Fosc = 10.24 MHz
//Default value = 80 ms (min. = 1.6 ms and max. = 1.6 s)
//0x003f,設(shè)置為100ms
VD6283TX_setALSExposureTime(VD6283TX_ID, 0x003f) ;
具體操作如下所示。
// ALS Exposure Registers
#define VD6283TX_ALS_EXPOSURE_M 0x1D
#define VD6283TX_ALS_EXPOSURE_L 0x1E
/**
* @brief 設(shè)置VD6283的ALS曝光時間
*
* @param add 設(shè)備地址
* @param exTime 曝光時間計數(shù)值(EXTIME[9:0],不是實際的時間單位)
* @retval 操作的返回狀態(tài)
*
* 該函數(shù)用于控制VD6283的ALS曝光時間。寄存器地址從0x1D到0x1E。
* 寄存器的[9:0]位表示ALS的曝光時間。
* 默認值對應(yīng)的曝光時間是80毫秒,最小值是1.6毫秒,最大值是1.6秒。
*/
uint8_t VD6283TX_setALSExposureTime(uint8_t add, uint16_t exTime)
{
uint8_t data[2];
uint8_t ret;
data[0] = exTime & 0xFF; // 低字節(jié)
data[1] = (exTime > > 8) & 0xFF; // 高字節(jié)
ret = VD6283TX_write_reg(add, VD6283TX_ALS_EXPOSURE_L, &data[0], 1);
if(ret)
return ret;
else
ret = VD6283TX_write_reg(add, VD6283TX_ALS_EXPOSURE_M, &data[1], 1);
return ret;
}
通道使能
由于VD6283TX有六個,所以進行使能時候需要根據(jù)所需要的通道進行使能,主要寄存器為0x2d和0x2e。
這里將6個通道都開啟。
//設(shè)置VD6283的ALS通道使能狀態(tài)(1-5) 0x1F- >11111
VD6283TX_setALSChannelEnable(VD6283TX_ID, 0x1F);
//設(shè)置VD6283的ALS通道6使能狀態(tài)
VD6283TX_setChannel6Enable(VD6283TX_ID, 0x01);
函數(shù)如下所示。
// Channel 6 Enable Register
#define VD6283TX_CHANNEL6_ENABLE 0x2D
// ALS Channel Enable Register
#define VD6283TX_ALS_CHANNEL_ENABLE 0x2E
/**
* @brief 設(shè)置VD6283的通道6使能
*
* @param add 設(shè)備地址
* @param enable 1表示啟用通道6,0表示禁用通道6
* @retval 操作的返回狀態(tài)
*/
uint8_t VD6283TX_setChannel6Enable(uint8_t add, uint8_t enable)
{
uint8_t data;
if (enable > 1) {
// 輸入的使能值無效,返回錯誤碼
return 0xFF;
}
// 根據(jù)enable參數(shù)來設(shè)置或清除CH6_EN位
if (enable) {
data |= 0x01; // 設(shè)置第0位
} else {
data &= ~0x01; // 清除第0位
}
// 使用I2C或其他通信協(xié)議寫回更改后的值。
// 假設(shè)VD6283TX_write_reg是一個函數(shù),用于向指定的寄存器寫入一個字節(jié)。
return VD6283TX_write_reg(add, VD6283TX_CHANNEL6_ENABLE, &data, 1);
}
/**
* @brief 設(shè)置VD6283的ALS通道使能狀態(tài)
*
* @param add 設(shè)備的I2C地址
* @param channels 一個字節(jié),其中位[4:0]表示要啟用的ALS通道
* @retval 操作的返回狀態(tài)(例如:成功或失敗)
*/
uint8_t VD6283TX_setALSChannelEnable(uint8_t add, uint8_t channels)
{
// 檢查channels的位[7:5]是否為0,因為這些位是保留的
if (channels & 0xE0) {
return 0xFF; // 錯誤碼,表示無效的參數(shù)
}
// 假設(shè)有一個函數(shù)VD6283TX_write_reg,用于向給定的地址寫入一個字節(jié)
return VD6283TX_write_reg(add, VD6283TX_ALS_CHANNEL_ENABLE, &channels,1);
}
啟用ALS操作
寄存器0x03是選擇ALS的工作模式(單次測量或連續(xù)測量)并啟動或停止ALS操作。
這里啟動單次測量模式。
//啟用VD6283的ALS操作,使用ALS_CONT模式啟動ALS操作。
VD6283TX_enableALSOperation(VD6283TX_ID, 0x01);
具體函數(shù)如下所示。
#define VD6283TX_ALS_CTRL 0x03
/**
* @brief 啟用或禁用VD6283的ALS操作
*
* @param add 設(shè)備地址
* @param enable 1啟用ALS操作,0禁用
* @retval 操作的返回狀態(tài)
*[0] ALS_EN (Enable ALS Operation): 啟用或禁用ALS操作。
*0: ALS操作已停止(即,空閑)。
*1: 使用ALS_CONT模式啟動ALS操作。
*/
uint8_t VD6283TX_enableALSOperation(uint8_t add, uint8_t enable)
{
uint8_t data[1] = {(enable & 0x01)};
return VD6283TX_write_reg(add, VD6283TX_ALS_CTRL, data, 1);
}
中斷查詢及清除
當信號準備好時候可以查詢寄存器0x02進行查詢。
可以通過查詢中斷方式判斷數(shù)據(jù)是否獲取完畢。
//獲取VD6283的中斷狀態(tài),等待INTR_ST為0
timeout = 0xffff;//溢出時間
while(1)
{
data=VD6283TX_getInterruptStatus(VD6283TX_ID);
timeout--;
if(data==0 || timeout==0)
break;
}
具體函數(shù)如下所示。
#define VD6283TX_INTERRUPT_CTRL 0x02
/**
* @brief 獲取VD6283的中斷狀態(tài)
*[1] INTR_ST (Interrupt Status): 該位表示中斷狀態(tài)。當值為1時,表示沒有觸發(fā)中斷或上一個中斷尚未清除。
*[0] CLR_INTR (Clear Interrupt): 該位用于清除中斷標志。INTR_ST中斷標志可以通過將CLR_INTR設(shè)置為'1',隨后設(shè)置為'0'來清除。
* @param add 設(shè)備地址
* @retval 中斷狀態(tài):1 表示沒有觸發(fā)中斷或上一個中斷尚未清除,0 則表示已清除或未設(shè)置。
*
*/
uint8_t VD6283TX_getInterruptStatus(uint8_t add)
{
uint8_t intStatus[1] = {0};
VD6283TX_read_reg(add, VD6283TX_INTERRUPT_CTRL, intStatus, 1);
return (intStatus[0] > > 1) & 0x01;
}
獲取中斷如下所示。
//清除VD6283的中斷標志
VD6283TX_clearInterruptFlag(VD6283TX_ID);
具體函數(shù)如下所示。
/**
* @brief 清除VD6283的中斷標志
*
* @param add 設(shè)備地址
* @retval 操作的返回狀態(tài)
*
*/
uint8_t VD6283TX_clearInterruptFlag(uint8_t add)
{
uint8_t cmd[1] = {0x01}; // Set CLR_INTR to '1'
uint8_t ret = VD6283TX_write_reg(add, VD6283TX_INTERRUPT_CTRL, cmd, 1);
cmd[0] = 0x00; // Set CLR_INTR to '0'
ret |= VD6283TX_write_reg(add, VD6283TX_INTERRUPT_CTRL, cmd, 1);
return ret;
}
獲取ALS數(shù)據(jù)
讀取環(huán)境光傳感器通1的數(shù)據(jù)值。數(shù)據(jù)值由三個字節(jié)組成,包括高、中和低字節(jié),共計24位。這可能意味著該通道可以提供非常高的測量精度,因為它使用24位來表示一個單一的測量值。
獲取方式如下所示。
//讀取VD6283的ALS通道數(shù)據(jù)
AlsResults[LIGHT_SENSOR_RED_CHANNEL]=VD6283TX_getALSCH1Data(VD6283TX_ID);
ALS_CH2_DATA=VD6283TX_getALSCH2Data(VD6283TX_ID);
AlsResults[LIGHT_SENSOR_BLUE_CHANNEL]=VD6283TX_getALSCH3Data(VD6283TX_ID);
AlsResults[LIGHT_SENSOR_GREEN_CHANNEL]=VD6283TX_getALSCH4Data(VD6283TX_ID);
ALS_CH5_DATA=VD6283TX_getALSCH5Data(VD6283TX_ID);
ALS_CH6_DATA=VD6283TX_getALSCH6Data(VD6283TX_ID);
具體操作如下所示。
/**
* @brief 讀取VD6283的ALS通道1數(shù)據(jù)
*
* @param add 設(shè)備地址
* @retval 返回數(shù)值
*ALS channel 1 data register (ALS_CH1_DATA)
*
*這是一個只讀寄存器,用于讀取ALS通道1的數(shù)據(jù)。寄存器地址范圍是0x06到0x08,默認值都是0x00。
*
*[23:16] ALS_CH1_DATA_H:ALS通道1的高字節(jié)數(shù)據(jù)。
*
*[15:8] ALS_CH1_DATA_M:ALS通道1的中字節(jié)數(shù)據(jù)。
*
*[7:0] ALS_CH1_DATA_L:ALS通道1的低字節(jié)數(shù)據(jù)
*/
uint32_t VD6283TX_getALSCH1Data(uint8_t add)
{
uint8_t data1[3];
uint32_t ALSCHData=0;
VD6283TX_read_reg(add, VD6283TX_ALS_CH1_DATA_H, data1, 3);
ALSCHData = data1[0];
ALSCHData = ALSCHData< < 8;
ALSCHData|= data1[1];
ALSCHData = ALSCHData< < 8;
ALSCHData|= data1[2];
return ALSCHData;
}
/**
* @brief 讀取VD6283的ALS通道2數(shù)據(jù)
*
* @param add 設(shè)備地址
* @param data 存儲讀取數(shù)據(jù)的數(shù)組,大小至少為3字節(jié)
* @retval 操作的返回狀態(tài)
*用于讀取ALS通道2的數(shù)據(jù)。寄存器地址范圍是0x0A到0x0C,默認值都是0x00。
*
*[23:16] ALS_CH2_DATA_H:ALS通道2的高字節(jié)數(shù)據(jù)。
*
*[15:8] ALS_CH2_DATA_M:ALS通道2的中字節(jié)數(shù)據(jù)。
*
*[7:0] ALS_CH2_DATA_L:ALS通道2的低字節(jié)數(shù)據(jù)。
*/
uint32_t VD6283TX_getALSCH2Data(uint8_t add)
{
uint8_t data1[3];
uint32_t ALSCHData=0;
VD6283TX_read_reg(add, VD6283TX_ALS_CH2_DATA_H, data1, 3);
ALSCHData = data1[0];
ALSCHData = ALSCHData< < 8;
ALSCHData|= data1[1];
ALSCHData = ALSCHData< < 8;
ALSCHData|= data1[2];
return ALSCHData;
}
/**
* @brief 讀取VD6283的ALS通道3數(shù)據(jù)
*
* @param add 設(shè)備地址
* @param data 存儲讀取數(shù)據(jù)的數(shù)組,大小至少為3字節(jié)
* @retval 操作的返回狀態(tài)
*用于讀取ALS通道3的數(shù)據(jù)。寄存器地址范圍是0x0E到0x10,默認值都是0x00。
*
*[23:16] ALS_CH3_DATA_H:ALS通道3的高字節(jié)數(shù)據(jù)。
*
*[15:8] ALS_CH3_DATA_M:ALS通道3的中字節(jié)數(shù)據(jù)。
*
*[7:0] ALS_CH3_DATA_L:ALS通道3的低字節(jié)數(shù)據(jù)。
*/
uint32_t VD6283TX_getALSCH3Data(uint8_t add)
{
uint8_t data1[3];
uint32_t ALSCHData=0;
VD6283TX_read_reg(add, VD6283TX_ALS_CH3_DATA_H, data1, 3);
ALSCHData = data1[0];
ALSCHData = ALSCHData< < 8;
ALSCHData|= data1[1];
ALSCHData = ALSCHData< < 8;
ALSCHData|= data1[2];
return ALSCHData;
}
/**
* @brief 讀取VD6283的ALS通道4數(shù)據(jù)
*
* @param add 設(shè)備地址
* @param data 存儲讀取數(shù)據(jù)的數(shù)組,大小至少為3字節(jié)
* @retval 操作的返回狀態(tài)
*用于讀取ALS通道4的數(shù)據(jù)。寄存器地址范圍是0x12到0x14,默認值都是0x00。
*
*[23:16] ALS_CH4_DATA_H:ALS通道4的高字節(jié)數(shù)據(jù)。
*
*[15:8] ALS_CH4_DATA_M:ALS通道4的中字節(jié)數(shù)據(jù)。
*
*[7:0] ALS_CH4_DATA_L:ALS通道4的低字節(jié)數(shù)據(jù)。
*/
uint32_t VD6283TX_getALSCH4Data(uint8_t add)
{
uint8_t data1[3];
uint32_t ALSCHData=0;
VD6283TX_read_reg(add, VD6283TX_ALS_CH4_DATA_H, data1, 3);
ALSCHData = data1[0];
ALSCHData = ALSCHData< < 8;
ALSCHData|= data1[1];
ALSCHData = ALSCHData< < 8;
ALSCHData|= data1[2];
return ALSCHData;
}
/**
* @brief 讀取VD6283的ALS通道5數(shù)據(jù)
*
* @param add 設(shè)備地址
* @param data 存儲讀取數(shù)據(jù)的數(shù)組,大小至少為3字節(jié)
* @retval 操作的返回狀態(tài)
*用于讀取ALS通道5的數(shù)據(jù)。寄存器地址范圍是0x16到0x18,默認值都是0x00。
*
*[23:16] ALS_CH5_DATA_H:ALS通道5的高字節(jié)數(shù)據(jù)。
*
*[15:8] ALS_CH5_DATA_M:ALS通道5的中字節(jié)數(shù)據(jù)。
*
*[7:0] ALS_CH5_DATA_L:ALS通道5的低字節(jié)數(shù)據(jù)。
*/
uint32_t VD6283TX_getALSCH5Data(uint8_t add)
{
uint8_t data1[3];
uint32_t ALSCHData=0;
VD6283TX_read_reg(add, VD6283TX_ALS_CH5_DATA_H, data1, 3);
ALSCHData = data1[0];
ALSCHData = ALSCHData< < 8;
ALSCHData|= data1[1];
ALSCHData = ALSCHData< < 8;
ALSCHData|= data1[2];
return ALSCHData;
}
/**
* @brief 讀取VD6283的ALS通道6數(shù)據(jù)
*
* @param add 設(shè)備地址
* @param data 存儲讀取數(shù)據(jù)的數(shù)組,大小至少為3字節(jié)
* @retval 操作的返回狀態(tài)
*用于讀取ALS通道6的數(shù)據(jù)。寄存器地址范圍是0x1A到0x1C,默認值都是0x00。
*
*[23:16] ALS_CH6_DATA_H:ALS通道6的高字節(jié)數(shù)據(jù)。
*
*[15:8] ALS_CH6_DATA_M:ALS通道6的中字節(jié)數(shù)據(jù)。
*
*[7:0] ALS_CH6_DATA_L:ALS通道6的低字節(jié)數(shù)據(jù)。
*/
uint32_t VD6283TX_getALSCH6Data(uint8_t add)
{
uint8_t data1[3];
uint32_t ALSCHData=0;
VD6283TX_read_reg(add, VD6283TX_ALS_CH6_DATA_H, data1, 3);
ALSCHData = data1[0];
ALSCHData = ALSCHData< < 8;
ALSCHData|= data1[1];
ALSCHData = ALSCHData< < 8;
ALSCHData|= data1[2];
return ALSCHData;
}
計算光強及色溫
計算色溫(Correlated Color Temperature, CCT)的方法基于顏色科學(xué)和人類對顏色的感知。
這里移植了ST提供代碼,左邊為ST提供代碼,右邊為本項目代碼。
從RGB到XYZ:
RGB色彩空間是基于顯示設(shè)備(如電視和計算機屏幕)的顏色表示。然而,為了更廣泛、更精確地描述顏色(特別是在與人的視覺感知有關(guān)的情況下),科學(xué)家們使用了CIE 1931 XYZ色彩空間。
RGB到XYZ的轉(zhuǎn)換通常使用一個線性轉(zhuǎn)換矩陣。這是因為RGB和XYZ都是線性色彩空間,所以可以通過一個線性關(guān)系(即矩陣乘法)從一個空間轉(zhuǎn)換到另一個空間。
為什么要使用XYZ空間:
XYZ色彩空間是一個設(shè)備無關(guān)的色彩空間,這意味著它不依賴于特定的顯示設(shè)備或光源。這使得它成為一個非常適合描述色彩和進行色彩科學(xué)研究的空間。
其中,Y值與亮度或明度有關(guān),而X和Z與色彩有關(guān)。從XYZ值,我們可以計算出xy色度坐標,這些坐標在CIE色度圖上描述了顏色的色調(diào)和飽和度。
計算CCT:
通過將XYZ轉(zhuǎn)換為xy色度坐標,我們可以在CIE色度圖上定位顏色。然后,我們可以使用McCamy的公式(或其他方法)來近似CCT。CCT基本上表示該顏色與哪種"色溫"的黑體輻射器最接近。例如,一個CCT值為6500K的光可能看起來與中午的陽光相似。
McCamy的公式是一個經(jīng)驗公式,基于xy色度坐標為輸入,并提供一個近似的CCT值。它是通過對多個實際樣本進
在CIE 1931 XYZ色彩空間中,Y值通常與亮度或明度有關(guān),這也可以與光的強度或光照量(lux)聯(lián)系起來。
具體來說:
X, Y, Z 在XYZ色彩空間中分別代表三個維度的色彩信息。
Y 組件直接與感知亮度有關(guān)。在光學(xué)和顏色科學(xué)中,它經(jīng)常被用來代表一個光源或反射物的明度或亮度,因此,它可以與光照量(用lux度量)直接關(guān)聯(lián)。
當我們在測量光源或環(huán)境光時,這個Y 值可以被視為對于該光源的總亮度或光強的表示。
*
* @brief compute cct value from RGB channels values
*/
static void compute_cct(uint32_t TimeExposure, ResultCCT_t *Result)
{
/* correlation matrix used in order to convert RBG values to XYZ space */
/*
* (X) (G) (Cx1 Cx2 Cx3)
* (Y) = (B) * (Cy1 Cy2 Cy3)
* (Z) (R) (Cz1 Cz2 Cz3)
*
* X = G * Cx1 + B * Cx2 + R * Cx3
* Y = G * Cy1 + B * Cy2 + R * Cy3
* Z = G * Cz1 + B * Cz2 + R * Cz3
*
* */
static const double_t Cx[] = {0.416700, -0.143816, 0.205570};
static const double_t Cy[] = {0.506372, -0.120614, -0.028752};
static const double_t Cz[] = {0.335866, 0.494781, -0.552625};
uint8_t i;
double_t data[CCT_COEFF_NB];
double_t X_tmp = 0, Y_tmp = 0, Z_tmp = 0;
double_t xyNormFactor;
double_t m_xNormCoeff;
double_t m_yNormCoeff;
double_t nCoeff;
double_t expo_scale = 100800.0 / TimeExposure;
/* normalize and prepare RGB channels values for cct computation */
data[0] = (double_t)AlsResults[LIGHT_SENSOR_GREEN_CHANNEL] / (float_t)VD6283TX_DEFAULT_GAIN;
data[1] = (double_t)AlsResults[LIGHT_SENSOR_BLUE_CHANNEL] / (float_t)VD6283TX_DEFAULT_GAIN;
data[2] = (double_t)AlsResults[LIGHT_SENSOR_RED_CHANNEL] / (float_t)VD6283TX_DEFAULT_GAIN;
/* apply correlation matrix to RGB channels to obtain (X,Y,Z) */
for (i = 0; i < CCT_COEFF_NB; i++)
{
X_tmp += Cx[i] * data[i];
Y_tmp += Cy[i] * data[i];
Z_tmp += Cz[i] * data[i];
}
/* transform (X,Y,Z) to (x,y) */
xyNormFactor = X_tmp + Y_tmp + Z_tmp;
m_xNormCoeff = X_tmp / xyNormFactor;
m_yNormCoeff = Y_tmp / xyNormFactor;
/* rescale X, Y, Z according to expo. Reference is G1x and 100.8ms */
Result- >X = expo_scale * X_tmp;
Result- >Y = expo_scale * Y_tmp;
Result- >Z = expo_scale * Z_tmp;
/* apply McCamy's formula to obtain CCT value (expressed in °K) */
nCoeff = (m_xNormCoeff - 0.3320) / (0.1858 - m_yNormCoeff);
Result- >cct = (449 * pow(nCoeff, 3) + 3525 * pow(nCoeff, 2) + 6823.3 * nCoeff + 5520.33);
}
打印信息如下所示。
static void print_cct(ResultCCT_t *Result)
{
/* clip the result in order to avoid negative values */
if (Result- >Y < 0) Result- >Y = 0;
printf("%6ld.%01ld Lux ", (long)Result- >Y, (long)decimal_partlux(Result- >Y));
printf("tCCT: %5ld Kr", (long)Result- >cct);
fflush(stdout);
}
結(jié)果演示
審核編輯:湯梓紅
-
驅(qū)動
+關(guān)注
關(guān)注
12文章
1840瀏覽量
85291 -
光強傳感器
+關(guān)注
關(guān)注
0文章
6瀏覽量
12741 -
環(huán)境光傳感器
+關(guān)注
關(guān)注
3文章
108瀏覽量
21912 -
驅(qū)動開發(fā)
+關(guān)注
關(guān)注
0文章
130瀏覽量
12077 -
stm32cubemx
+關(guān)注
關(guān)注
5文章
283瀏覽量
14809
發(fā)布評論請先 登錄
相關(guān)推薦
評論