maixcam通过YOLOv5实现目标检测与电机控制:检测数字并控制电机正反转
效果展示
结合目标检测和电机控制技术,来实现一个智能系统,能够根据检测到的数字来控制电机的正转和反转。我们使用了YOLOv5目标检测模型和Maix模块进行实现。
本文的目标是实现一个系统,当摄像头检测到数字“1”时,电机将正转;当检测到数字“2”时,电机将反转,每次转动持续2秒钟。
硬件准备
我们将使用以下硬件组件:
(图片来源网络,侵删)
Maix开发板(如Sipeed Maixduino)
具有PWM控制的电机驱动模块(如TB6612)
直流电机
摄像头模块(兼容Maix开发板)
其他配件,如电源、连接线等
软件环境
在软件方面,我们将使用Python编程语言,并且使用Maix的库来实现目标检测和电机控制。主要的软件组件包括:
YOLOv5模型(用于目标检测)
Maix库(用于控制摄像头、显示器和GPIO)
完整代码
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)
文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。