学习目标:
在Canmv IDE环境下使用K210学习颜色识别功能,根据颜色的LAB值,框出相同颜色的物品
学习内容:
1、导入相关库,并初始化摄像头和LCD显示屏
import sensor, image, time, lcd # sensor 引入感光元件的模块
lcd.init()
sensor.reset()# 初始化相机传感器
sensor.set_pixformat(sensor.RGB565) # 设置为彩色
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time = 100) # 在更改设置后,跳过一些帧,等待感光元件变稳定
sensor.set_auto_gain(False) # 关闭图像增益,以防止图像冲洗
sensor.set_auto_whitebal(False) # 关闭图像白平衡,以防止图像冲洗
clock = time.clock()
2、在摄像头画面中绘制一个小的白色方框,提示用户将要识别的颜色放入方框内
r = [(320//2)-(50//2), (240//2)-(50//2), 50, 50] # 屏幕中心 50x50
for i in range(50):
img = sensor.snapshot() #摄像头拍摄一张照片
img.draw_rectangle(r) #画矩形
lcd.display(img) #显示在屏幕上
3、方框由白色变为绿色,开始学习颜色的LAB值,多次读取平均值作为学习的LAB值结果
threshold = [50, 50, 0, 0, 0, 0] # Middle L, A, B values.中间灰度值
for i in range(50):
img = sensor.snapshot()
hist = img.get_histogram(roi=r) ##获取直方图(颜色直方图)
lo = hist.get_percentile(0.01) # 获取1%范围的直方图的CDF(根据需要调整)!
hi = hist.get_percentile(0.99) # 获取99%范围的直方图的CDF(根据需要调整)!
#threshold_index = 0 # 0 for red, 1 for green, 2 for blue
# 颜色跟踪阈值 (L Min, L Max, A Min, A Max, B Min, B Max)
# 下面的阈值通常跟踪红色/绿色/蓝色的东西。您可能希望调整它们……
#thresholds = [(30, 100, 15, 127, 15, 127), # 通用的红色阈值
# (30, 100, -64, -8, -32, 32), # 通用的绿色阈值
# (0, 30, 0, 64, -128, 0)] # 通用的蓝色阈值
# 平均百分位值
threshold[0] = (threshold[0] + lo.l_value()) // 2
threshold[1] = (threshold[1] + hi.l_value()) // 2
threshold[2] = (threshold[2] + lo.a_value()) // 2
threshold[3] = (threshold[3] + hi.a_value()) // 2
threshold[4] = (threshold[4] + lo.b_value()) // 2
threshold[5] = (threshold[5] + hi.b_value()) // 2
#(颜色阈值,像素个数阈值,面积阈值,merge=True,那么识别到的所有色块将会合并成一个大色块
#margin ,如果设置为1,那么两个blobs如果间距1一个像素点,也会被合并)
for blob in img.find_blobs([threshold], pixels_threshold=100, area_threshold=100, merge=True, margin=10):
img.draw_rectangle(blob.rect()) #用矩形标记出目标颜色区域
img.draw_cross(blob.cx(), blob.cy()) #在目标颜色区域的中心画十字形标记
img.draw_rectangle(r, color=(0,255,0))
lcd.display(img)
4、颜色学习完成后,使用while循环识别摄像头画面中的颜色,分析与上一步学习到的颜色的LAB值是否符合,如果符合则框出来对应的颜色块
while(True):#死循环
clock.tick()
img = sensor.snapshot()
for blob in img.find_blobs([threshold], pixels_threshold=100, area_threshold=100, merge=True, margin=10):
img.draw_rectangle(blob.rect())
img.draw_cross(blob.cx(), blob.cy())
lcd.display(img)
print(clock.fps()) #打印帧率
实验分析:
Image Color Learning: |
Image Color Learning: |
Frame Buffer Image: |
RGB Color Space Histogram: |
实验过程与总结:
实验过程:
- 系统启动后,LCD屏幕将呈现摄像头捕获的图像,此时用户应将目标颜色置于屏幕中央的白色方框内。
- 当白色方框转变为绿色,表明系统已开始对颜色进行学习,该过程大约持续5秒钟。完成颜色学习后,系统将能够自动识别并框选摄像头画面中与学习颜色相匹配的区域。
总结:
- 颜色识别功能通过分析颜色的LAB值来实现。用户首先将目标颜色置于设定的方框内,系统读取并学习该颜色的LAB值。随后,系统对比摄像头采集图像中的颜色LAB值与学习值,若匹配则在屏幕上标记出识别的颜色区域。为提高识别准确度,建议在颜色对比明显的环境中操作,以减少误识别的可能性。
完整代码展示:
# Color_recognition.py - By: Jack - 周日 4月 13 2024
import sensor, image, time, lcd
# sensor 引入感光元件的模块
lcd.init()
sensor.reset()#初始化相机传感器
sensor.set_pixformat(sensor.RGB565) #设置为彩色
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time = 100)
sensor.set_auto_gain(False)
sensor.set_auto_whitebal(False)
clock = time.clock()
print("Hold the object you want to track in front of the camera in the box.")
print("MAKE SURE THE COLOR OF THE OBJECT YOU WANT TO TRACK IS FULLY ENCLOSED BY THE BOX!")
r = [(320//2)-(50//2), (240//2)-(50//2), 50, 50] # 屏幕中心 50x50
for i in range(50):
img = sensor.snapshot() #摄像头拍摄一张照片
img.draw_rectangle(r) #画矩形
lcd.display(img) #显示在屏幕上
print("Learning thresholds...")
threshold = [50, 50, 0, 0, 0, 0] # Middle L, A, B values.中间灰度值
for i in range(50):
img = sensor.snapshot()
hist = img.get_histogram(roi=r) ##获取直方图(颜色直方图)
lo = hist.get_percentile(0.01) # 获取1%范围的直方图的CDF(根据需要调整)!
hi = hist.get_percentile(0.99) # 获取99%范围的直方图的CDF(根据需要调整)!
#threshold_index = 0 # 0 for red, 1 for green, 2 for blue
# 颜色跟踪阈值 (L Min, L Max, A Min, A Max, B Min, B Max)
# 下面的阈值通常跟踪红色/绿色/蓝色的东西。您可能希望调整它们……
#thresholds = [(30, 100, 15, 127, 15, 127), # 通用的红色阈值
# (30, 100, -64, -8, -32, 32), # 通用的绿色阈值
# (0, 30, 0, 64, -128, 0)] # 通用的蓝色阈值
# 平均百分位值
threshold[0] = (threshold[0] + lo.l_value()) // 2
threshold[1] = (threshold[1] + hi.l_value()) // 2
threshold[2] = (threshold[2] + lo.a_value()) // 2
threshold[3] = (threshold[3] + hi.a_value()) // 2
threshold[4] = (threshold[4] + lo.b_value()) // 2
threshold[5] = (threshold[5] + hi.b_value()) // 2
#(颜色阈值,像素个数阈值,面积阈值,merge=True,那么识别到的所有色块将会合并成一个大色块
#margin ,如果设置为1,那么两个blobs如果间距1一个像素点,也会被合并)
for blob in img.find_blobs([threshold], pixels_threshold=100, area_threshold=100, merge=True, margin=10):
img.draw_rectangle(blob.rect()) #用矩形标记出目标颜色区域
img.draw_cross(blob.cx(), blob.cy()) #在目标颜色区域的中心画十字形标记
img.draw_rectangle(r, color=(0,255,0))
lcd.display(img)
print("Thresholds learned...")
print("Start Color Recognition...")
while(True):#死循环
clock.tick()
img = sensor.snapshot()
for blob in img.find_blobs([threshold], pixels_threshold=100, area_threshold=100, merge=True, margin=10):
img.draw_rectangle(blob.rect())
img.draw_cross(blob.cx(), blob.cy())
lcd.display(img)
print(clock.fps()) #打印帧率