1 项目需求
1.1 目标
本项目旨在设计一个系统,能够识别至少五种颜色,并将识别结果显示在LCD屏幕上。同时,系统还需要能够将识别到的颜色的ADC数据转换为RGB值,并在LCD上用色块的形式展示出来,以便我们能够直观地观察到颜色的接近程度。
1.2 功能需求
- 颜色识别: 系统需要能够准确地识别至少五种不同的颜色。
- RGB值转换: 对于识别到的颜色ADC数据,系统需要将其转换为对应的RGB值。
- 显示基本信息: 在LCD上显示当前识别到的颜色名称和对应的RGB值。
- 绘制颜色色块: 在LCD上用色块的形式绘制出识别到的颜色,以便用户直观地观察到颜色的接近程度。
2 完成的功能及达到的性能
1. 颜色识别
系统通过I2C传输命令给传感器,并读取ADC数据以获取颜色信息。经过LUX计算,系统准确返回RGB值,从而成功识别红、绿、蓝、黄、紫、白、青蓝等五种以上不同颜色。
2. RGB值的转换
对于识别到的颜色的ADC数据,系统利用“calculate_rgb”函数将其转换为相应的RGB值,并根据“recognize_color”函数中设定的颜色阈值范围,准确地映射到对应的颜色名称。
3. 显示基本信息
在获取到RGBZ值和识别到的颜色名称后,在LCD屏幕上显示当前识别到的颜色名称和对应的RGB值。
4. 绘制识别的颜色色块
系统利用获取到的RGB值,通过“display.circle()”函数,在LCD屏幕上绘制出识别到的颜色色块。色块的颜色与实际颜色接近度较高,使得我们可以直观地观察到识别结果。
3 实现思路
颜色识别: 使用图像处理算法对摄像头采集的图像数据信息进行处理,提取出图像中的颜色信息,并与预先定义的颜色模板进行匹配,从而实现颜色识别。
RGB值转换: 对于识别到的颜色,将其获取的ADC数据通过LUX公式进行转换获取该颜色的RGB值。
显示基本信息: 将识别到的颜色名称和RGB值显示在LCD屏幕上。
绘制颜色色块: 利用转换所得的RGB值在LCD屏幕上通过函数绘制出与识别到的颜色相近的色块。
4 实现过程
4.1程序流程图
4.2颜色识别:
- 读取ADC数据:使用read_adc_data函数从颜色传感器获取RGB颜色的原始数据。该函数按顺序读取指定寄存器地址的低、中、高字节数据,并将其合并为一个ADC数据,以便后续处理。
- 识别颜色:使用recognize_color函数对读取到的RGB数据进行颜色识别。根据预定义的颜色识别规则,判断RGB值与特定颜色的阈值范围关系,从而确定颜色类型。如果RGB值符合某一颜色的阈值范围,则返回对应的颜色名称;否则返回"Unknown"表示无法识别的颜色。
# 读取ADC数据
def read_adc_data(register_addr_low, register_addr_mid, register_addr_high):
data = bytearray(3)
i2c.writeto(LTR381_I2C_ADDR, bytes([register_addr_low]))
time.sleep(0.01)
data[0] = i2c.readfrom_mem(LTR381_I2C_ADDR, register_addr_low, 1)[0]
i2c.writeto(LTR381_I2C_ADDR, bytes([register_addr_mid]))
time.sleep(0.01)
data[1] = i2c.readfrom_mem(LTR381_I2C_ADDR, register_addr_mid, 1)[0]
i2c.writeto(LTR381_I2C_ADDR, bytes([register_addr_high]))
time.sleep(0.01)
data[2] = i2c.readfrom_mem(LTR381_I2C_ADDR, register_addr_high, 1)[0]
CS_COLOR_ADC_DATA = (data[2]<<16) | (data[1]<<8) | data[0]
return CS_COLOR_ADC_DATA
# 识别颜色
def recognize_color(red, green, blue):
if red > 200 and green < 150 and blue < 100:
return "Red"
elif red < 100 and green > 200 and blue < 150:
return "Green"
elif red < 60 and green < 150 and blue > 200:
return "Blue"
elif red > 200 and green > 200 and blue < 150:
return "Yellow"
elif red > 200 and green < 200 and blue > 200:
return "Purple"
elif red > 200 and green > 200 and blue > 200:
return "White"
elif red < 100 and green > 200 and blue > 200:
return "Cyan"
else:
return "Unknown"
4.3ADC数据到RGB值的转换
- · 根据读取到的ADC数据,利用数据手册中的公式,通过计算将其转换成LUX值对应的光照强度值,即对应的RGB值。同时,限定RGB值的范围在0-255之间,以避免程序运行时的异常情况。
# 根据Lux值计算RGB值
def calculate_rgb(red_raw, green_raw, blue_raw, cs_ir_data):
if red_raw == 0:
red_raw = 1 # 避免除以零错误
if green_raw == 0:
green_raw = 1 # 避免除以零错误
if blue_raw == 0:
blue_raw = 1 # 避免除以零错误
red = int(min(255, max(0, 3.2 * red_raw * (1 - 0.033 * cs_ir_data / red_raw))))
green = int(min(255, max(0, 3.2 * green_raw * (1 - 0.033 * cs_ir_data / green_raw))))
blue = int(min(255, max(0, 3.2 * blue_raw * (1 - 0.033 * cs_ir_data / blue_raw))))
return red, green, blue
4.4显示基本信息
- 利用MicroPython自带的库`breakout_colourlcd240x240`,初始化一个LCD对象`display`用于绘制LCD屏幕。根据`calculate_rgb`函数和`recognize_color`函数识别并返回的颜色名称和RGB值,将其显示在LCD屏幕上。
# 读取颜色数据并在LCD上显示
def read_and_display_color():
init()
while True:
red_raw = read_adc_data(0x10, 0x11, 0x12)
green_raw = read_adc_data(0x0D, 0x0E, 0x0F)
blue_raw = read_adc_data(0x13, 0x14, 0x15)
CS_IR_DATA = read_adc_data(0x0A, 0x0B, 0x0C)
if red_raw > 255:
red_raw = 255
if green_raw > 255:
green_raw = 255
if blue_raw > 255:
blue_raw = 255
#根据Lux值计算RGB值
red, green, blue = calculate_rgb(red_raw, green_raw, blue_raw, CS_IR_DATA)
print("Red:", red, "Green:", green, "Blue:", blue)
# 在LCD上显示颜色数据
display.set_pen(0,0,0)
display.rectangle(0, 0, 240, 240)#绘制背景,避免乱码
display.set_pen(255, 0, 0)
display.text("Red="+str(red), 0, 0, 5, 3)
display.set_pen(0, 255, 0)
display.text("Green="+str(green), 0, 60, 5, 3)
display.set_pen(0, 0, 255)
display.text("Blue="+str(blue), 0, 120, 5, 3)
4.5绘制颜色色块
- 使用LCD屏幕绘制出识别到的颜色色块,根据计算得到的颜色的RGB值确定色块的颜色。
首先,通过调用`recognize_color`函数识别颜色,并在LCD屏幕上显示颜色名称。然后,根据RGB值设置色块颜色,并绘制在LCD屏幕上。最后,通过调用`display.update()`函数更新LCD内容,使色块显示在屏幕上。
color_name = recognize_color(red, green, blue)
display.set_pen(255, 255, 255)
display.text("Color="+color_name, 0, 180, 5, 3)
print(color_name)
# 在LCD上绘制色块
display.set_pen(red, green, blue)
display.circle(190, 120, 50)
time.sleep(1)
display.update() # 更新LCD内容
5 遇到的难题
5.1颜色识别精度
在实际环境中,光照条件、物体表面反射等因素会影响颜色识别的精度,需要采用合适的算法和技术来提高颜色识别的准确性。
5.2RGB值转换
不同颜色空间之间的转换可能存在误差,需要进行适当的校正和调整。
5.3LCD色彩显示
LCD屏幕的色彩显示受到硬件限制,可能无法完美还原颜色,需要进行颜色校正和优化。
6 未来的计划建议
在我看来,该项目已经成功实现了颜色识别及校准的功能,并达到了预期指标。然而通过更换硬件,还有许多可以提升与扩展的地方:
- 增加颜色识别种类: 可以进一步增加系统能够识别的颜色种类,提高系统的适用范围。
- 优化颜色识别算法: 进一步优化颜色识别算法,提高颜色识别的准确性和稳定性。
- 扩展应用领域: 可以将颜色识别系统应用到更广泛的领域,如智能家居、智能车载等,拓展系统的应用场景和市场潜力。