0


【K210】K210学习笔记二——image

【K210】K210学习笔记二——image

前言

本人大四学生,电赛生涯已经走到尽头,一路上踩过不少坑,但运气也不错拿了两年省一,思来想去,决定开始写博客,将电赛经验分享一二,能力有限,高手轻喷。
本篇主要是介绍 K210 上的 image 机器视觉模块。如果你要使用 K210 来进行一些颜色追踪(比如识别黑色,传回坐标让小车寻线,或者是识别其他颜色的线),那么你首先要做的就是将 sensor 配置好,如果配置不好,会直接影响颜色追踪的效果。
sensro的配置可以看我上一篇学习笔记,传送门
【K210】K210学习笔记一——sensor
如果你配置完了,就可以接着学习如何用 image 模块做一些事情啦!
本文着重于 image 模块中的一个函数 find_blobs 也就是寻找色块的函数,因为多次比赛使用下来,给我的感觉就是 image 模块中最好用的便是寻找色块这个函数。其他的函数做的都比较差(个人感觉),比如识别形状的那几个函数,但其实找色块也是可以识别形状的。我这两年来做无人机题的识别都靠的是这一个函数,另外这两年的小车题靠这个函数也是可以的,只要你懂得怎么处理,我就分享一下我的使用心得,另外这个作为 image 模块的使用贴,后续如果我发现了其他函数有什么好用之处,也会在这里更新。

寻找色块相关类和函数定义

类定义

这里定义了颜色属性类,主要是用于保存找到的色块的一些信息,以及色块的阈值,寻找区域等信息。

#__________________________________________________________________# 寻找色块# 定义类classcolor_property():
    cx                      =0# 色块 x轴 中心坐标
    cy                      =0# 色块 y轴 中心坐标
    flag                    =0# 色块标志位 1 找到 0 未找到
    color                   =0# 色块颜色标志位 例如 你可以用 1 来表示 黑色
    density                 =0# 色块密度比 反映色块锁定程度 值越大 锁定程度越好
    pixels_max              =0# 色块像素最大值
    led_flag                =0# LED标志位 方便调试用

    color_threshold         =(0,0,0,0,0,0)# 色块颜色阈值
    color_roi               =(0,0,320,240)# 色块寻找区域(感兴趣区域)
    color_x_stride          =1# 色块 x轴 像素最小宽度 色块如果比较大可以调大此参数 提高寻找速度
    color_y_stride          =1# 色块 y轴 像素最小宽度 色块如果比较大可以调大此参数 提高寻找速度
    color_pixels_threshold  =100# 色块 像素个数阈值 例如调节此参数为100 则可以滤除色块像素小于100的色块
    color_area_threshold    =100# 色块 被框面积阈值 例如调节此参数为100 则可以滤除色块被框面积小于100的色块
    color_merge             =True# 是否合并寻找到的色块 True 则合并 False 则不合并
    color_margin            =1# 色块合并间距 例如调节此参数为1 若上面选择True合并色块 且被找到的色块有多个 相距1像素 则会将这些色块合并

实例化类

这里我实例化了4个类,分别是黑色、红色、绿色、蓝色。举例我只举例两个,一个是找黑色色块(我在无人机上用这个方法找到黑色降落点),一个是找红色线(去年小车题就可以找红线),绿色和蓝色预留。当然你也可以依据你的需要定义找其他颜色。

# 实例化类# 黑色
black = color_property()
black.color_threshold         =(0,50,-10,10,-10,10)
black.color_roi               =(0,0,320,240)
black.color_x_stride          =1
black.color_y_stride          =1
black.color_pixels_threshold  =100
black.color_area_threshold    =100
black.color_merge             =True
black.color_margin            =1# 红色
red   = color_property()
red.color_threshold           =(0,100,20,127,-5,127)#red.color_roi                = (0,0,320,240)
red.color_roi                 =(0,110,320,20)

red.color_x_stride            =1
red.color_y_stride            =1#red.color_pixels_threshold   =  100#red.color_area_threshold     =  100
red.color_pixels_threshold    =10
red.color_area_threshold      =10

red.color_merge               =True
red.color_margin              =1# 绿色 预留
green = color_property()# 蓝色 预留
blue  = color_property()

类中各参数的设置

黑色设置

第一个参数 black.color_threshold 是设置黑色的阈值,可由阈值编辑器得到(直接在阈值编辑器中复制,然后粘贴到 black.color_threshold = 后面,覆盖掉原来的阈值即可)。阈值这个参数不是万能的,要依据个人实际情况进行设置,最准确的就是上电运行,将摄像头对着被追踪物体,然后停止运行,打开阈值编辑器取阈值。
第二个参数是设置色块寻找区域,对于 QVGA ,全屏寻找就设置成(0,0,320,240),这四个参数分别代表的是x,y,w,h,即x轴开始坐标,y轴开始坐标,x轴宽度,y轴高度。x轴和y轴的零点坐标都在图像的左上方。这个值略微修改就可以摇身一变,让寻找色块变成巡线。比如你可以设置这个值为(0,110,320,20),就表示你要从x轴的0坐标开始,到x轴的320,y轴的110坐标开始,到y轴的130,寻找色块,这样一来,就可以知道小车的当前位置是在x轴哪里,x轴中心是160,如果当前位置小于160,就左转,大于160,就右转,这样就可以完成巡线。
第三和第四个参数是设置色块x轴、y轴上像素的最小宽度,如果被寻找的目标比较大,可以调大这两个参数提高寻找速度。
第五个参数 black.color_pixels_threshold 是设置被找色块像素的个数阈值,如果被找到的色块像素个数少于这个值,将会被滤除,这是作为一种辅助手段,排除环境干扰的好方法。
第六个参数 black.color_area_threshold 是设置被找色块被框面积的个数阈值,如果被找到的色块被框面积少于这个值,将会被滤除,这是作为一种辅助手段,排除环境干扰的好方法。
第七个参数 black.color_merge 是需不需要合并找到的像素,一般都是需要的。
第八个参数 black.color_margin 是控制色块合并间距,例如调节此参数为1,若上面选择True合并色块且被找到的色块有多个,它们之间如果相距1像素,则会将这些色块合并。

# 实例化类# 黑色
black = color_property()
black.color_threshold         =(0,50,-10,10,-10,10)
black.color_roi               =(0,0,320,240)
black.color_x_stride          =1
black.color_y_stride          =1
black.color_pixels_threshold  =100
black.color_area_threshold    =100
black.color_merge             =True
black.color_margin            =1

阈值编辑器打开方式,源图像位置来自帧缓冲区。
在这里插入图片描述
阈值编辑器的使用方法很简单,拖动进度条改变 LAB 阈值即可,白色是被追踪的颜色阈值,保证白色尽量集中在被追踪的物体上即可。
在这里插入图片描述

红色设置

各参数的设置原因已经在黑色设置中说明了,通过对比我们可以发现,相对于黑色,红色这里的设置是将阈值改成了红色阈值,压缩了y轴的感兴趣区域,调小了滤除色块的参数,如果用于巡红线,就可以获取红线的位置信息。

# 红色
red   = color_property()
red.color_threshold           =(0,100,20,127,-5,127)#red.color_roi                = (0,0,320,240)
red.color_roi                 =(0,110,320,20)

red.color_x_stride            =1
red.color_y_stride            =1#red.color_pixels_threshold   =  100#red.color_area_threshold     =  100
red.color_pixels_threshold    =10
red.color_area_threshold      =10

red.color_merge               =True
red.color_margin              =1

寻找色块函数定义

这里定义了寻找色块的函数,使用的时候将实例类传入即可。led_flag是为了方便脱机运行的时候判断识别效果,后续文章会介绍到怎么用,这里先定义。

# 定义寻找色块函数defopv_find_blobs(color,led_flag):
    color.pixels_max =0# 重置 色块 最大像素数量
    color.flag       =0# 重置 色块 标志位
    color.led_flag   =0# 重置 led 标志位for blobs in img.find_blobs([color.color_threshold],# 色块颜色阈值
    roi = color.color_roi,# 色块寻找区域(感兴趣区域)
    x_stride = color.color_x_stride,# 色块 x轴 像素最小宽度 色块如果比较大可以调大此参数 提高寻找速度
    y_stride = color.color_y_stride,# 色块 y轴 像素最小宽度 色块如果比较大可以调大此参数 提高寻找速度
    pixels_threshold = color.color_pixels_threshold,# 色块 像素个数阈值 例如调节此参数为100 则可以滤除色块像素小于100的色块
    area_threshold = color.color_area_threshold,# 色块 被框面积阈值 例如调节此参数为100 则可以滤除色块被框面积小于100的色块
    merge = color.color_merge,# 是否合并寻找到的色块 True 则合并 False 则不合并
    margin = color.color_margin):# 色块合并间距 例如调节此参数为1 若上面选择True合并色块 且被找到的色块有多个 相距1像素 则会将这些色块合并
        img.draw_rectangle(blobs[0:4])# 圈出找到的色块if color.pixels_max < blobs.pixels():# 找到面积最大的色块
            color.pixels_max = blobs.pixels()
            color.cx = blobs.cx()# 将面积最大的色块的 x轴 中心坐标值 赋值给 color
            color.cy = blobs.cy()# 将面积最大的色块的 y轴 中心坐标值 赋值给 color
            color.flag =1# 标志画面中有找到色块
            color.density = blobs.density()# 将面积最大的色块的 色块密度比 赋值给 color
            color.led_flag = led_flag                       # 将控制led颜色的标志位的值 赋值给 colorif color.flag ==1:# 标记画面中被找到的最大色块的中心坐标
        img.draw_cross(color.cx,color.cy, color=127, size =15)
        img.draw_circle(color.cx,color.cy,15, color =127)

测试寻找色块

测试寻找色块之前,需要定义一个函数,用来打印被寻找到的色块信息,方便调试使用。

# 定义打印色块参数函数defprint_blobs_property(color,name):print(name,"cx:",color.cx,"cy:",color.cy,"flag:",color.flag,"color:",color.color,"density:",color.density,"led_flag:",color.led_flag)

主函数如下所示,这里寻找两个色块,一个是寻找黑色色块,另一个是寻找红线,然后间隔一定时间,将结果打印出来。

#__________________________________________________________________# 主函数while(True):

    clock.tick()# 跟踪运行时间

    img = sensor.snapshot()# 拍摄一张照片
    opv_find_blobs(black,1)# 找黑色色块 led标志为1 表示黑色
    opv_find_blobs(red,2)# 找红色色块 led标志为2 表示红色if mycnt ==0:# 如果 mycnt 等于 0 此步骤的目的是控制打印周期 不要打印的太快
        mycnt =1# 将 1 赋值给 mycnt 使下一次不再满足 mycnt == 0 进入 elif
        print_sensor()# 打印sensor参数
        print_blobs_property(black,"Black-")# 打印黑色色块参数
        print_blobs_property(red,"Red-  ")# 打印红色色块参数elif mycnt < mycnt_max:# 计数变量 小于 计数上限 则 计数变量 自增
        mycnt = mycnt +1else:# 计数变量 超出 计数上限 则 将0赋值给 mycnt 使下一次进入 if
        mycnt =0

黑色色块测试结果,可以看到寻找效果还不错。
在这里插入图片描述
红线测试效果,可以看到寻找效果还不错。
在这里插入图片描述
在这里插入图片描述

完整源码

完整源码如下所示,大家可以复制该源码,进行测试,下一次学习笔记将会记录K210按键的配置、LED的配置、LCD显示屏的配置,我们下期再见~!

# image_V1.0 - By: FITQY - 周一 8 月 22 日 2022#__________________________________________________________________# 导入模块import sensor, time, image                                  # 导入感光元件模块 sensor 跟踪运行时间模块 time 机器视觉模块 image#__________________________________________________________________# 感光元件设置
sensor.reset()# 重置并初始化感光元件 默认设置为 摄像头频率 24M 不开启双缓冲模式#sensor.reset(freq=24000000, dual_buff=True)                # 设置摄像头频率 24M 开启双缓冲模式 会提高帧率 但内存占用增加

sensor.set_pixformat(sensor.RGB565)# 设置图像格式为 RGB565 (彩色) 除此之外 还可设置格式为 GRAYSCALE 或者 YUV422
sensor.set_framesize(sensor.QVGA)# 设置图像大小为 QVGA (320 x 240) 像素个数 76800 K210最大支持格式为 VGA

sensor.set_auto_exposure(1)# 设置自动曝光#sensor.set_auto_exposure(0, exposure=120000)               # 设置手动曝光 曝光时间 120000 us

sensor.set_auto_gain(0, gain_db =12)# 设置画面增益 17 dB 影响实时画面亮度
sensor.set_auto_whitebal(0, rgb_gain_db =(0,0,0))# 设置RGB增益 0 0 0 dB 影响画面色彩呈现效果 在 K210 上无法调节增益 初步判定是感光元件 ov2640 无法支持#sensor.set_contrast(0)                                     # 设置对比度 0 这个参数无法读取 且调这个参数对画面似乎不会产生影响 暂时注释#sensor.set_brightness(0)                                   # 设置亮度 0 这个参数无法读取 且调这个参数对画面似乎不会产生影响 暂时注释#sensor.set_saturation(0)                                   # 设置饱和度 0 这个参数无法读取 且调这个参数对画面似乎不会产生影响 暂时注释

sensor.set_vflip(1)# 打开垂直翻转 如果是 01Studio 的 K210 不开启会导致画面方向与运动方向相反
sensor.set_hmirror(1)# 打开水平镜像 如果是 01Studio 的 K210 不开启会导致画面方向与运动方向相反

sensor.skip_frames(time =2000)# 延时跳过2s 等待感光元件稳定#__________________________________________________________________# 创建时钟对象
clock = time.clock()# 创建时钟对象 clock#__________________________________________________________________# 寻找色块# 定义类classcolor_property():
    cx                      =0# 色块 x轴 中心坐标
    cy                      =0# 色块 y轴 中心坐标
    flag                    =0# 色块标志位 1 找到 0 未找到
    color                   =0# 色块颜色标志位 例如 你可以用 1 来表示 黑色
    density                 =0# 色块密度比 反映色块锁定程度 值越大 锁定程度越好
    pixels_max              =0# 色块像素最大值
    led_flag                =0# LED标志位 方便调试用

    color_threshold         =(0,0,0,0,0,0)# 色块颜色阈值
    color_roi               =(0,0,320,240)# 色块寻找区域(感兴趣区域)
    color_x_stride          =1# 色块 x轴 像素最小宽度 色块如果比较大可以调大此参数 提高寻找速度
    color_y_stride          =1# 色块 y轴 像素最小宽度 色块如果比较大可以调大此参数 提高寻找速度
    color_pixels_threshold  =100# 色块 像素个数阈值 例如调节此参数为100 则可以滤除色块像素小于100的色块
    color_area_threshold    =100# 色块 被框面积阈值 例如调节此参数为100 则可以滤除色块被框面积小于100的色块
    color_merge             =True# 是否合并寻找到的色块 True 则合并 False 则不合并
    color_margin            =1# 色块合并间距 例如调节此参数为1 若上面选择True合并色块 且被找到的色块有多个 相距1像素 则会将这些色块合并# 实例化类# 黑色
black = color_property()
black.color_threshold         =(0,50,-10,10,-10,10)
black.color_roi               =(0,0,320,240)
black.color_x_stride          =1
black.color_y_stride          =1
black.color_pixels_threshold  =100
black.color_area_threshold    =100
black.color_merge             =True
black.color_margin            =1# 红色
red   = color_property()
red.color_threshold           =(0,100,20,127,-10,127)#red.color_roi                = (0,0,320,240)
red.color_roi                 =(0,110,320,20)

red.color_x_stride            =1
red.color_y_stride            =1#red.color_pixels_threshold   =  100#red.color_area_threshold     =  100
red.color_pixels_threshold    =10
red.color_area_threshold      =10

red.color_merge               =True
red.color_margin              =1# 绿色 预留
green = color_property()# 蓝色 预留
blue  = color_property()# 定义寻找色块函数defopv_find_blobs(color,led_flag):
    color.pixels_max =0# 重置 色块 最大像素数量
    color.flag       =0# 重置 色块 标志位
    color.led_flag   =0# 重置 led 标志位for blobs in img.find_blobs([color.color_threshold],# 色块颜色阈值
    roi = color.color_roi,# 色块寻找区域(感兴趣区域)
    x_stride = color.color_x_stride,# 色块 x轴 像素最小宽度 色块如果比较大可以调大此参数 提高寻找速度
    y_stride = color.color_y_stride,# 色块 y轴 像素最小宽度 色块如果比较大可以调大此参数 提高寻找速度
    pixels_threshold = color.color_pixels_threshold,# 色块 像素个数阈值 例如调节此参数为100 则可以滤除色块像素小于100的色块
    area_threshold = color.color_area_threshold,# 色块 被框面积阈值 例如调节此参数为100 则可以滤除色块被框面积小于100的色块
    merge = color.color_merge,# 是否合并寻找到的色块 True 则合并 False 则不合并
    margin = color.color_margin):# 色块合并间距 例如调节此参数为1 若上面选择True合并色块 且被找到的色块有多个 相距1像素 则会将这些色块合并
        img.draw_rectangle(blobs[0:4])# 圈出找到的色块if color.pixels_max < blobs.pixels():# 找到面积最大的色块
            color.pixels_max = blobs.pixels()
            color.cx = blobs.cx()# 将面积最大的色块的 x轴 中心坐标值 赋值给 color
            color.cy = blobs.cy()# 将面积最大的色块的 y轴 中心坐标值 赋值给 color
            color.flag =1# 标志画面中有找到色块
            color.density = blobs.density()# 将面积最大的色块的 色块密度比 赋值给 color
            color.led_flag = led_flag                       # 将控制led颜色的标志位的值 赋值给 colorif color.flag ==1:# 标记画面中被找到的最大色块的中心坐标
        img.draw_cross(color.cx,color.cy, color=127, size =15)
        img.draw_circle(color.cx,color.cy,15, color =127)# 定义打印色块参数函数defprint_blobs_property(color,name):print(name,"cx:",color.cx,"cy:",color.cy,"flag:",color.flag,"color:",color.color,"density:",color.density,"led_flag:",color.led_flag)#__________________________________________________________________# 打印sensor参数defprint_sensor():print("Exposure: "+str(sensor.get_exposure_us()))# 打印 曝光时间print("Gain: "+str(sensor.get_gain_db()))# 打印 画面增益print("RGB: "+str(sensor.get_rgb_gain_db()))# 打印 RGB 增益#__________________________________________________________________# 调试区
mycnt       =0# 计数变量
mycnt_max   =30# 计数上限 此值越大 计数周期越长#__________________________________________________________________# 主函数while(True):

    clock.tick()# 跟踪运行时间

    img = sensor.snapshot()# 拍摄一张照片
    opv_find_blobs(black,1)# 找黑色色块 led标志为1 表示黑色
    opv_find_blobs(red,2)# 找红色色块 led标志为2 表示红色if mycnt ==0:# 如果 mycnt 等于 0 此步骤的目的是控制打印周期 不要打印的太快
        mycnt =1# 将 1 赋值给 mycnt 使下一次不再满足 mycnt == 0 进入 elif
        print_sensor()# 打印sensor参数
        print_blobs_property(black,"Black-")# 打印黑色色块参数
        print_blobs_property(red,"Red-  ")# 打印红色色块参数elif mycnt < mycnt_max:# 计数变量 小于 计数上限 则 计数变量 自增
        mycnt = mycnt +1else:# 计数变量 超出 计数上限 则 将0赋值给 mycnt 使下一次进入 if
        mycnt =0#__________________________________________________________________

本文转载自: https://blog.csdn.net/adas323/article/details/126469467
版权归原作者 欠羽 所有, 如有侵权,请联系我们删除。

“【K210】K210学习笔记二——image”的评论:

还没有评论