基于YOLOv11的美国硬币识别系统开发实践

📅 2026/7/4 12:24:37
基于YOLOv11的美国硬币识别系统开发实践
1. 项目概述这个基于YOLOv11的美国硬币识别系统是我最近完成的一个计算机视觉项目它能够准确识别四种常见美国硬币Dime10美分、Nickel5美分、Penny1美分和Quarter25美分。作为一个经常需要处理硬币分类问题的开发者我发现市面上的通用识别方案往往在硬币这种小物体检测上表现不佳特别是在复杂背景下。于是决定基于最新的YOLOv11算法开发这个专用解决方案。系统最突出的特点是实现了95%以上的检测准确率这得益于三个关键设计首先采用了专门标注的硬币数据集其次优化了YOLOv11对小物体的检测能力最后通过多线程架构确保了实时性能。整个项目用Python实现包含完整的训练代码、预训练模型和带登录功能的用户界面非常适合需要硬币自动识别场景的开发者参考比如自动售货机、银行清分系统等应用。2. 技术架构解析2.1 YOLOv11模型选型选择YOLOv11作为基础模型主要基于以下考量实时性需求相比两阶段检测器如Faster R-CNN单阶段检测的YOLO系列更符合硬币检测对速度的要求。实测在RTX 3060显卡上YOLOv11s模型能达到120FPS的处理速度。小物体检测优化YOLOv11针对小目标新增了SPPFCSPC模块通过扩大感受野提升对小硬币的检测能力。我们在neck部分保留了4个检测头80x80到10x10确保不同尺度硬币都能被有效捕捉。模型轻量化项目提供了从nano到large五种预训练模型其中yolov11s.pt在准确率91.3%mAP和速度15ms/帧间取得了最佳平衡。2.2 数据处理管道数据集构建是项目成功的关键。我们收集了2000张包含四种硬币的图像涵盖以下场景不同光照条件自然光、室内灯光、低光照复杂背景桌面、手掌、包装袋多硬币重叠情况不同拍摄角度正面、侧面、倾斜标注采用YOLO格式每个硬币标注为class_id x_center y_center width height其中归一化坐标的计算公式为x_center (x_min x_max) / 2 / image_width y_center (y_min y_max) / 2 / image_height width (x_max - x_min) / image_width height (y_max - y_min) / image_height2.3 多线程架构设计系统采用生产者-消费者模式解决UI响应问题主线程处理用户交互和界面更新通过信号槽机制与检测线程通信检测线程继承QThread类独立运行检测算法。关键代码段class DetectionThread(QThread): frame_received pyqtSignal(np.ndarray, np.ndarray, list) def run(self): while self.running: ret, frame self.cap.read() results self.model(frame) self.frame_received.emit(original_frame, result_frame, detections)视频写入线程当启用视频保存时通过OpenCV的VideoWriter异步写入文件这种架构即使在处理1080p视频时也能保持界面流畅响应CPU占用率控制在30%以下。3. 核心实现细节3.1 模型训练优化训练配置采用以下关键参数lr0: 0.01 # 初始学习率 lrf: 0.1 # 最终学习率lr0*lrf momentum: 0.937 weight_decay: 0.0005 warmup_epochs: 3 batch: 8 # 根据GPU显存调整我们通过两种策略提升小硬币检测效果自适应锚框计算在data.yaml中预设硬币的典型尺寸anchors: - [4,5, 8,10, 13,16] # P3/8 - [23,29, 43,55, 73,105] # P4/16 - [146,217, 231,300, 335,433] # P5/32马赛克增强启用4图拼接增强大幅提升小目标检测鲁棒性3.2 界面交互实现UI采用PyQt5实现主要技术亮点包括双视图同步显示通过QLabelQPixmap实现实时画面更新def update_image(self, q_img): pixmap QPixmap.fromImage(q_img) self.label.setPixmap(pixmap.scaled( self.label.size(), Qt.KeepAspectRatio))参数联动控制置信度和IoU阈值使用QSlider与QDoubleSpinBox双向绑定self.conf_slider.valueChanged.connect( lambda v: self.conf_spin.setValue(v/100)) self.conf_spin.valueChanged.connect( lambda v: self.conf_slider.setValue(int(v*100)))科幻风格主题通过QSS实现动态光影效果QSlider::groove:horizontal { border: 1px solid #00ffff; height: 5px; background: qlineargradient(x1:0, y1:0, x2:1, y2:0, stop:0 #003333, stop:1 #00aaaa); }3.3 检测结果后处理从YOLO输出提取检测信息的核心逻辑def parse_detection(results): detections [] for box in results.boxes: cls int(box.cls) conf float(box.conf) xywh box.xywh[0].tolist() detections.append({ class: model.names[cls], confidence: conf, position: xywh }) return detections对于视频流处理额外增加了基于IOU的去重算法防止同一硬币在连续帧中被重复计数。4. 部署与优化指南4.1 环境配置要点推荐使用conda创建隔离环境conda create -n coin_det python3.9 conda activate coin_det pip install torch1.13.1cu117 torchvision0.14.1cu117 --extra-index-url https://download.pytorch.org/whl/cu117 pip install -r requirements.txt常见问题解决方案CUDA版本冲突可通过nvcc --version查看CUDA版本必须与PyTorch版本匹配DLL加载失败安装对应版本的VC_redist运行时库界面卡顿检查是否启用了GPU加速可通过torch.cuda.is_available()验证4.2 模型压缩技巧针对边缘设备部署我们测试了三种优化方案FP16量化模型大小减少50%速度提升20%精度损失1%model.export(formatonnx, halfTrue)TensorRT加速通过trtexec工具转换ONNX模型可获得3-5倍速度提升Pruning剪枝使用torch-pruner移除20%的冗余通道模型体积减少35%4.3 实际应用建议根据落地经验给出以下优化建议光照补偿在低光环境下建议先使用CLAHE算法增强对比度clahe cv2.createCLAHE(clipLimit2.0, tileGridSize(8,8)) gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) enhanced clahe.apply(gray)多角度检测对于叠放的硬币建议从至少两个不同角度拍摄动态阈值调整根据环境光线自动调节置信度阈值adaptive_conf 0.5 - 0.3*(image_brightness/255)5. 常见问题排查5.1 检测精度问题症状漏检或误检率高检查数据集确认标注是否准确特别是边缘模糊的硬币调整锚框使用k-means重新计算anchorsfrom utils.autoanchor import kmean_anchors kmean_anchors(datasetdata.yaml, n9, img_size640)增强策略增加旋转、模糊等数据增强5.2 性能问题症状检测速度慢检查硬件加速确认torch是否使用GPUprint(torch.cuda.current_device()) # 应返回0或以上降低输入分辨率将640x640调整为480x480results model(img, imgsz480)启用半精度FP16模式可提升30%速度model.half() # 转换模型权重为FP165.3 界面异常处理典型错误摄像头无法打开检查设备索引号多摄像头时可能需要尝试0-3视频播放卡顿降低解码分辨率或使用硬件加速cap cv2.VideoCapture(file_path, cv2.CAP_FFMPEG) cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc(*H264))内存泄漏定期清理Qt缓存对象def clear_memory(self): for label in [self.orig_label, self.result_label]: if label.pixmap(): label.pixmap().detach()6. 扩展开发方向当前系统已经支持以下扩展接口REST API集成通过Flask添加HTTP接口app.route(/detect, methods[POST]) def detect(): img request.files[image].read() results model(img) return jsonify(results)数量统计模块扩展硬币计数功能def count_coins(detections): counts defaultdict(int) for det in detections: counts[det[class]] 1 return counts金额计算根据硬币类型自动求和VALUE_MAP {Penny:0.01, Nickel:0.05, Dime:0.10, Quarter:0.25} total sum(VALUE_MAP[det[class]] for det in detections)对于需要更高精度的场景建议尝试以下改进增加红外成像模块处理反光硬币集成重量传感器进行多模态验证使用超分辨率网络预处理低质量图像