K210寻黑线

K210寻黑线

相关资料

代码:

# 导入必要的模块
import sensor, image, lcd
from machine import UART  # 串口库函数
from fpioa_manager import fm  # GPIO重定向函数

# GPIO引脚重定向为UART1的TX和RX
fm.register(18, fm.fpioa.UART1_TX, force=True)
fm.register(19, fm.fpioa.UART1_RX, force=True)
uart_A = UART(UART.UART1, 115200, 8, 0, 1, timeout=1000, read_buf_len=4096)  # 初始化UART1串口

# 设置巡线需要的阈值和敏感区域
green_threshold = ((0, 190))  # 绿色阈值(用于黑色)
roi1 = [0, 100, 320, 16]  # 巡线敏感区域
roi2 = [0, 180, 320, 8]   # 关键点敏感区域
expectedValue = 160       # 巡线位置期望值
err = 0                   # 本次误差
old_err = 0               # 上次误差
Kp = 0.046                # PID比例系数
Kd = 0                    # PID微分系数
Speed = 0                 # 期望速度
Speed_left = 0            # 左轮速度
Speed_right = 0           # 右轮速度
Flag = 0                  # 关键点标志位

# 发送数据的函数定义
def sending_data(x, y, z):
    global uart_A
    FH = bytearray([0x2C, 0x12, x, y, z, 0x5B])  # 准备发送的数据包
    uart_A.write(FH)  # 发送数据

# 初始化LCD和摄像头
lcd.init()
sensor.reset()
sensor.set_pixformat(sensor.GRAYSCALE)
sensor.set_framesize(sensor.QVGA)  # 设置图像帧大小为320x240
sensor.skip_frames(time=3000)  # 跳过3000张图像帧以便调整传感器
sensor.set_auto_gain(False)  # 关闭自动增益
sensor.set_auto_whitebal(False)  # 关闭白平衡

sensor.run(1)  # 启动摄像头

while True:
    img = sensor.snapshot()  # 获取一帧图像

    # 在roi1区域内寻找绿色区域的统计数据(用于巡线)
    statistics1 = img.find_blobs([green_threshold], roi=roi1, area_threshold=200, merge=True)
    # 在roi2区域内寻找绿色区域的统计数据(用于关键点检测)
    statistics2 = img.find_blobs([green_threshold], roi=roi2, area_threshold=120, merge=True, margin=120)

    if statistics1:  # 如果在roi1区域找到绿色区域
        for b in statistics1:
            tmp = img.draw_rectangle(b[0:4])  # 在找到的区域绘制矩形框
            tmp = img.draw_cross(b[5], b[6])  # 在找到的区域绘制十字交叉点

            # PID控制计算
            actualValue = b[5]  # 获取当前绿色区域的中心位置
            err = actualValue - expectedValue  # 计算误差
            Speed_left = Speed - (Kp * err + Kd * (err - old_err))  # 计算左轮速度
            Speed_right = Speed + (Kp * err + Kd * (err - old_err))  # 计算右轮速度
            old_err = err  # 更新误差值
            print("Speed_left, Speed_right")
            print(int(Speed_left), int(Speed_right))  # 打印速度值

    if statistics2:  # 如果在roi2区域找到绿色区域
        for b in statistics2:
            tmp = img.draw_rectangle(b[0:4])  # 在找到的区域绘制矩形框
            tmp = img.draw_cross(b[5], b[6])  # 在找到的区域绘制十字交叉点
            if b[2] > 50:
                Flag = 1  # 如果面积大于50,则设置关键点标志位为1

    sending_data(int(Speed_left), int(Speed_right), Flag)  # 发送控制数据到UART
    lcd.display(img)  # 在LCD上显示处理后的图像


代码解释:

1、1寻找色块部分

  • 其中的 sensor.set_pixformat(sensor.GRAYSCALE) 是将像素模式设置为灰度灰度模式对于只有两种颜色的地图可以起到提高帧数,过滤其它颜色的影响,提高了识别的正确率。
  • 其中的 Flag 是用于当检测到如十字路口,起停线等的标志
  • 通过find_blobs函数可以找到色块,其中==[green_threshold]==寻找目标是颜色的阈值,阈值可以通过Maixpy IDE工具栏中的工具 -> 机器视觉 -> 阈值编辑器获得。
  • 其中的 ==roi1 ==和 ==roi2 ==分别是寻线部分和关键的感兴趣区,就是在要处理的整张图像中
    敏感区示例
  • ==area_threshold ==是面积阈值,如果色块被框起来的面积小于这个值,会被过滤掉,减少干扰提高巡线准确度。
  • merge=True 将所有重叠的blob合并为一个。
  • margin为边界,如果设置为1,那么两个blobs如果间距1一个像素点,也会被合并。此参数只在检测关键点寻找色块函数中运用,可以更明确的侦测出关键点,如Y型路口。
  • ==statistics = img.find_blobs[ ] ==对象返回的是多个blob的列表,列表类似与C语言的数组,一个blobs列表里包含很多blob对象,blobs对象就是色块,每个blobs对象包含一个色块的信息。b就是很多色块。可以用for循环把所有的色块找一遍。

for b in statistics:
返回色块的外框的x坐标(int),也可以通过b[0]来获得
返回色块的外框的y坐标(int),也可以通过b[1]来获得
返回色块的外框的宽度w(int),也可以通过b[2]来获得
返回色块的外框的高度h(int),也可以通过b[3]来获得
返回色块的像素数量(int),也可以通过b[4]来获得
返回色块的外框的中心x坐标(int),也可以通过b[5]来获得
返回色块的外框的中心y坐标(int),也可以通过b[6]来获得
————————————————

  • tmp=img.draw_rectangle(b[0:4]) 和tmp=img.draw_cross(b[5], b[6]) 分别为画出找到色块的外框和中心十字
    在这里插入图片描述

1、2寻线部分

由上我们可得b[5]为返回外框中心x的值,而且拍摄的画面为320x240,X方向的中间为160,所以线与摄像头中心的偏移量err,就为实际值actualValue 也就是b[5]减去期望expectedValue(160)。对应代码为:

actualValue=b[5]
err=actualValue-expectedValue

得到偏差之后计算pid的值:

Speed_left = Speed - (Kperr+Kd(err-old_err))
Speed_right = Speed + (Kperr+Kd(err-old_err))
old_err= err

1、3 关键点部分

当要经过十字路口,y型路口,起停线时,可以关注blob的列表中的b[2],其反回的值为返回色块的外框的宽度w。因为正常巡线时寻找到的色块外框宽度w的值是小于关键点部分的值。
正常寻线
r型路口
启停线
十字路口
只需要判断是否大于正常色块外框宽度就可以判断关键点

if b[2] >50:
Flag = 1

相关推荐

  1. 【已解决】k210模型烧录——kfpkg 打包

    2024-07-22 11:56:04       58 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-22 11:56:04       52 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-22 11:56:04       54 阅读
  3. 在Django里面运行非项目文件

    2024-07-22 11:56:04       45 阅读
  4. Python语言-面向对象

    2024-07-22 11:56:04       55 阅读

热门阅读

  1. OMOST 作画能力的硬核解析[C#]

    2024-07-22 11:56:04       15 阅读
  2. Linux 驱动学习笔记

    2024-07-22 11:56:04       14 阅读
  3. 掌握Git:面试中常见的问题与解答

    2024-07-22 11:56:04       16 阅读
  4. DOS常用命令大全

    2024-07-22 11:56:04       12 阅读
  5. 设计模式在FileBrowser中的几个应用

    2024-07-22 11:56:04       13 阅读
  6. 代码随想录 day 17 二叉树

    2024-07-22 11:56:04       16 阅读
  7. Golang_交替打印ABC\奇偶数\1-10\字母(并发编程)

    2024-07-22 11:56:04       15 阅读