一、颜色识别:
基础知识:
MaixPy集成了RGB565颜色识别find_blobs函数,主要是基于LAB颜色模型,其位于image模块下,因此直接对拍摄到的图片进行处理。
构造函数:
image.find_blobs(thresholds[, invert=False[, roi[, x_stride=2[, y_stride=1[, area_threshold=10[, pixels_threshold=10[, merge=False[, margin=0[, thresholds_cb=None[, merge_cb=None[, merge_cb=None]]]]]]]]]]):
功能:查找图像中指定的色块。返回image.blog对象列表:
· thresholds:必须是元组列表。[(lo,hi),···,(lo,hi)]定义想追踪的颜色范围。对于灰度图像,每个元组需要包含两个值(最小灰度值和最大灰度值)。若为RGB565彩色图像,每个元组需要有六个值(l_lo, l_hi, a_lo, a_hi, b_lo, b_hi)分别是LAB(L为亮度;a的正数为红,负数为绿;b的正数为黄,负数为蓝)L,A,B通道的最小值和最大值;
· area_threshold:若色块的边界框区域小于此参数,则会被过滤掉;
· pixels_threshold:若色块的像素数量小于此参数值,则会被过滤掉;
· merge:若为True,则合并所有没有被过滤的色块;
· margin:调整合并色块的边缘。
使用方法:以上函数返回image.blob。
blob.rect():
功能:返回一个矩形元组(x,y,w,h),如色块边界,可以通过索引[0,3]来获取这些参数。
blob.cx():
功能:返回色块(int)的中心x位置。可以通过索引5来获取这个值。
blob.cy():
功能:返回色块(int)的中心y位置。可以通过索引6来获取这个值。
如何获取LAB的元组:
如图在工具栏打开机器视觉中的阈值编辑器。
选择图像文件或者在运行摄像头时打开帧缓冲区(建议帧缓冲,因为摄像头的原因,差值会很大)。
该值为直接使用图像文件调出的LAB阈值。
该值为使用摄像头的帧缓冲区得到的LAB阈值
调整参数,使得你要查找的色块为白色其余为黑色,复制LAB阈值为元组。
颜色识别的运行结果。
为什么会产生那么大的误差,我认为是因为拍摄角度和摄像头的原因,导致了光照条件不同,而K210对颜色的识别会受到光照因素的较大影响,在实际使用时可以用LED灯进行补光来提供一个比较稳定的光照环境。
基础实验:查找色块
# 色块查找
import lcd
import sensor
import image
# 对摄像头进行设置
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.set_vflip(1)
# 初始化lcd
lcd.init()
# 颜色识别,该值由阈值编辑器得出
thresholds = (26, 100, -39, -5, -14, 127)
while True:
img = sensor.snapshot().lens_corr(1.8) # 建立图像,将摄像头拍摄画面赋值给它并进行矫正
blobs = img.find_blobs([thresholds]) # 查找色块,返回image.blob类型的元组
if blobs: # 判断是否存在blobs,若存在,则运行
for b in blobs: # 将blobs元组内的值一一赋值给b,进行循环
tmp = img.draw_rectangle(b[0:4]) # 画矩阵框住色块边界
tmp = img.draw_cross(b[5], b[6]) # 画十字,标注色块中心
lcd.display(img)
运行结果如图所示
二、二维码识别:
基础知识:
构造函数:
image.find_qrcodes([roi]):
功能:查找roi区域内的所有二维码并返回一个image.qrcode的对象列表。
使用方法:以上函数返回image.qrcode对象列表
qrcode.rect():
功能:返回一个矩形元组(x,y,w,h)。
qrcode.payload():
功能:返回二维码字符串信息。可以通过索引4来获得这个值。
qrcode.version():
功能:返回二维码版本号。
生成二维码的方式:
可以使用草料二维码生成。草料二维码生成器 (cli.im)
基础实验:
# 二维码识别
# 导入模板
import lcd
import sensor
import image
# 设置摄像头
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.set_vflip(1)
sensor.skip_frames()
# 初始化lcd
lcd.init()
while True:
img = sensor.snapshot()
res = img.find_qrcodes() # 寻找二维码
if len(res) > 0: # 加入列表中不止一个二维码
img.draw_rectangle(res[0].rect()) # 在第一个二维码处绘制一个矩形,将该二维码框出
img.draw_string(2,2,res[0].payload(),color=(0,128,0),scale=2) # 在(2,2)处返回出二维码内的字符
print(res[0].payload()) # 在串口终端上打印出二维码内蕴含的字符
lcd.display(img)
上述代码只适用于英文二维码,下给出识别中文二维码的方法。
拓展:中文二维码的识别
首先要先准备号中文的字库,K210并没有内置,所以如果直接用上述代码能将二维码框出,但二维码的内容显示不出会显示一个小框在应该出现字符的位置。将字库通过SD卡读取器,将字库放入SD卡中,在上述程序中将字库导入变可以实现识别中文二维码了。
如何获得中文字库这边不展开,给出官方链接:如何显示中文 - Sipeed Wiki
# 二维码识别
# 导入模板
import lcd
import sensor
import image
# 设置摄像头
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.set_vflip(1)
sensor.skip_frames()
# 初始化lcd
lcd.init()
image.font_load(image.UTF8, 16, 16, '/sd/language/songti.Dzk')
while True:
img = sensor.snapshot().lens_corr(1.8)
res = img.find_qrcodes() # 寻找二维码
if len(res) > 0: # 加入列表中不止一个二维码
img.draw_rectangle(res[0].rect()) # 在第一个二维码处绘制一个矩形,将该二维码框出
img.draw_string(10,2,res[0].payload(),color=(0,128,0),scale=2) # 在(2,2)处返回出二维码内的字符
print(res[0].payload()) # 在串口终端上打印出二维码内蕴含的字符
lcd.display(img)