K210视觉识别模块学习笔记9:三ROI区域识别最大色块及中点

今日学习K210视觉识别模块: 三ROI区域识别最大色块及中点

亚博智能      K210视觉识别模块......  

固件库:        canmv_yahboom_v2.1.1.bin

 本文只简单编写记录一下如何编程使用3个ROI区域识别最大黑色块及其中点,可用于巡线

 文章提供测试代码讲解、完整代码贴出、测试效果图

目录

代码展示:

几种巡线情况的测试效果图与建议:

直线

斜线:

转弯:

路口:

网上学习资料贴出:


代码展示:

这个代码展示了先将摄像头转化为灰度模式,当然也可注释掉while True 循环之前打开灰度的语句,只是灰度模式更适合寻迹黑线

摄像头采集像素设置为  320*240  

设置了三个ROI区域检测黑色色块,它们X轴边长都是(0~320)全范围,就Y轴起点不同

分别为(60,120,180),然后它们框的区域都是16个像素的Y轴区域

其中每个识别到的中点都能输出(但语句被注释)

目前如果你也是亚博智能的K210并且固件库与我一致的话,这个程序可以直接运行的,不需要更改,但我建议接着往下看,复制使用文章靠后部分改进后的程序

import sensor, image, time, lcd
from machine import UART
from fpioa_manager import fm
 
# 初始化摄像头和串口
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.HQVGA)
sensor.skip_frames(time=2000)
sensor.set_vflip(0)#设置摄像头上下翻转模式

#lcd.init(freq=15000000)
sensor.set_pixformat(sensor.GRAYSCALE) #灰度模式(方便循黑线),可以注释掉方便以后用来循其余颜色的线..
sensor.set_framesize(sensor.QVGA)  # 设置图像帧大小为320x240

fm.register(6, fm.fpioa.UART1_RX, force=True)
fm.register(7, fm.fpioa.UART1_TX, force=True)
uart = UART(UART.UART1, 115200, read_buf_len=4096)

# 定义阈值和颜色范围
thresholds_1 = [(0, 38, -60, 111, -76, 97)]  #黑色

roi1 = [0, 60, 320, 16]   # 巡线敏感区域1
roi2 = [0, 120, 320, 16]   # 巡线敏感区域2
roi3 = [0, 180, 320, 16]  # 巡线敏感区域3

 
while True:
    img = sensor.snapshot()#使用摄像机拍摄一张图片并返回给img后续进行操作
    lcd.display(img)  # 将图像用LCD显示
 
    # 查找所有黑色色块   area_threshold是过滤小的,自己可以改    pixels_threshold像素的最小数量
    #blobs_1 = img.find_blobs(thresholds_1, pixels_threshold=100, area_threshold=100)
    
    # 在roi1区域内寻找绿色区域的统计数据(用于巡线1)
    statistics1 = img.find_blobs(thresholds_1, roi=roi1, area_threshold=200, merge=True)
    # 在roi2区域内寻找绿色区域的统计数据(用于巡线2), margin=120
    statistics2 = img.find_blobs(thresholds_1, roi=roi2, area_threshold=200, merge=True)
    # 在roi3区域内寻找绿色区域的统计数据(用于巡线2), margin=120
    statistics3 = img.find_blobs(thresholds_1, roi=roi3, area_threshold=200, merge=True)   
    
    if statistics1:  # 如果在roi1区域找到黑色区域
      for b in statistics1:
        #绘制框出黑色区域的矩形框
        actualValue = b[5]  # 获取当前黑区域的中心位置   
        max_blob1 = max(statistics1, key=lambda b: b.pixels())
        # 绘制矩形框
        img.draw_rectangle(max_blob1.rect(),color=(0,255,0),scale=2)
        #中心点XY 并 画十字
        img.draw_cross(max_blob1.cx(), max_blob1.cy())
 
        # 计算中心位置并向串口发送数据
        #x1 = max_blob1.cx()
        #y1 = max_blob1.cy()
        #data = bytearray([0xb3,0xb3,x1,y1,0x0c,0x0d,0x0a]) # 要发送的数据,对应串口接收中断需要设置头尾判断
        #uart.write(data)  # 发送数据
        #print(x1, y1)
        
    if statistics2:  # 如果在roi2区域找到黑色区域
      for b in statistics2:
        actualValue = b[5]  # 获取当前黑区域的中心位置   
        max_blob2 = max(statistics2, key=lambda b: b.pixels())
            # 绘制矩形框
        img.draw_rectangle(max_blob2.rect(),color=(0,255,255),scale=2)
        #中心点XY
        img.draw_cross(max_blob2.cx(), max_blob2.cy())
 
        # 计算中心位置并向串口发送数据
        #x2 = max_blob2.cx()
        #y2 = max_blob2.cy()
        #data = bytearray([0xb3,0xb3,x2,y2,0x0c,0x0d,0x0a]) # 要发送的数据,对应串口接收中断需要设置头尾判断
        #uart.write(data)  # 发送数据
        #print(x2, y2)  
          
    if statistics3:  # 如果在roi3区域找到黑色区域
      for b in statistics3:
        actualValue = b[5]  # 获取当前黑区域的中心位置
        max_blob3 = max(statistics3, key=lambda b: b.pixels())
            # 绘制矩形框
        img.draw_rectangle(max_blob3.rect(),color=(0,0,255),scale=2)
        #中心点XY
        img.draw_cross(max_blob3.cx(), max_blob3.cy())
 
        # 计算中心位置并向串口发送数据
        #x3 = max_blob3.cx()
        #y3 = max_blob3.cy()
        #data = bytearray([0xb3,0xb3,x3,y3,0x0c,0x0d,0x0a]) # 要发送的数据,对应串口接收中断需要设置头尾判断
        #uart.write(data)  # 发送数据
        #print(x3, y3) 
   # lcd.rotation(2)
    lcd.display(img)  # 将img,也就是那帧图像用lcd显示

几种巡线情况的测试效果图与建议:

直线

三点坐标连线斜率为0,小车俩边轮子差速建议一致

斜线:

三点斜率不为0,但中间的X2满足落在X1与X3组成的直线一次函数关系

转弯:

三点斜率不为0,中间的X2也不满足落在X1与X3组成的直线一次函数关系

路口:

X1\X2\X3在一条直线,但X1 的ROI区域识别到的色块已经占满ROI区域(>75%)

其余ROI区域对黑线的识别 还未发生这种突变

程序改进:

如果你也是亚博智能的K210并且固件库与我一致的话 :也是直接复制就能使用的程序,新增一些功能,以及改进串口程序\

界面显示:

三个Roi同步在屏幕上打印识别到色块中心点的坐标

串口程序:

之前的程序串口没有测试,其实是没法用的,这次改进后就能用了

LCD程序:

之前忘记添加初始化LCD的程序了,导致在canmv测试没啥问题,但将main.py程序放在SD卡让其执行时能正常运行返回坐标,但LCD不显示,现已解决

import sensor, image, time, lcd
from machine import UART
from fpioa_manager import fm
from modules import ybserial #从modules导入ybserial
 
# 初始化摄像头和串口
lcd.init() # 初始化LCD显示屏
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.HQVGA)
sensor.skip_frames(time=2000)
sensor.set_vflip(0)#设置摄像头上下翻转模式
 
#lcd.init(freq=15000000)
sensor.set_pixformat(sensor.GRAYSCALE) #灰度模式(方便循黑线),可以注释掉方便以后用来循其余颜色的线..
sensor.set_framesize(sensor.QVGA)  # 设置图像帧大小为320x240
 
#fm.register(6, fm.fpioa.UART1_RX, force=True)
#fm.register(7, fm.fpioa.UART1_TX, force=True)
#uart = UART(UART.UART1, 115200, read_buf_len=4096)

serial = ybserial() #创建ybserial的对象,并命名为serial
 
# 定义阈值和颜色范围
thresholds_1 = [(0, 38, -60, 111, -76, 97)]  #黑色
 
roi1 = [0, 60, 320, 16]   # 巡线敏感区域1
roi2 = [0, 120, 320, 16]   # 巡线敏感区域2
roi3 = [0, 180, 320, 16]  # 巡线敏感区域3
 
 
while True:
    img = sensor.snapshot()#使用摄像机拍摄一张图片并返回给img后续进行操作
    lcd.display(img)  # 将图像用LCD显示
 
    # 查找所有黑色色块   area_threshold是过滤小的,自己可以改    pixels_threshold像素的最小数量
    #blobs_1 = img.find_blobs(thresholds_1, pixels_threshold=100, area_threshold=100)
    
    # 在roi1区域内寻找绿色区域的统计数据(用于巡线1)
    statistics1 = img.find_blobs(thresholds_1, roi=roi1, area_threshold=200, merge=True)
    # 在roi2区域内寻找绿色区域的统计数据(用于巡线2), margin=120
    statistics2 = img.find_blobs(thresholds_1, roi=roi2, area_threshold=200, merge=True)
    # 在roi3区域内寻找绿色区域的统计数据(用于巡线2), margin=120
    statistics3 = img.find_blobs(thresholds_1, roi=roi3, area_threshold=200, merge=True)   
    
    if statistics1:  # 如果在roi1区域找到黑色区域
      for b in statistics1:
        #绘制框出黑色区域的矩形框
        actualValue = b[5]  # 获取当前黑区域的中心位置   
        max_blob1 = max(statistics1, key=lambda b: b.pixels())
        # 绘制矩形框
        img.draw_rectangle(max_blob1.rect(),color=(0,255,0),scale=2)
        #中心点XY 并 画十字
        img.draw_cross(max_blob1.cx(), max_blob1.cy())
        
        # 计算中心位置
        x1 = max_blob1.cx()
        y1 = max_blob1.cy()
        
        #屏幕上标出坐标
        string = "({},{})".format(x1, y1)
        img.draw_string(max_blob1.cx(), max_blob1.cy(),string,color=(0,255,0),scale=2)
        #向串口发送数据 
        data = [0xb1,0xb1,x1,y1,0x00,0x00]               # 要发送的数据,对应串口接收中断最好需要设置头尾判断
        serial.send_bytearray(data)                      # 外置串口发送数据
        #print(x1, y1)                                   # USB串口发送数据
        
    if statistics2:  # 如果在roi2区域找到黑色区域
      for b in statistics2:
        actualValue = b[5]  # 获取当前黑区域的中心位置   
        max_blob2 = max(statistics2, key=lambda b: b.pixels())
            # 绘制矩形框
        img.draw_rectangle(max_blob2.rect(),color=(0,255,255),scale=2)
        #中心点XY
        img.draw_cross(max_blob2.cx(), max_blob2.cy())
 
        # 计算中心位置并向串口发送数据
        x2 = max_blob2.cx()
        y2 = max_blob2.cy()
        
        #屏幕上标出坐标
        string = "({},{})".format(x2, y2)
        img.draw_string(max_blob2.cx(), max_blob2.cy(),string,color=(0,255,0),scale=2)
        
        data = [0xb2,0xb2,x2,y2,0x00,0x00]               # 要发送的数据,对应串口接收中断最好需要设置头尾判断
        serial.send_bytearray(data)  # 发送数据
        #print(x2, y2)        
        
    if statistics3:  # 如果在roi3区域找到黑色区域
      for b in statistics3:
        actualValue = b[5]  # 获取当前黑区域的中心位置
        max_blob3 = max(statistics3, key=lambda b: b.pixels())
            # 绘制矩形框
        img.draw_rectangle(max_blob3.rect(),color=(0,0,255),scale=2)
        #中心点XY
        img.draw_cross(max_blob3.cx(), max_blob3.cy())
 
        # 计算中心位置并向串口发送数据
        x3 = max_blob3.cx()
        y3 = max_blob3.cy()
        #屏幕上标出坐标
        string = "({},{})".format(x3, y3)
        img.draw_string(max_blob3.cx(), max_blob3.cy(),string,color=(0,255,0),scale=2)
        
        data = [0xb3,0xb3,x3,y3,0x00,0x00]               # 要发送的数据,对应串口接收中断最好需要设置头尾判断
        serial.send_bytearray(data)  # 发送数据        
        #print(x3, y3) 
        
   # lcd.rotation(2)
    lcd.display(img)  # 将img,也就是那帧图像用lcd显示

测试效果图:

三个Roi同步在屏幕上打印识别到色块中心点的坐标,同时外置串口发送相关数据

网上学习资料贴出:

K210巡线循迹识别最大色块,发送坐标巡线_k210 巡线-CSDN博客

  • 10
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NULL指向我

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值