maixcam通过YOLOv5实现目标检测与电机控制:检测数字并控制电机正反转

效果展示

结合目标检测和电机控制技术,来实现一个智能系统,能够根据检测到的数字来控制电机的正转和反转。我们使用了YOLOv5目标检测模型和Maix模块进行实现。

本文的目标是实现一个系统,当摄像头检测到数字"1"时,电机将正转;当检测到数字"2"时,电机将反转,每次转动持续2秒钟。

硬件准备

我们将使用以下硬件组件:

Maix开发板(如Sipeed Maixduino)

具有PWM控制的电机驱动模块(如TB6612)

直流电机

摄像头模块(兼容Maix开发板)

其他配件,如电源、连接线等

软件环境

在软件方面,我们将使用Python编程语言,并且使用Maix的库来实现目标检测和电机控制。主要的软件组件包括:

YOLOv5模型(用于目标检测)

Maix库(用于控制摄像头、显示器和GPIO)

完整代码

python 复制代码
from maix import camera, display, image, nn, app
from maix import gpio, pinmap, time, pwm

# 初始化YOLOv5模型
detector = nn.YOLOv5(model="/root/models/model_127448.mud")  # 注意修改成你的模型文件路径

# 初始化摄像头,使用模型输入尺寸
cam = camera.Camera(detector.input_width(), detector.input_height(), detector.input_format())

# 初始化显示器
dis = display.Display()

# 定义PWM频率和占空比范围
PWM_FREQUENCY = 1000  # PWM频率为1kHz
PWM_MIN_DUTY = 0      # 最小占空比(0%表示停止)
PWM_MAX_DUTY = 100    # 最大占空比(100%表示全速)

# 定义TB6612的PWM通道和引脚
PWM_A_PIN = "A19"    # 电机A的PWM引脚
PWM_B_PIN = "A18"    # 电机B的PWM引脚
IN1_PIN = "A27"     # 控制电机A方向的引脚1
IN2_PIN = "A23"     # 控制电机A方向的引脚2
IN3_PIN = "A22"     # 控制电机B方向的引脚1
IN4_PIN = "A25"     # 控制电机B方向的引脚2
STBY_PIN = "A15"    # 待机引脚

# 设置引脚功能
pinmap.set_pin_function(PWM_A_PIN, "PWM7")   # 设置电机A PWM引脚功能
pinmap.set_pin_function(PWM_B_PIN, "PWM6")   # 设置电机B PWM引脚功能
pinmap.set_pin_function(IN1_PIN, "GPIO")     # 设置电机A方向引脚1功能
pinmap.set_pin_function(IN2_PIN, "GPIO")     # 设置电机A方向引脚2功能
pinmap.set_pin_function(IN3_PIN, "GPIO")     # 设置电机B方向引脚1功能
pinmap.set_pin_function(IN4_PIN, "GPIO")     # 设置电机B方向引脚2功能
pinmap.set_pin_function(STBY_PIN, "GPIO")    # 设置待机引脚功能

# 初始化GPIO对象
gpio_stby = gpio.GPIO(STBY_PIN, gpio.Mode.OUT)  # 初始化待机引脚为输出模式
gpio_in1 = gpio.GPIO(IN1_PIN, gpio.Mode.OUT)    # 初始化电机A方向引脚1为输出模式
gpio_in2 = gpio.GPIO(IN2_PIN, gpio.Mode.OUT)    # 初始化电机A方向引脚2为输出模式
gpio_in3 = gpio.GPIO(IN3_PIN, gpio.Mode.OUT)    # 初始化电机B方向引脚1为输出模式
gpio_in4 = gpio.GPIO(IN4_PIN, gpio.Mode.OUT)    # 初始化电机B方向引脚2为输出模式

# 初始化PWM对象,用于控制电机速度
pwm_a = pwm.PWM(7, freq=PWM_FREQUENCY, duty=PWM_MIN_DUTY, enable=True)  # 初始化电机A PWM对象
pwm_b = pwm.PWM(6, freq=PWM_FREQUENCY, duty=PWM_MIN_DUTY, enable=True)  # 初始化电机B PWM对象

# 设置电机速度的辅助函数
def set_motor_speed(pwm, speed_percent):
    """
    设置电机的速度。
    :param pwm: PWM对象,用于控制电机速度
    :param speed_percent: 电机速度百分比(0到100)
    """
    duty = PWM_MIN_DUTY + (PWM_MAX_DUTY - PWM_MIN_DUTY) * speed_percent / 100.0
    pwm.duty(duty)

# 设置电机方向的函数
def set_motor_direction(motor, direction):
    """
    设置电机的旋转方向。
    :param motor: 要控制的电机('A' 或 'B')
    :param direction: 电机的旋转方向('forward', 'backward', 'stop')
    """
    if motor == 'A':
        if direction == 'forward':
            gpio_in1.value(1)  # 电机A正转,IN1高电平
            gpio_in2.value(0)  # 电机A正转,IN2低电平
        elif direction == 'backward':
            gpio_in1.value(0)  # 电机A反转,IN1低电平
            gpio_in2.value(1)  # 电机A反转,IN2高电平
        elif direction == 'stop':
            gpio_in1.value(0)  # 停止电机A,IN1低电平
            gpio_in2.value(0)  # 停止电机A,IN2低电平
    elif motor == 'B':
        if direction == 'forward':
            gpio_in3.value(1)  # 电机B正转,IN3高电平
            gpio_in4.value(0)  # 电机B正转,IN4低电平
        elif direction == 'backward':
            gpio_in3.value(0)  # 电机B反转,IN3低电平
            gpio_in4.value(1)  # 电机B反转,IN4高电平
        elif direction == 'stop':
            gpio_in3.value(0)  # 停止电机B,IN3低电平
            gpio_in4.value(0)  # 停止电机B,IN4低电平

# 控制电机的运行
def run_motors(direction, duration):
    """
    根据检测结果控制电机的方向和速度。
    :param direction: 'forward' 或 'backward',控制电机方向
    :param duration: 运行时间(秒)
    """
    gpio_stby.value(1)  # 启用TB6612模块(将待机引脚设置为高电平)
    
    if direction == 'forward':
        set_motor_direction('A', 'forward')
        set_motor_direction('B', 'backward')
        set_motor_speed(pwm_a, 50)  # 设置电机A的速度为50%
        set_motor_speed(pwm_b, 50)  # 设置电机B的速度为50%
    elif direction == 'backward':
        set_motor_direction('A', 'backward')
        set_motor_direction('B', 'forward')
        set_motor_speed(pwm_a, 50)  # 设置电机A的速度为50%
        set_motor_speed(pwm_b, 50)  # 设置电机B的速度为50%
    
    # 持续运行电机指定的时间
    time.sleep(duration)
    
    # 停止电机
    set_motor_direction('A', 'stop')
    set_motor_direction('B', 'stop')
    set_motor_speed(pwm_a, 0)  # 停止电机A
    set_motor_speed(pwm_b, 0)  # 停止电机B

# 主循环
while not app.need_exit():
    # 读取摄像头图像
    img = cam.read()
    
    # 进行目标检测
    objs = detector.detect(img, conf_th=0.5, iou_th=0.45)
    
    # 标志变量,用于确定是否检测到数字1或2
    detected_1 = False
    detected_2 = False

    # 处理检测到的对象
    for obj in objs:
        # 绘制检测框
        img.draw_rect(obj.x, obj.y, obj.w, obj.h, color=image.COLOR_RED)
        
        # 获取检测结果标签和置信度
        label = detector.labels[obj.class_id].strip()  # 确保标签文件正确映射并去除多余空格
        score = obj.score
        
        # 打印检测结果
        print(f'Detected: {label} with score: {score}')

        # 根据检测结果更新标志变量
        if label == "1":
            detected_1 = True
        elif label == "2":
            detected_2 = True
        
        # 绘制检测结果文本
        msg = f'{label}: {score:.2f}'
        img.draw_string(obj.x, obj.y, msg, color=image.COLOR_RED)
    
    # 根据检测到的结果控制电机方向
    if detected_1:
        print("Detected '1': Turning motors forward for 2 seconds")
        run_motors('forward', 2)  # 电机正转2秒
    elif detected_2:
        print("Detected '2': Turning motors backward for 2 seconds")
        run_motors('backward', 2)  # 电机反转2秒

    # 显示处理后的图像
    dis.show(img)

    # 延迟一段时间,以避免过于频繁的检测(根据需要调整)
    time.sleep_ms(100)
相关推荐
奔跑中的小象1 天前
统信UOS + 天数AI卡部署SGLang服务手册
人工智能·uos·sglang·天数智芯
DevSecOps选型指南1 天前
中国版Mythos,为何是悬镜安全灵脉CodeAI?
人工智能·安全
Shockang1 天前
LangGraph 状态机实战
人工智能
刹那芳华19921 天前
循环神经网络的从零开始实现(RNN)
人工智能·rnn·深度学习
阿童木写作1 天前
跨境图片翻译工具多合一,批量图片视频字幕翻译加智能抠图
人工智能·python·音视频·语音识别
科技之门1 天前
AI3D从建模到贴图、绑骨和动画的完整流程怎么做?V2Fun完整工作流指南
人工智能·3d·贴图
宇宙第一小趴菜1 天前
二、机器学习的应用领域和发展史
人工智能·机器学习
前端开发江鸟1 天前
我写过 MCP Server,却一直以为 MCP 只有 Tool
人工智能
天国梦1 天前
自习室智能化升级避坑指南:天学网AI智习室方案实测与选型建议
大数据·人工智能
阿里云云原生1 天前
可用性从 99.9% 跃升至 99.995%:畅捷通如何用 AI 重塑运维底座?
运维·网络·人工智能