当前位置: 首页 > news >正文

基于 OpenMV 的矩形识别与 STM32 串口通信(电子设计大赛实用教程)

🎯 基于 OpenMV 的矩形识别与 STM32 串口通信(电子设计大赛实用教程)

一、前言

在本科生电子设计大赛中,经常会遇到图像识别相关的任务,例如:

  • 识别 矩形框(如识别一个 A4 纸、黑色标记框等);
  • 将识别结果传输到 STM32 单片机,用于后续控制(舵机、移动小车、机械臂等)。

很多同学会用 OpenMV 来做图像处理,因为它开箱即用、Python 脚本开发方便,能快速实现视觉任务。再配合 STM32,就能完成 感知 + 控制 的闭环。

今天我就带大家梳理一份完整的 OpenMV 矩形识别 + STM32 串口通信 的实例代码,并讲解核心思路,帮助大家快速上手。


二、整体思路

1. OpenMV 端(负责“看”)

  • 使用摄像头拍摄画面。
  • 利用 find_blobs() 方法寻找黑色区域,并筛选出符合 矩形特征 的目标。
  • 计算矩形的 中心点坐标,并绘制出来。
  • 将坐标通过 UART 串口 发给 STM32。

2. STM32 端(负责“动”)

  • 接收 OpenMV 发来的坐标字符串。
  • 解析坐标数据(例如 CENTER:160,120)。
  • 可以基于坐标进行舵机或电机的控制(例如居中跟踪)。

这样,OpenMV 负责 视觉识别,STM32 负责 运动控制,两者结合就能完成各种电子设计大赛任务。


三、OpenMV 代码详解

下面是完整的 OpenMV 代码(已加详细注释),功能:
👉 识别 A4 比例的矩形目标,并实时将中心点坐标通过串口发送给 STM32。

import sensor, image, time, math 
from pyb import UART# ================== 初始化串口 ==================
uart = UART(3, 9600)  # 使用 UART3,波特率 9600
uart.init(9600, bits=8, parity=None, stop=1)# ================== 初始化摄像头 ==================
sensor.reset()
sensor.set_pixformat(sensor.RGB565)   # 彩色图像
sensor.set_framesize(sensor.QVGA)     # 分辨率 320x240
sensor.skip_frames(time=2000)         # 等待摄像头稳定
sensor.set_auto_gain(False)           # 关闭自动增益
sensor.set_auto_whitebal(False)       # 关闭自动白平衡# ================== 参数设置 ==================
MIN_AREA = 2000      # 最小矩形面积
MAX_AREA = 40000     # 最大矩形面积
A4_RATIO = 1.414     # A4纸长宽比 √2
A4_RATIO_INV = 0.707 # 1/√2
RATIO_TOLERANCE = 0.6  # 长宽比容差# 黑色检测阈值(在 LAB 色彩空间)
BLACK_THRESHOLD = [(0, 30, -128, 127, -128, 127)]# ================== 判断矩形函数 ==================
def is_valid_rectangle(blob):rect = blob.rect()w, h = rect[2], rect[3]if w == 0 or h == 0:return Falseratio_wh = w / hratio_hw = h / wis_valid_ratio = (abs(ratio_wh - A4_RATIO) < RATIO_TOLERANCE orabs(ratio_wh - A4_RATIO_INV) < RATIO_TOLERANCE orabs(ratio_hw - A4_RATIO) < RATIO_TOLERANCE orabs(ratio_hw - A4_RATIO_INV) < RATIO_TOLERANCE)if is_valid_ratio:rectangularity = blob.area() / (w * h)if rectangularity > 0.6:  # 矩形度阈值return Truereturn False# ================== 查找矩形中心 ==================
def find_rectangle_center(img):img_gray = img.to_grayscale()blobs = img_gray.find_blobs(BLACK_THRESHOLD,pixels_threshold=80,area_threshold=MIN_AREA,merge=True)best_blob, best_score = None, 0for blob in blobs:if blob.area() < MIN_AREA or blob.area() > MAX_AREA:continueif is_valid_rectangle(blob):rect = blob.rect()rectangularity = blob.area() / (rect[2] * rect[3])score = blob.area() * rectangularityif score > best_score:best_score, best_blob = score, blobreturn best_blob# ================== 绘制矩形并输出中心点 ==================
def draw_rectangle_info(img, blob):if blob is None:return Nonerect = blob.rect()center_x = rect[0] + rect[2] // 2center_y = rect[1] + rect[3] // 2img.draw_rectangle(rect, color=(255,0,0), thickness=2)img.draw_circle(center_x, center_y, 8, color=(0,0,255), thickness=3)img.draw_string(10, 10, f"Center: ({center_x},{center_y})", color=(255,255,255))return (center_x, center_y)# ================== 主循环 ==================
print("OpenMV矩形检测启动...")
clock = time.clock()
last_send_time = 0
SEND_INTERVAL = 100  # 每 100ms 发送一次while True:clock.tick()img = sensor.snapshot()best_blob = find_rectangle_center(img)if best_blob:center = draw_rectangle_info(img, best_blob)if center:current_time = time.ticks_ms()if current_time - last_send_time > SEND_INTERVAL:message = f"CENTER:{center[0]},{center[1]}\n"uart.write(message)print("发送:", message.strip())last_send_time = current_timeelse:img.draw_string(10, 10, "未检测到矩形", color=(255,0,0))

四、STM32 代码解析

在 STM32 上,我们需要做的事情比较简单:

  • 接收串口数据;
  • 判断一条数据是否接收完成(以 \n 作为结束标志);
  • 解析数据,提取坐标;
  • 打印确认,或者做后续控制。

下面是处理函数的示例:

// 串口数据接收处理
void process_uart_data(void)
{if (Serial_GetRxFlag() == 1) // 判断是否有数据{RxData = Serial_GetRxData();if (RxData == '\n') // 接收完成{received_data[data_index] = '\0';new_data_flag = 1;   // 标志位置 1}else if (RxData != '\r' && data_index < 99){received_data[data_index++] = RxData;}else if (data_index >= 99){data_index = 0; // 缓冲区溢出,重置}}
}// 处理 OpenMV 发来的数据
void process_openmv_data(char *data)
{if (strncmp(data, "CENTER:", 7) == 0){if (sscanf(data + 7, "%d,%d", &center_x, &center_y) == 2){printf("STM32: 接收到中心点(%d,%d)\r\n", center_x, center_y);// 这里可以添加舵机控制逻辑}else{printf("数据格式错误: %s\r\n", data);}}else{printf("未知数据: %s\r\n", data);}
}

五、运行效果

  1. 在摄像头前放置一个黑色矩形(如 A4 纸加黑边框)。

  2. OpenMV 能识别出矩形,并实时计算 中心点坐标

  3. 通过串口发送数据到 STM32,格式类似:

    CENTER:160,120
    
  4. STM32 成功接收,并打印确认:

    STM32: 接收到中心点(160,120)
    
  5. 后续可以加上 舵机转动、PID 调整 等功能,实现自动跟踪。


六、总结

本文分享了一个 电子设计大赛常用模块

  • OpenMV 实现矩形检测,核心在于 blob 检测 + 长宽比筛选;
  • STM32 串口解析数据,实现视觉到控制的桥梁。

这个小模块能应用在很多场景:
✅ 自动对准目标(如巡线小车的识别框);
✅ 机械臂定位(对准工件中心点);
✅ 运动控制(云台自动居中)。

掌握这一套,就等于打通了视觉识别和控制的关键环节。🚀


👉 如果你也在准备电子设计大赛,建议先把这份代码跑通,再在 STM32 上加上电机/舵机控制逻辑,你的速度已经超越大部分本科生了!

附上文字版的接线说明

🔌 OpenMV 与 STM32 串口接线说明

OpenMV 模块和 STM32 开发板之间通过 UART 串口通信,一般只需要接 4 根线:

  1. GND (地线)

    • OpenMV 的 GND → STM32 的 GND
    • 必须共地,否则串口通信不稳定。
  2. TX (发送端)

    • OpenMV 的 TX → STM32 的 RX(接收端口)
    • 负责将 OpenMV 发送的数据传输给 STM32。
  3. RX (接收端)

    • OpenMV 的 RX → STM32 的 TX(发送端口)
    • 用于接收 STM32 发回的数据(比如确认信息)。
  4. VCC (电源)

    • OpenMV 的 3.3V/5V → STM32 的 3.3V/5V(取决于你的 STM32 板供电电压)。
    • 推荐使用 5V 给 OpenMV 供电。

📋 接线对照表

OpenMV 引脚STM32 引脚说明
VCC (5V)5V电源供电
GNDGND公共地线
TX (P4)RX (PA10, USART1)OpenMV → STM32
RX (P5)TX (PA9, USART1)STM32 → OpenMV

⚠️ 注意事项

  • 串口波特率要一致(这里配置的是 9600bps)。
  • 如果使用 不同的串口(例如 STM32 USART2),只需要修改对应的 引脚号和代码
  • 不要忘记 共地,这是新手最容易忽略的问题。

在这里插入图片描述
视频可以参考:小破站 小陈学长电子实验室 欢迎关注三连 谢谢谢谢谢谢谢谢谢谢谢谢

http://www.dtcms.com/a/340063.html

相关文章:

  • k8s运维实践:高可用Redis Cluster(三主三从)与Proxy部署方案
  • 使用 Docker 安装长安链管理平台 + 部署区块链与示例合约
  • daily notes[3]
  • Eigen中Dense 模块简要介绍和实战应用示例(最小二乘拟合直线、协方差矩阵计算和稀疏求解等)
  • 三极管驱动led灯搭配的电阻选取方法
  • 跟随广州AI导游深度探寻广州历史底蕴​
  • 如何做一次AIMD
  • 农田扫描提速37%!基于检测置信度的无人机“智能抽查”路径规划,Coovally一键加速模型落地
  • [OWASP]智能体应用安全保障指南
  • 英伟达显卡驱动怎么更新 详细步骤教程
  • MySQL练习题50题(附带详细教程)
  • Day13_【DataFrame数据组合concat连接】【案例】
  • C5.5:VDB及后面的电路讨论
  • 决策树(2)
  • Yum使用时报错
  • Spring Boot 全局异常处理
  • 快速了解Anaconda系统
  • 08.5【C++ 初阶】实现一个相对完整的日期类--附带源码
  • implement libtime on Windows
  • MyCAT基础概念
  • Python函数总结
  • week2-[一维数组]最大元素
  • 单细胞格式转换 rds 转成 h5ad
  • transformer模型初理解
  • Transformer、BERT、BEiT等模型相关八股及代码【自用】
  • HJ4 字符串分隔
  • 神经网络训练过程详解
  • 电流采样实现方法
  • JavaScript 代码保护与混淆
  • Vue2+Vue3前端开发_Day1