2025 年全国大学生电子设计竞赛 C 题
发挥部分 1:多正方形 / 重叠正方形高精度识别与最小边长测量
香橙派 + OpenCV C++ 全流程解析
目录
赛题背景与需求 技术难点全景图 系统总体架构 硬件平台与接线 软件架构与线程模型 算法流水线逐帧拆解 6.1 图像预处理 6.2 轮廓提取与面积过滤 6.3 重叠正方形分割:向量夹角法 6.4 最小正方形边长计算 6.5 透视畸变补偿 6.6 亚像素级优化 关键代码剖析 香橙派编译与烧录 调试工具链 性能 Benchmark 常见问题 FAQ 拓展阅读与开源仓库
1 赛题背景与需求
2025 年电赛 C 题 发挥部分 1 要求:
指标 说明 目标 正方形组合图形,6 cm ~ 12 cm 边长 状态 可彼此分离,也可 局部重叠 ≤ 30 % 输出 最小正方形边长 ,误差 ≤ 0.5 cm限制 单目固定摄像头,禁止 PC,一键启动,5 s 内完成
2 技术难点全景图
难点 场景示例 传统方案痛点 本文解决策略 边缘粘连 两正方形重叠 25 % 大轮廓误判为 1 个 向量夹角分割 透视拉伸 视角倾斜 45° 像素长度失真 Homography + cosθ 补偿 实时性 720 p 30 fps CPU 满载 80 % NEON + ROI 裁剪 量化误差 像素 → 厘米 ±1 px ≈ ±0.8 cm 亚像素角点 零依赖 现场无网 Tesseract 不可用 纯 OpenCV
3 系统总体架构
4 硬件平台与接线
模块 接口 引脚 供电 备注 OV5640 MIPI-CSI CAM1 3.3 V 自带 24 MHz 时钟 OLED I²C1 PB8_SCL PB9_SDA 3.3 V 128×64 SSD1306 按键 GPIO PC13 3.3 V 一键启动 调试串口 UART0 PA9_TX PA10_RX 5 V→3.3 V CH340G
5 软件架构与线程模型
main.cpp 初始化摄像头 → 启动 4 个 std::thread
pic_deal.cpp thread_deal.cpp uart.cpp
6 算法流水线逐帧拆解
6.1 图像预处理
Mat gray;
cvtColor ( frame, gray, COLOR_BGR2GRAY) ;
Ptr< CLAHE> clahe = createCLAHE ( 2.0 , Size ( 8 , 8 ) ) ;
clahe-> apply ( gray, gray) ;
GaussianBlur ( gray, blur, Size ( 5 , 5 ) , 1 ) ;
Canny ( blur, edges, 50 , 150 ) ;
6.2 轮廓提取与面积过滤
vector< vector< Point>> contours;
findContours ( edges, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE) ;
vector< RotatedRect> candidates;
for ( auto & c : contours) { double a = contourArea ( c) ; if ( a < 500 || a > 0.3 * frame. total ( ) ) continue ; RotatedRect rr = minAreaRect ( c) ; float ratio = rr. size. width/ rr. size. height; if ( ratio > 0.9f && ratio < 1.1f ) candidates. push_back ( rr) ;
}
6.3 重叠正方形分割:向量夹角法
6.3.1 四边形顶点排序
vector< Point2f> orderPointsAlongContour ( const vector< Point> & contour, const vector< Point2f> & pts) { vector< float > cumLen ( contour. size ( ) ) ; float acc = 0 ; for ( size_t i= 1 ; i< contour. size ( ) ; ++ i) { acc += norm ( contour[ i] - contour[ i- 1 ] ) ; cumLen[ i] = acc; } return ordered;
}
6.3.2 向量夹角验证
const double ANGLE_THRESH = CV_PI/ 18.0 ;
for ( size_t i= 0 ; i< ordered. size ( ) ; i+= 4 ) { Point2f v1 = ordered[ ( i+ 1 ) % 4 ] - ordered[ i] ; Point2f v2 = ordered[ ( i+ 2 ) % 4 ] - ordered[ ( i+ 1 ) % 4 ] ; double angle = fabs ( atan2 ( v1. cross ( v2) , v1. dot ( v2) ) ) ; if ( angle < ANGLE_THRESH) { squares. emplace_back ( ordered[ i] , ordered[ ( i+ 1 ) % 4 ] ) ; }
}
6.4 最小正方形边长计算
double minSide = DBL_MAX;
for ( const auto & sq : squares) { double len = norm ( sq. first - sq. second) ; minSide = std:: min ( minSide, len * scale_w) ;
}
squareEdgeResult. minEdgeLength = minSide;
6.5 透视畸变补偿
Homography 计算 :利用 A4 纸 4 角点cosθ 修正 :
6.6 亚像素级优化
cornerSubPix ( gray, corners, Size ( 5 , 5 ) , Size ( - 1 , - 1 ) , TermCriteria ( TermCriteria:: EPS+ TermCriteria:: MAX_ITER, 30 , 0.001 ) ) ;
7 关键代码剖析
文件 职责 亮点 shibie_Square_min.cpp
重叠分割 + 最小边 向量夹角法零依赖 pic_deal.cpp
全流程 NEON intrinsics 加速 thread_deal.cpp
多线程 无锁队列 + condition_variable
8 香橙派编译与烧录
8.1 依赖
sudo apt update
sudo apt install build-essential cmake libopencv-dev
8.2 一键脚本
git clone https://github.com/langhaofu/2025-C-Software.git
cd 2025 -C-Advance
chmod +x build.sh run.sh
./build.sh
./run.sh
9 调试工具链
工具 用途 指令 htop
CPU 占用 htop
perf
NEON 指令 perf stat ./bin/2025_C
v4l2-ctl
摄像头参数 v4l2-ctl -d 0 --list-formats-ext
imwrite("debug.jpg")
中间结果 现场回溯
10 性能 Benchmark
场景 真值 测量 误差 耗时 两正方形重叠 25 % 最小 8 cm 8.1 cm 0.1 cm 1.7 s 三正方形并排 最小 6 cm 6.0 cm 0.0 cm 1.5 s 倾斜 40° 重叠 最小 10 cm 10.2 cm 0.2 cm 1.8 s 随机 5 正方形 最小 7 cm 7.1 cm 0.1 cm 1.6 s
11 常见问题 FAQ
问题 根因 解决 最小边 0 cm 角点 <4 个 降低 Canny 阈值 重叠未分割 面积过滤过严 调低 minArea CPU 100 % NEON 未开启 -mfpu=neon
画面卡顿 分辨率过高 锁 640×480
12 拓展阅读与开源仓库
GitHub:github.com/langhaofu/2025-C-Software 香橙派镜像:2025-C-ubuntu-22.04-lite.img.xz
本方案 纯 OpenCV 实现,已在现场验证 1.8 s 完成全流程。欢迎 Star & PR!