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

2025 电赛 C 题 发挥3 带数字编号的正方形识别 边长测量

2025 电赛 C 题「发挥 3」

带编号正方形识别 & 边长测量

香橙派 + 自训 PyTorch 模型 + C++ 零拷贝调用


目录

  1. 赛题需求与官方指标
  2. 技术路线全景图
  3. 硬件平台 & 接线
  4. 软件架构(C++ → Python → 自训模型)
  5. 模型训练回顾
  6. 端到端算法流程
    • 6.1 图像预处理 & ROI 提取
    • 6.2 Python 推理脚本(best_epoch_weights.pth
    • 6.3 C++ 零拷贝调用 Python
    • 6.4 编号-边长映射
    • 6.5 结果回显 & 串口输出
  7. 关键代码深度剖析
  8. 编译 & 部署指南
  9. 现场调试手册
  10. 性能 Benchmark
  11. FAQ & 常见坑
  12. 开源仓库 & 后续拓展

1 赛题需求与官方指标

指标要求
目标边长 6 cm~12 cm 的带编号正方形
输出指定编号的正方形边长,误差 ≤ 0.5 cm
输入单张 640×480 图像
限制5 s 内完成,禁止 PC,一键启动
额外编号由串口屏下发

2 技术路线全景图

在这里插入图片描述

3 硬件平台 & 接线

模块接口引脚供电
OV5640MIPI-CSICAM13.3 V
OLED SSD1306I²C-1PB8 PB93.3 V
串口屏UART3TX PA9 / RX PA103.3 V
按键GPIOPC133.3 V

4 软件架构

2025-C-NumberSquare/
├── src/
│   ├── main.cpp          # C++ 主程序
│   ├── python_wrapper.cpp # 调 Python
│   └── python/
│       ├── infer.py      # 加载 best_epoch_weights.pth(模型不开源了,可以来xianyu:)
│       └── dataset.py    # 训练脚本(留档)
├── models/
│   └── best_epoch_weights.pth
├── build/                # CMake 输出
└── scripts/└── build.sh          # 一键编译 & 运行

5 模型训练回顾

  • 数据集
    • 200张 64×64 正方形截图
    • 数字 0-9,字体 Arial,字号 20-36
  • 网络:MobileNetV2-0.5×
  • 损失:CrossEntropy + Label Smoothing
  • 训练
    python train.py --epochs 50 --batch 128 --lr 1e-3
    
  • 精度
    • 训练集 99.7 %
    • 验证集 97.8 %
  • 模型大小:7.9 MB

6 端到端算法流程

6.1 图像预处理 & ROI 提取

// 1. 外轮廓提取 (同发挥 1)
Rect roi = detectOuterShapes(frame, imgContour);
Mat roiImg = frame(roi);// 2. 正方形内 ROI
vector<RotatedRect> squares = findSquares(roiImg);
for(const auto& sq : squares){Mat square = cropSquare(roiImg, sq);resize(square, square, Size(64,64));sendToPython(square);   // 64×64 送入推理
}

6.2 Python 推理脚本(零拷贝)

python/infer.py

import torch
import cv2
import numpy as npdevice = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = torch.load("models/best_epoch_weights.pth", map_location=device)
model.eval()def infer_one(img_bgr):img = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)img = img.astype(np.float32) / 255.0tensor = torch.from_numpy(img).permute(2,0,1).unsqueeze(0)with torch.no_grad():logits = model(tensor)pred = logits.argmax(1).item()return pred

6.3 C++ 零拷贝调用 Python

src/python_wrapper.cpp

#include <Python.h>
#include <opencv2/opencv.hpp>class PyInference{
public:PyInference(){Py_Initialize();PyRun_SimpleString("import sys; sys.path.append('./python')");pModule = PyImport_ImportModule("infer");pFunc   = PyObject_GetAttrString(pModule, "infer_one");}int run(const cv::Mat& img){PyObject* pArgs = PyTuple_New(1);npy_intp dims[3] = {img.rows, img.cols, 3};PyObject* pValue = PyArray_SimpleNewFromData(3, dims, NPY_UINT8, img.data);PyTuple_SetItem(pArgs, 0, pValue);PyObject* pResult = PyObject_CallObject(pFunc, pArgs);int num = PyLong_AsLong(pResult);Py_DECREF(pArgs); Py_DECREF(pResult);return num;}~PyInference(){ Py_Finalize(); }
private:PyObject *pModule, *pFunc;
};

6.4 编号-边长映射

// 建立 map<编号, 边长>
unordered_map<int, double> id2len;
for(const auto& sq : squares){int id = pyInf.run(cropSquare(sq));double len = calSide(sq) * scale;id2len[id] = len;
}

6.5 结果回显 & 串口输出

int target_id = uart_get_target();          // 来自串口屏
double edge_cm = id2len[target_id];
printf("编号 %d 边长 %.2f cm\n", target_id, edge_cm);

7 关键代码深度剖析

7.1 正方形内截图

Mat cropSquare(const Mat& src, const RotatedRect& r){Mat M = getRotationMatrix2D(r.center, r.angle, 1.0);Mat rotated;warpAffine(src, rotated, M, src.size());Rect roi = r.boundingRect() & Rect(0,0,src.cols,src.rows);return rotated(roi);
}

7.2 Python 零拷贝数据传递

  • 无内存拷贝PyArray_SimpleNewFromData 直接包裹 cv::Mat 数据指针
  • 线程安全:C++ 主线程 + Python GIL 互斥

8 编译 & 部署指南

8.1 依赖安装

sudo apt update
sudo apt install build-essential cmake libopencv-dev python3 python3-pip
pip3 install torch torchvision numpy

8.2 一键脚本

git clone https://github.com/YourTeam/2025-C-NumberSquare.git
cd 2025-C-NumberSquare
chmod +x scripts/build.sh scripts/run.sh
./scripts/build.sh   # 约 40 s
./scripts/run.sh     # 自动加载模型 + 串口屏

9 现场调试手册

现象根因解决
“ModuleNotFoundError: torch”Python 环境缺失pip3 install torch
数字识别 0 %图像方向错误cropSquare 加旋转
串口屏无回显波特率不匹配统一 115200
内存溢出640×480 全图仅处理 ROI

10 性能 Benchmark

场景编号真值边长真值识别号测量边长误差耗时
单正方形 7 cm37.00 cm37.02 cm0.02 cm1.4 s
两正方形并排59.00 cm59.05 cm0.05 cm1.5 s
重叠 20 %86.50 cm86.48 cm0.02 cm1.6 s

11 FAQ & 常见坑

问题原因解决
Python 启动慢冷加载预加载模型 torch.jit.script
数字 6/9 混淆样本不足再采集 200 张
图像灰化BGR→RGB 顺序统一 RGB 送入 PyTorch

12 开源仓库 & 后续拓展

  • GitHub:github.com/langhaofu/2025-C-NumberSquare
  • 数据集 & 训练脚本:python/train.py
  • 香橙派镜像:2025-C-number-ubuntu-22.04-lite.img.xz
  • 未来:
    • ONNX 导出torch.onnx.export
    • TensorRT FP16 → Jetson Nano 迁移

总结
本文在 香橙派 上实现了 “C++ 主程序 → Python 零拷贝 → 自训 PyTorch 模型” 的完整链路,现场实测 1.5 s 完成编号识别 + 边长测量,误差 ≤ 0.05 cm。欢迎 Star、Issue、PR!

http://www.lryc.cn/news/620722.html

相关文章:

  • [特殊字符]走进华为,解锁商业传奇密码
  • 通过网页调用身份证阅读器http websocket方法-湖南步联科技美萍MP999A电子————仙盟创梦IDE
  • 从根源到生态:Apache Doris 与 StarRocks 的深度对比 —— 论开源基因与长期价值的优越性
  • 审批流程系统设计与实现:状态驱动、灵活扩展的企业级解决方案
  • 实战指南|消防管理系统搭建全流程解析
  • OpenCV ------图像基础处理(一)
  • 【P81 10-7】OpenCV Python【实战项目】——车辆识别、车流统计(图像/视频加载、图像运算与处理、形态学、轮廓查找、车辆统计及显示)
  • 【OpenCV】Mat详解
  • 入门基础人工智能理论
  • 计算机视觉(opencv)实战二——图像边界扩展cv2.copyMakeBorder()
  • 论,物联网日志系统架构如何设计?
  • AI增强SEO关键词表现
  • Postman 平替 技术解析:架构优势与实战指南
  • 考研408《计算机组成原理》复习笔记,第五章(2)——CPU指令执行过程
  • 使用 Docker 部署 PostgreSQL
  • 考研408《计算机组成原理》复习笔记,第四章(3)——指令集、汇编语言
  • Java设计模式之《策略模式》
  • Effective C++ 条款41:理解隐式接口和编译期多态
  • 应用系统连达梦数据库报“服务器模式不匹配”的根源与修复方案
  • 使用colmap自制3DGaussian_Splatting数据集
  • BotCash:GPT-5发布观察 工程优化的进步,还是技术突破的瓶颈?
  • GoLand 项目从 0 到 1:第八天 ——GORM 命名策略陷阱与 Go 项目启动慢问题攻坚
  • 通过机器学习框架实现Android手写识别输入功能
  • Spring Boot 3中JWT密钥安全存储方案
  • Python训练营打卡Day32-神经网络的训练
  • 【Golang】Golang内存泄漏问题排查(二)
  • OpenCv(三)——图像平滑处理
  • 8. 函数简介
  • OpenCV中对图像进行平滑处理的4种方式
  • HarmonyOS AI辅助编程工具(CodeGenie)智慧调优