如果买过这个模块的小伙伴就会知道,TCS34725厂家给的颜色识别例程写的就是一坨,一点都不准。
这里,我来给大家提供一些思路。
1.白光校正
想要把颜色传感器数值转换为RGB,我们可以直接从传感器得到cdata,rdata,gdata,bdata三种数据,分别使用rdata,gdata,bdata于cdata相除得到一个比例值,与255相乘,cdata表示色温,也可以理解成光照,得RGB数值,再取白光读取计算的RGB,把它调校到255:255:255,得到各分量的校准参数。
这里我用的是python代码,如果你用的是C也是一样的思路。
第一步:
你需要先准备一个白色物体放在模块前面,用来白光校正。
白色物体的rgb就用 rdata_white, gdata_white, bdata_white 以及cdata_white来表示;然后计算初始状态下rgb值为多少,具体代码如下:
RGB888_R = (rdata / cdata) * 255
RGB888_G = (gdata / cdata) * 255
RGB888_B = (bdata / cdata) * 255
上面这段代码直接替换原有的rgb888转换的代码 ,就当作初始的rgb888的值。
第二步:
计算校准增益,这个步骤需要在外部计算得到三个数值。
R_gain = 255 / RGB888_R # 保证R分量在白色时为255
G_gain = 255 / RGB888_G # 保证G分量在白色时为255
B_gain = 255 / RGB888_B # 保证B分量在白色时为255
注意:如果你使用的是C,记得除法记得强转成浮点数,以免精度损失过大。
第三步:
实时转换传感器数据的值
# 注意:需处理 cdata=0 的情况(返回黑色)
if cdata == 0:
R, G, B = 0, 0, 0
else:
RGB888_R = (rdata / cdata) * 255 * R_gain
RGB888_G = (gdata / cdata) * 255 * G_gain
RGB888_B = (bdata / cdata) * 255 * B_gain
RGB888_R = int(max(0, min(255, RGB888_R)))
RGB888_G = int(max(0, min(255, RGB888_G)))
RGB888_B = int(max(0, min(255, RGB888_B)))
RGB888 = (RGB888_R << 16) | (RGB888_G << 8) | RGB888_B
白光校正到此结束。
2.黑白光校正
如果你完成的白光校正,大概率测出的颜色偏亮,这里还有一个多光校正的方法,通过黑白两色的光来校正,其实理论上就是将他输出的数值映射到0-255这个区间上,但是在实验的过程中发现即便光照强度相同,cdata也随着rgb的变化受到很大的影响,这里就不建议再加上色温来进行处理了,只处理rgb三个值。
和之前一样,准备一个黑色和白色的物块。
写一个例程来获取这两个物块的rdata gdata bdata的值,因为这是一个区间,我们可是适当缩小这个区间,用下面代码,获取一个线性函数用来映射
# 白色物块对应的值,根据自己的实际情况取
white_r = 3100
white_g = 5200
white_b = 5000
white_c = 13000
# 黑色物块对应的值,根据自己的实际情况取
black_r = 640
black_g = 1350
black_b = 1355
black_c = 3300
# 线性校正公式 rgb888 = a* rgbdata +b
def func(rgbdata_black, rgbdata_white):
a = (255 - 0) / (rgbdata_white - rgbdata_black)
b = 0 - a * rgbdata_black
return a,b
r_a, r_b = func(black_r, white_r)
g_a, g_b = func(black_g, white_g)
b_a, B_b = func(black_b, white_b)
print(r_a, r_b)
print(g_a, g_b)
print(b_a, B_b)
最后的到三组值,就可以对rgb888转换函数进行修改了,代码如下:
def GetRGB888(self):
if self.C == 0:
self.RGB888_R = 0
self.RGB888_G = 0
self.RGB888_B = 0
self.RGB888 = 0x000000
else:
self.RGB888_R = self.R * R_a - R_b
self.RGB888_G = self.G * G_a - G_b
self.RGB888_B = self.B * B_a - B_b
self.RGB888_R = max(0, min(255, int(self.RGB888_R)))
self.RGB888_G = max(0, min(255, int(self.RGB888_G)))
self.RGB888_B = max(0, min(255, int(self.RGB888_B)))
self.RGB888 = (self.RGB888_R << 16) | (self.RGB888_G << 8) | self.RGB888_B