目录

一、引言:当激光笔遇上视觉识别

更多原理图信息三连评论区回复“原理图”即可,私信发

二、系统总体设计

三、硬件连接一览

四、软件架构

4.1 技术栈

4.2 任务流

五、核心代码解析

5.1 初始化:让硬件“醒”过来

5.2 目标识别:色块+矩形双保险

5.3 坐标映射:把像素“翻译”成角度

5.4 主循环:20行代码完成闭环


一、引言:当激光笔遇上视觉识别

在2023年全国大学生电子设计竞赛中,视觉识别+执行机构类题目频繁出现:从“电磁炮打靶”到“智能搬运车”,无一不要求“看得准、打得稳、控得精”。传统方案往往采用“PC+OpenCV+下位机”的分布式架构,成本高、延迟大、部署难。

本文提出一种“All-in-One”解决方案:
以立创·庐山派K230-CanMV开发板为核心,在端侧完成图像采集→视觉识别→激光指示→舵机闭环控制的全链路闭环

立创·庐山派K230-CanMV开发板原理图如下:

更多原理图信息三连评论区回复“原理图”即可,私信发

仅用一块板子、一根USB线、一颗舵机、一支激光笔,即可实现“看到目标→激光瞄准→舵机跟随”的完整演示。


二、系统总体设计

模块 功能 资源占用
Camera 640×640@30fps RGB 采集 K230 ISP + DVP
Vision 色块/矩形/线段识别 K230 NPU + OpenCV
Laser 3.3V 激光笔开关 GPIO33
Servo 9g舵机 0°–180° PWM2(GPIO46)
UI 实时画面+FPS叠加 LT9611 800×480
Power 5V 2A Type-C 供电 板载MT9700

三、硬件连接一览

外设 引脚 原理图索引
激光笔正极 3V3 P1-01
激光笔负极 GPIO33 P1-33
舵机信号线 GPIO46(PWM2) P1-46
舵机VCC 5V P1-02
舵机GND GND P1-06

注:舵机务必使用板载5V供电,GPIO仅提供信号,防止电流倒灌。

四、软件架构

4.1 技术栈

  • 操作系统:RT-Smart(K230大核)

  • 视觉库:CanMV Media Framework(Python3)

  • 控制库:machine.PWM + machine.Pin

  • 调试界面:IDE实时回传

4.2 任务流

五、核心代码解析

5.1 初始化:让硬件“醒”过来

from media.sensor import *
from media.display import *
from media.media import *
from machine import FPIOA, Pin, PWM
import time, os

# 1. 重映射引脚
fpioa = FPIOA()
fpioa.set_function(33, FPIOA.GPIO33)   # 激光
fpioa.set_function(46, FPIOA.PWM2)     # 舵机

# 2. 激光笔初始化
laser = Pin(33, Pin.OUT, value=0)

# 3. 舵机PWM初始化:50Hz,周期20ms
servo = PWM(2, freq=50, duty=0)
servo.enable(True)

# 4. 摄像头
sensor = Sensor(width=640, height=640)
sensor.reset()
sensor.set_pixformat(Sensor.RGB565)
sensor.set_framesize(width=640, height=640)

# 5. 显示
Display.init(Display.LT9611, to_ide=True)
MediaManager.init()
sensor. Run()

5.2 目标识别:色块+矩形双保险

def find_max_blob(img):
    blobs = img.find_blobs([(41, 57, 31, 83, 13, 71)],  # 红色阈值
                           pixels_threshold=5000,
                           area_threshold=5000,
                           margin=True)
    if not blobs:
        return None
    max_blob = max(blobs, key=lambda b: b.pixels())
    return max_blob

5.3 坐标映射:把像素“翻译”成角度

def map_coord_to_angle(x, img_w=640):
    """
    将x坐标线性映射到0-180°
    """
    return int((x / img_w) * 180)

5.4 主循环:20行代码完成闭环

clock = time.clock()
while True:
    clock.tick()
    os.exitpoint()
    img = sensor.snapshot()

    blob = find_max_blob(img)
    if blob:
        cx = blob.cx()
        angle = map_coord_to_angle(cx)
        duty = 0.5 + angle / 180 * 2  # 0.5ms~2.5ms
        servo.duty(duty / 20 * 100)

        laser.value(1)  # 点亮激光
        img.draw_rectangle(blob.rect(), color=(0, 255, 0), thickness=4)
        img.draw_cross(cx, blob.cy(), color=(255, 0, 0), size=10)
    else:
        laser.value(0)

    img.draw_string(10, 10, f"FPS:{clock.fps():.1f}", scale=2)
    Display.show_image(img)

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐