使用OpenMV4 H7 PLUS摄像头进行红绿蓝三颜色的识别:
官网:https://book.openmv.cc
函数库:https://docs.singtown.com/micropython/zh/latest/openmvcam/library/omv.sensor.html?highlight=sensor#module-sensor
环境下载:https://openmv.io/pages/download
通过find_blobs函数可以找到色块.我们来讨论一下,find_blobs的细节。
image.find_blobs(thresholds, roi=Auto, x_stride=2, y_stride=1, invert=False, area_threshold=10, pixels_threshold=10, merge=False, margin=0, threshold_cb=None, merge_cb=None)
这里的参数比较多。
thresholds是颜色的阈值,注意:这个参数是一个列表,可以包含多个颜色。如果你只需要一个颜色,那么在这个列表中只需要有一个颜色值,如果你想要多个颜色阈值,那这个列表就需要多个颜色阈值。注意:在返回的色块对象blob可以调用code方法,来判断是什么颜色的色块。
red = (xxx,xxx,xxx,xxx,xxx,xxx)
blue = (xxx,xxx,xxx,xxx,xxx,xxx)
yellow = (xxx,xxx,xxx,xxx,xxx,xxx)
img=sensor.snapshot()
red_blobs = img.find_blobs([red])
color_blobs = img.find_blobs([red,blue, yellow])
roi是“感兴趣区”。roi的格式是(x, y, w, h)的tupple元组:
x:ROI区域中左上角的x坐标
y:ROI区域中左上角的y坐标
w:ROI的宽度
h:ROI的高度
left_roi = [0,0,160,240]
blobs = img.find_blobs([red],roi=left_roi)
x_stride 就是查找的色块的x方向上最小宽度的像素,默认为2,如果你只想查找宽度10个像素以上的色块,那么就设置这个参数为10:
blobs = img.find_blobs([red],x_stride=10)
y_stride 就是查找的色块的y方向上最小宽度的像素,默认为1,如果你只想查找宽度5个像素以上的色块,那么就设置这个参数为5:
blobs = img.find_blobs([red],y_stride=5)
invert 反转阈值,把阈值以外的颜色作为阈值进行查找
area_threshold 面积阈值,如果色块被框起来的面积小于这个值,会被过滤掉
pixels_threshold 像素个数阈值,如果色块像素数量小于这个值,会被过滤掉
merge 合并,如果设置为True,那么合并所有重叠的blob为一个。
注意:这会合并所有的blob,无论是什么颜色的。如果你想混淆多种颜色的blob,只需要分别调用不同颜色阈值的find_blobs。
all_blobs = img.find_blobs([red,blue,yellow],merge=True)
red_blobs = img.find_blobs([red],merge=True)
blue_blobs = img.find_blobs([blue],merge=True)
yellow_blobs = img.find_blobs([yellow],merge=True)
margin 边界,如果设置为1,那么两个blobs如果间距1一个像素点,也会被合并。
三原色的原理不是物理原因,而是由于人的生理原因造成的。人的眼睛内有几种辨别颜色的锥形感光细胞,分别对黄绿色、绿色和蓝紫色(或称紫罗兰色)的光最敏感(波长分别为564、534和420纳米)。
所以RGB经常用于显示器上,用来显示图片。
Lab颜色空间中,L亮度;a的正数代表红色,负端代表绿色;b的正数代表黄色,负端代表兰色。不像RGB和CMYK色彩空间,Lab颜色被设计来接近人类视觉。
因此L分量可以调整亮度对,修改a和b分量的输出色阶来做精确的颜色平衡。
注意:在OpenMV的查找色块的算法中,运用的就是这个LAB模式!
import sensor, image, time
#颜色识别LAB域值设定,可根据自己需求寻找次范围
red_threshold = (30, 100, 15, 127, 15, 127)
green_threshold = (20, 70, -127, -10, -64, 120)
blue_threshold = (10, 80, -96, 32, -100, -20)
sensor.reset() #初始化摄像头
sensor.set_pixformat(sensor.RGB565) #彩色方式
sensor.set_framesize(sensor.LCD) #设置图像像素模式
sensor.skip_frames(time = 2000) # 设置一定时间让新的设置生效。在更改设置后,跳过一些帧,等待感光元件变稳定。
sensor.set_auto_gain(False) # 颜色跟踪必须关闭自动增益
sensor.set_auto_whitebal(False) #关闭白平衡。
sensor.set_auto_exposure(False,33333) #设置曝光,需要更改
sensor.set_windowing((100,100)) #设置子分辨率
clock = time.clock() # 跟踪FPS帧率
def find_MaxBlob(colour_blobs):#获取找到颜色的最大值函数
max_size = 0
for blob in colour_blobs:
if blob[2]*blob[3] > max_size: #blob[2]*blob[3]为面积
max_Blob = blob
max_size = blob[2]*blob[3]
return max_Blob
while(True):
clock.tick() # 追踪两个snapshots()之间经过的毫秒数.
img = sensor.snapshot() # 拍一张照片并返回图像。
colour_blobs = img.find_blobs([red_threshold, green_threshold, blue_threshold], area_threshold=200)
#area_threshold=200为面积阀值可根据目标自由设置
#find_blobs(thresholds, invert=False, roi=Auto),thresholds为颜色阈值,
#是一个元组,需要用括号[ ]括起来。invert=1,反转颜色阈值,invert=False默认
#不反转。roi设置颜色识别的视野区域,roi是一个元组, roi = (x, y, w, h),代表
#从左上顶点(x,y)开始的宽为w高为h的矩形区域,roi不设置的话默认为整个图像视野。
#这个函数返回一个列表,[0]代表识别到的目标颜色区域左上顶点的x坐标,[1]代表
#左上顶点y坐标,[2]代表目标区域的宽,[3]代表目标区域的高,[4]代表目标
#区域像素点的个数,[5]代表目标区域的中心点x坐标,[6]代表目标区域中心点y坐标,
#[7]代表目标颜色区域的旋转角度(是弧度值,浮点型,列表其他元素是整型),
#[8]代表与此目标区域交叉的目标个数,[9]代表颜色的编号(它可以用来分辨这个
#区域是用哪个颜色阈值threshold识别出来的)。
if colour_blobs: #如果识别到颜色
max_Blob = find_MaxBlob(colour_blobs) #获取最大值
img.draw_cross(max_Blob[5], max_Blob[6]) # cx, cy 画出中心
print(max_Blob[8]) #获取颜色对应32位二进制转换的数值:1红、2绿、4蓝
else:
pass
print("FPS %f" % clock.fps()) # 注意: 当连接电脑后,OpenMV会变成一半的速度。当不连接电脑,帧率会增加。