# 摄像头初始化函数
def set_sensor():
sensor.reset() # 重置感光元件,重置摄像机
sensor.set_pixformat(sensor.RGB565) # 设置颜色格式为RGB565,彩色,每个像素16bit。
sensor.set_framesize(sensor.QQVGA) # 图像大小为QQVGA
sensor.skip_frames(time=10) # 跳过n张照片,在更改设置后,跳过一些帧,等待感光元件变稳定。
sensor.set_auto_gain(False) # 颜色识别必须关闭自动增益,会影响颜色识别效果
sensor.set_auto_whitebal(False) # 颜色识别必须关闭白平衡,会影响颜色识别效果,导致颜色的阈值发生改变
sensor.set_auto_exposure(False) #只是禁用曝光值更新,但不会更改相机传感器确定的曝光值。
#clock = time.clock()
找到最大面积的色块对应的颜色
对最大色块的方形区域进行判断,即不仅包括目标颜色
def find_max(blobs):
max_size = 0
for blob in blobs:
if blob[2]*blob[3] > max_size:
max_blob = blob#最大的颜色
max_size = blob[2]*blob[3]#w*h,最大色块的面积
return max_blob
主代码
clock.tick()
img = sensor.snapshot()
blobs = img.find_blobs([threshold_1])#查找图像中所有色块,并返回一个包括每个色块的色块对象的列表,thresholds 必须是元组列表,定义你想追踪的颜色范围
blobs1 = img.find_blobs([threshold_2])#进行两次颜色采样
if blobs: #如果找到了目标颜色
blob = find_max(blobs)#找到所有目标颜色中最大的色块区域
if ((blob.cx() in range(60, 110)) and (blob.cy() in range(40, 90))):#判断目标是否在摄像头指定区域
#density()返回这个色块的密度比。这是在色块边界框区域内的像素点的数量。
#总的来说,较低的密度比意味着这个对象的锁定得不是很好。 结果在0和1之间。
#即判断目标颜色所在(blob.cx(), blob.cy(),blob.cw(), blob.ch())的矩形区域中的所占面积,即密度,0.0~1.0
if 0.285 0.8:#判断是否是圆
# 这些值始终是稳定的。
img.draw_rectangle(blob.rect()) # 用矩形标记出目标颜色区域
img.draw_cross(blob.cx(), blob.cy()) # 在目标颜色区域的中心画十字形标记
# 注意blob的旋转是唯一的0-180。
在没有测距模块时,可利用小孔成像原理判断大致距离
K=5000#随实际测量数据改变
x = blob[0]
y = blob[1]
width = blob[2]
height = blob[3]
# Draw a rect around the blob.
img.draw_rectangle([x, y, width, height]) # rect
# 用矩形标记出目标颜色区域
img.draw_cross(blob[5], blob[6]) # cx, cy
# 在目标颜色区域的中心画十字形标记
Lm = (blob[2] + blob[3]) / 2 # b[2]色块的外框的宽 ,b[3]色块的外框的高
pixels = blob[4] # 色块的像素数量
length = K / Lm#利用小孔成像原理判断大致距离
对于blobs=img.find_blobs(threshold_1,pixels_threshold=400,area_threshold=5,x_stride=1, y_stride=1, margin=False)
x_stride
是查找某色块时需要跳过的x像素的数量。找到色块后,直线填充算法将精确像素。 若已知色块较大,可增加 x_stride
来提高查找色块的速度,y_stride
同理
若一个色块的边界框区域小于 area_threshold
,则会被过滤掉。
若一个色块的像素数小于 pixel_threshold
,则会被过滤掉。
merge
若为True,则合并所有没有被过滤掉的色块,这些色块的边界矩形互相交错重叠。
margin
可在相交测试中用来增大或减小色块边界矩形的大小。例如:边缘为1、相互间边界矩形为1的色块将被合并。
合并色块使颜色代码追踪得以实现。每个色块对象有一个代码值 code
,该值为一个位向量。 例如:若您在image.find_blobs中输入两个颜色阈值,则第一个阈值代码为1,第二个代码为2(第三个代码为4,第四个代码为8,以此类推)。 合并色块对所有的code使用逻辑或运算,以便您知道产生它们的颜色。这使得您可以追踪两个颜色,若您用两种颜色得到一个色块对象,则可能是一种颜色代码。
若您使用严格的颜色范围,无法完全追踪目标对象的所有像素,您可能需要合并色块。
最后,若您想要合并色块,但不想两种不同阈值颜色的色块被合并,只需分别两次调用 image.find_blobs
,不同阈值色块就不会被合并。
blob=image.find_blobs()返回值
blob.rect() 返回这个色块的外框——矩形元组(x, y, w, h),可以直接在image.draw_rectangle中使用。
blob.x()返回色块的边界框的x坐标(int)。您也可以通过索引 [0]
取得这个值。左上角
blob.y()返回色块的边界框的y坐标(int)。您也可以通过索引 [1]
取得这个值。左上角
blob.w()返回色块的边界框的w坐标(int)。您也可以通过索引 [2]
取得这个值。左上角,向右为+
blob.h()返回色块的边界框的h坐标(int)。您也可以通过索引 [3]
取得这个值。左上角,向下为+
blob.pixels()返回从属于色块(int)一部分的像素数量。您也可以通过索引 [4]
取得这个值。
blob.cx()返回色块(int)的中心x位置。您也可以通过索引 [5]
取得这个值。
blob.cy()返回色块(int)的中心y位置。您也可以通过索引 [6]
取得这个值。
blob.rotation() 返回色块的旋转角度(单位为弧度)(float)。如果色块类似一个铅笔,那么这个值为0~180°。如果色块是一个圆,那么这个值是无用的。如果色块完全没有对称性,那么你会得到0~360°,也可以通过blob[7]来获取。
blob.code() 返回一个16bit数字,每一个bit会对应每一个阈值。举个例子:
blobs = img.find_blobs([red, blue, yellow], merge=True)
如果这个色块是黄色,那么它的code就是0001,如果是红色,那么它的code就是0010。注意:一个blob可能是合并的,如果是红色和蓝色的blob,那么这个blob就是0011。这个功能可以用于查找颜色代码。也可以通过blob[8]来获取。
blob.count() 如果merge=True,那么就会有多个blob被合并到一个blob,这个函数返回的就是这个的数量。如果merge=False,那么返回值总是1。也可以通过blob[9]来获取。
blob.area() 返回色块的外框的面积。应该等于(w * h)
blob.density() 返回色块的密度。这等于色块的像素数除以矩形框的面积。如果密度较低,那么说明目标锁定的不是很好。
比如,识别一个红色的圆,返回的blob.pixels()是目标圆的像素点数,blob.area()是圆的外接正方形的面积
如果我们需要选择两种颜色,则需要拼接这两个阈值,使用pixels和area综合来过滤掉细小的像素识别。
blobs = img.find_blobs([green_threshold,red_threshold],pixels_threshold = 24,area_threshold = 5,merge = True)
图形判断
。。。。。。
。。。。。。
。。。。。。