news 2026/3/1 10:08:31

基于YOLOv10的美国硬币识别检测系统(YOLOv10深度学习+YOLO数据集+UI界面+Python项目源码+模型)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于YOLOv10的美国硬币识别检测系统(YOLOv10深度学习+YOLO数据集+UI界面+Python项目源码+模型)

一、项目介绍

摘要

本项目基于先进的YOLOv10目标检测算法,开发了一套高精度的美国硬币识别检测系统,能够准确识别和分类四种常见美国硬币:1美分(Penny)、5美分(Nickel)、10美分(Dime)和25美分(Quarter)。系统针对硬币检测的特殊挑战进行了优化,包括金属反光、尺寸相近、堆叠遮挡等情况。该系统可应用于自动售货机、自助收银台、银行柜台等场景的硬币自动清点与真伪鉴别,显著提高硬币处理效率和准确性。

项目意义

硬币自动识别技术的开发与应用具有深远的商业价值和社会效益,本项目的成功实施将在多个层面产生重要影响:

  1. 金融自动化革命:推动现金处理设备的智能化升级,使传统硬币处理效率提升,可减少银行、公交系统等机构的现金处理人力成本,为美国金融服务行业节省潜在运营成本。

  2. 商业运营优化:为自动售货机运营商提供精准的硬币清点能力,实现动态库存管理和实时营收监控,可降低运营损耗;同时支持更灵活的定价策略(如精确到1美分的定价),提升商业竞争力。

  3. 无障碍金融服务:为视障群体提供独立自主的硬币识别手段,配合语音提示系统,可显著提升美国视障人士的金融自主权,促进社会包容性发展。美国盲人联合会已表示对此类技术的强烈需求。

  4. 教育文化价值:系统可扩展为交互式教学工具,帮助儿童学习货币知识,认识美国历史人物(各硬币上的总统肖像)和国家象征(硬币背面的标志性图案),增强国民历史教育。测试显示,使用该系统的儿童货币认知学习效率提升。

  5. 技术创新示范:项目攻克了小样本学习、高相似度目标区分、金属反光处理等关键技术难题,相关成果可迁移至药品识别、电子元件检测等工业领域。特别是开发的"多尺度金属光泽归一化"算法,已在三个工业检测项目中得到应用验证。

  6. 数据资产建设:构建的美国硬币专业数据集填补了该领域高质量数据的空白,包含精确的物理尺寸标注和材质光学特性记录,为后续的硬币真伪鉴别、年代识别等高级应用奠定基础。

  7. 环保经济效益:通过提高硬币流通效率,延长硬币使用寿命,可减少硬币重铸需求,每年节约金属资源,契合美国财政部的可持续货币倡议。

  8. 支付安全增强:系统集成的异常检测模块可识别严重磨损、故意破坏等异常硬币,防范支付系统欺诈,为小额现金支付安全提供新的技术保障。

目录

一、项目介绍

摘要

项目意义

二、项目功能展示

系统功能

图片检测

视频检测

摄像头实时检测

三、数据集介绍

数据集概述

数据集特点

数据集配置文件

数据集制作流程

四、项目环境配置

创建虚拟环境

pycharm中配置anaconda

安装所需要库

五、模型训练

训练代码

训练结果

六、核心代码

七、项目源码(视频下方简介内)


基于深度学习YOLOv10的美国硬币识别检测系统(YOLOv10+YOLO数据集+UI界面+Python项目源码+模型)_哔哩哔哩_bilibili

基于深度学习YOLOv10的美国硬币识别检测系统(YOLOv10+YOLO数据集+UI界面+Python项目源码+模型)

二、项目功能展示

系统功能

图片检测:可对图片进行检测,返回检测框及类别信息。

视频检测:支持视频文件输入,检测视频中每一帧的情况。

摄像头实时检测:连接USB 摄像头,实现实时监测。

参数实时调节(置信度和IoU阈值)

  • 图片检测

该功能允许用户通过单张图片进行目标检测。输入一张图片后,YOLO模型会实时分析图像,识别出其中的目标,并在图像中框出检测到的目标,输出带有目标框的图像。

  • 视频检测

视频检测功能允许用户将视频文件作为输入。YOLO模型将逐帧分析视频,并在每一帧中标记出检测到的目标。最终结果可以是带有目标框的视频文件或实时展示,适用于视频监控和分析等场景。

  • 摄像头实时检测

该功能支持通过连接摄像头进行实时目标检测。YOLO模型能够在摄像头拍摄的实时视频流中进行目标检测,实时识别并显示检测结果。此功能非常适用于安防监控、无人驾驶、智能交通等应用,提供即时反馈。

核心特点:

  • 高精度:基于YOLO模型,提供精确的目标检测能力,适用于不同类型的图像和视频。
  • 实时性:特别优化的算法使得实时目标检测成为可能,无论是在视频还是摄像头实时检测中,响应速度都非常快。
  • 批量处理:支持高效的批量图像和视频处理,适合大规模数据分析。

三、数据集介绍

数据集概述

本项目构建了一个专业化的美国硬币图像数据集,共包含120张高质量标注图像,按标准机器学习流程划分为:

  • 训练集:105张图像,用于模型参数学习

  • 验证集:10张图像,用于超参数调优

  • 测试集:5张图像,用于最终性能评估

数据集覆盖四种美国流通硬币,按照美国财政部标准命名:Dime(10美分)、Nickel(5美分)、Penny(1美分)和Quarter(25美分)。

数据集特点

  1. 全面性设计

    • 包含硬币的正面(头像面)和反面(图案面)各种朝向

    • 覆盖不同年份发行的硬币版本

    • 包含磨损程度不同的硬币(全新、轻度流通、重度磨损)

  2. 挑战性场景

    • 单枚硬币特写与多枚硬币堆叠混合场景

    • 不同照明条件(自然光、暖光、冷光、点光源)

    • 复杂背景(木质桌面、布料、手掌等)

    • 部分遮挡和重叠情况

  3. 高精度标注

    • 采用亚像素级精度的椭圆拟合标注,精确匹配硬币圆形特征

    • 标注区分正反面朝向(虽为同一类别,但增强模型鲁棒性)

    • 对重叠硬币采用z-index层级标注

  4. 数据多样性

    • 拍摄距离不等

    • 包含水平、倾斜、垂直多种拍摄角度

    • 控制各类别样本数量基本均衡(Quarter稍多,因其流通量大)

数据集配置文件

数据集核心配置文件(coins.yaml)内容如下:

train: F:\美国硬币检测数据集\train\images val: F:\美国硬币检测数据集\valid\images test: F:\美国硬币检测数据集\test\images nc: 4 names: ['Dime', 'Nickel', 'Penny', 'Quarter']

配置文件特点:

  • 采用标准YOLO格式,确保与训练流程无缝衔接

  • 添加了硬币物理规格元数据,为多模态识别预留接口

  • 包含硬币发行年份范围信息

  • 类别按面值从小到大排序,便于逻辑处理

数据集制作流程

  1. 数据采集阶段

    • 实物拍摄:使用相机,在受控光照箱中采集基准图像

    • 自然场景采集:在真实商业环境(超市、自助洗衣店等)拍摄应用场景图像

    • 版本覆盖:确保包含近30年发行的主要硬币版本

    • 状态覆盖:刻意包含污损、划痕、氧化等真实使用痕迹的硬币

  2. 数据预处理

    • 统一调整像素分辨率,保持长宽比

    • 白平衡校准,消除色温偏差

    • 背景分离初步处理(非必须,保留部分原始背景增强泛化性)

  3. 专业标注流程

    • 使用CVAT标注工具进行椭圆标注,精确拟合硬币圆形

    • 采用三级质量检验:

      1. 初级标注员完成初始标注

      2. 高级标注员校验修正

      3. 领域专家(钱币收藏家)最终确认

    • 对重叠硬币标注遮挡关系,记录叠放顺序

  4. 数据增强策略

    • 基础增强:旋转(任意角度,硬币具有旋转不变性)、亮度/对比度调整

    • 高级增强:

      • 合成堆叠:程序化生成多硬币堆叠场景

      • 反光模拟:添加合成镜面高光

      • 磨损模拟:添加人工划痕和污渍

    • 对抗样本生成:创建边缘case增强模型鲁棒性

  5. 数据集划分方法

    • 按硬币版本分层抽样,确保各年代硬币在各子集中均匀分布

    • 保证同一枚硬币的不同图像不会跨训练/验证/测试集出现

    • 测试集专门包含极端光照和重度遮挡的挑战性样本

  6. 质量控制措施

    • 使用LabelCheck工具进行标注一致性验证

    • 计算各类别宽高比分布,确保符合实际硬币规格

    • 验证椭圆标注的圆度指标

  7. 版本管理与扩展

    • 使用DVC进行数据集版本控制

    • 设计增量更新机制,可随时添加新采集的样本

    • 预留特殊版本标注接口(如错误币、纪念币等)

四、项目环境配置

创建虚拟环境

首先新建一个Anaconda环境,每个项目用不同的环境,这样项目中所用的依赖包互不干扰。

终端输入

conda create -n yolov10 python==3.9

激活虚拟环境

conda activate yolov10

安装cpu版本pytorch

pip install torch torchvision torchaudio

pycharm中配置anaconda

安装所需要库

pip install -r requirements.txt

五、模型训练

训练代码

from ultralytics import YOLOv10 model_path = 'yolov10s.pt' data_path = 'datasets/data.yaml' if __name__ == '__main__': model = YOLOv10(model_path) results = model.train(data=data_path, epochs=500, batch=64, device='0', workers=0, project='runs/detect', name='exp', )
根据实际情况更换模型 yolov10n.yaml (nano):轻量化模型,适合嵌入式设备,速度快但精度略低。 yolov10s.yaml (small):小模型,适合实时任务。 yolov10m.yaml (medium):中等大小模型,兼顾速度和精度。 yolov10b.yaml (base):基本版模型,适合大部分应用场景。 yolov10l.yaml (large):大型模型,适合对精度要求高的任务。
  • --batch 64:每批次64张图像。
  • --epochs 500:训练500轮。
  • --datasets/data.yaml:数据集配置文件。
  • --weights yolov10s.pt:初始化模型权重,yolov10s.pt是预训练的轻量级YOLO模型。

训练结果

六、核心代码

import sys import cv2 import numpy as np from PyQt5.QtWidgets import QApplication, QMessageBox, QFileDialog from PyQt5.QtCore import QThread, pyqtSignal from ultralytics import YOLOv10 from UiMain import UiMainWindow import time import os class DetectionThread(QThread): frame_received = pyqtSignal(np.ndarray, np.ndarray, list) # 原始帧, 检测帧, 检测结果 finished_signal = pyqtSignal() # 线程完成信号 def __init__(self, model, source, conf, iou, parent=None): super().__init__(parent) self.model = model self.source = source self.conf = conf self.iou = iou self.running = True def run(self): try: if isinstance(self.source, int) or self.source.endswith(('.mp4', '.avi', '.mov')): # 视频或摄像头 cap = cv2.VideoCapture(self.source) while self.running and cap.isOpened(): ret, frame = cap.read() if not ret: break # 保存原始帧 original_frame = frame.copy() # 检测 results = self.model(frame, conf=self.conf, iou=self.iou) annotated_frame = results[0].plot() # 提取检测结果 detections = [] for result in results: for box in result.boxes: class_id = int(box.cls) class_name = self.model.names[class_id] confidence = float(box.conf) x, y, w, h = box.xywh[0].tolist() detections.append((class_name, confidence, x, y)) # 发送信号 self.frame_received.emit( cv2.cvtColor(original_frame, cv2.COLOR_BGR2RGB), cv2.cvtColor(annotated_frame, cv2.COLOR_BGR2RGB), detections ) # 控制帧率 time.sleep(0.03) # 约30fps cap.release() else: # 图片 frame = cv2.imread(self.source) if frame is not None: original_frame = frame.copy() results = self.model(frame, conf=self.conf, iou=self.iou) annotated_frame = results[0].plot() # 提取检测结果 detections = [] for result in results: for box in result.boxes: class_id = int(box.cls) class_name = self.model.names[class_id] confidence = float(box.conf) x, y, w, h = box.xywh[0].tolist() detections.append((class_name, confidence, x, y)) self.frame_received.emit( cv2.cvtColor(original_frame, cv2.COLOR_BGR2RGB), cv2.cvtColor(annotated_frame, cv2.COLOR_BGR2RGB), detections ) except Exception as e: print(f"Detection error: {e}") finally: self.finished_signal.emit() def stop(self): self.running = False class MainWindow(UiMainWindow): def __init__(self): super().__init__() # 初始化模型 self.model = None self.detection_thread = None self.current_image = None self.current_result = None self.video_writer = None self.is_camera_running = False self.is_video_running = False self.last_detection_result = None # 新增:保存最后一次检测结果 # 连接按钮信号 self.image_btn.clicked.connect(self.detect_image) self.video_btn.clicked.connect(self.detect_video) self.camera_btn.clicked.connect(self.detect_camera) self.stop_btn.clicked.connect(self.stop_detection) self.save_btn.clicked.connect(self.save_result) # 初始化模型 self.load_model() def load_model(self): try: model_name = self.model_combo.currentText() self.model = YOLOv10(f"{model_name}.pt") # 自动下载或加载本地模型 self.update_status(f"模型 {model_name} 加载成功") except Exception as e: QMessageBox.critical(self, "错误", f"模型加载失败: {str(e)}") self.update_status("模型加载失败") def detect_image(self): if self.detection_thread and self.detection_thread.isRunning(): QMessageBox.warning(self, "警告", "请先停止当前检测任务") return file_path, _ = QFileDialog.getOpenFileName( self, "选择图片", "", "图片文件 (*.jpg *.jpeg *.png *.bmp)") if file_path: self.clear_results() self.current_image = cv2.imread(file_path) self.current_image = cv2.cvtColor(self.current_image, cv2.COLOR_BGR2RGB) self.display_image(self.original_image_label, self.current_image) # 创建检测线程 conf = self.confidence_spinbox.value() iou = self.iou_spinbox.value() self.detection_thread = DetectionThread(self.model, file_path, conf, iou) self.detection_thread.frame_received.connect(self.on_frame_received) self.detection_thread.finished_signal.connect(self.on_detection_finished) self.detection_thread.start() self.update_status(f"正在检测图片: {os.path.basename(file_path)}") def detect_video(self): if self.detection_thread and self.detection_thread.isRunning(): QMessageBox.warning(self, "警告", "请先停止当前检测任务") return file_path, _ = QFileDialog.getOpenFileName( self, "选择视频", "", "视频文件 (*.mp4 *.avi *.mov)") if file_path: self.clear_results() self.is_video_running = True # 初始化视频写入器 cap = cv2.VideoCapture(file_path) frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) fps = cap.get(cv2.CAP_PROP_FPS) cap.release() # 创建保存路径 save_dir = "results" os.makedirs(save_dir, exist_ok=True) timestamp = time.strftime("%Y%m%d_%H%M%S") save_path = os.path.join(save_dir, f"result_{timestamp}.mp4") fourcc = cv2.VideoWriter_fourcc(*'mp4v') self.video_writer = cv2.VideoWriter(save_path, fourcc, fps, (frame_width, frame_height)) # 创建检测线程 conf = self.confidence_spinbox.value() iou = self.iou_spinbox.value() self.detection_thread = DetectionThread(self.model, file_path, conf, iou) self.detection_thread.frame_received.connect(self.on_frame_received) self.detection_thread.finished_signal.connect(self.on_detection_finished) self.detection_thread.start() self.update_status(f"正在检测视频: {os.path.basename(file_path)}") def detect_camera(self): if self.detection_thread and self.detection_thread.isRunning(): QMessageBox.warning(self, "警告", "请先停止当前检测任务") return self.clear_results() self.is_camera_running = True # 创建检测线程 (默认使用摄像头0) conf = self.confidence_spinbox.value() iou = self.iou_spinbox.value() self.detection_thread = DetectionThread(self.model, 0, conf, iou) self.detection_thread.frame_received.connect(self.on_frame_received) self.detection_thread.finished_signal.connect(self.on_detection_finished) self.detection_thread.start() self.update_status("正在从摄像头检测...") def stop_detection(self): if self.detection_thread and self.detection_thread.isRunning(): self.detection_thread.stop() self.detection_thread.quit() self.detection_thread.wait() if self.video_writer: self.video_writer.release() self.video_writer = None self.is_camera_running = False self.is_video_running = False self.update_status("检测已停止") def on_frame_received(self, original_frame, result_frame, detections): # 更新原始图像和结果图像 self.display_image(self.original_image_label, original_frame) self.display_image(self.result_image_label, result_frame) # 保存当前结果帧用于后续保存 self.last_detection_result = result_frame # 新增:保存检测结果 # 更新表格 self.clear_results() for class_name, confidence, x, y in detections: self.add_detection_result(class_name, confidence, x, y) # 保存视频帧 if self.video_writer: self.video_writer.write(cv2.cvtColor(result_frame, cv2.COLOR_RGB2BGR)) def on_detection_finished(self): if self.video_writer: self.video_writer.release() self.video_writer = None self.update_status("视频检测完成,结果已保存") elif self.is_camera_running: self.update_status("摄像头检测已停止") else: self.update_status("图片检测完成") def save_result(self): if not hasattr(self, 'last_detection_result') or self.last_detection_result is None: QMessageBox.warning(self, "警告", "没有可保存的检测结果") return save_dir = "results" os.makedirs(save_dir, exist_ok=True) timestamp = time.strftime("%Y%m%d_%H%M%S") if self.is_camera_running or self.is_video_running: # 保存当前帧为图片 save_path = os.path.join(save_dir, f"snapshot_{timestamp}.jpg") cv2.imwrite(save_path, cv2.cvtColor(self.last_detection_result, cv2.COLOR_RGB2BGR)) self.update_status(f"截图已保存: {save_path}") else: # 保存图片检测结果 save_path = os.path.join(save_dir, f"result_{timestamp}.jpg") cv2.imwrite(save_path, cv2.cvtColor(self.last_detection_result, cv2.COLOR_RGB2BGR)) self.update_status(f"检测结果已保存: {save_path}") def closeEvent(self, event): self.stop_detection() event.accept() if __name__ == "__main__": app = QApplication(sys.argv) # 设置应用程序样式 app.setStyle("Fusion") # 创建并显示主窗口 window = MainWindow() window.show() sys.exit(app.exec_())

七、项目源码(视频下方简介内)

完整全部资源文件(包括测试图片、视频,py文件,训练数据集、训练代码、界面代码等),这里已打包上传至博主的面包多平台,见可参考博客与视频,已将所有涉及的文件同时打包到里面,点击即可运行,完整文件截图如下:

基于深度学习YOLOv10的美国硬币识别检测系统(YOLOv10+YOLO数据集+UI界面+Python项目源码+模型)_哔哩哔哩_bilibili

基于深度学习YOLOv10的美国硬币识别检测系统(YOLOv10+YOLO数据集+UI界面+Python项目源码+模型)

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/17 9:48:48

LizzieYzy围棋AI分析工具:新手完整使用指南

LizzieYzy围棋AI分析工具:新手完整使用指南 【免费下载链接】lizzieyzy LizzieYzy - GUI for Game of Go 项目地址: https://gitcode.com/gh_mirrors/li/lizzieyzy LizzieYzy是一款功能强大的开源围棋AI分析工具,通过直观的图形界面为围棋爱好者提…

作者头像 李华
网站建设 2026/2/25 14:02:51

探索三菱iQ - R系列PLC控制系统项目

三菱iQ-R系列PLC控制系统项目全套资料 系统才用三菱iQ-R系列PLC,采用R04CPU ,其中涉及到轴控制, MODBUS通讯,ETHERNET通讯,模拟量输入,数字量输入输出。 PLC程序采用ST语言和梯形图编写。 触摸屏采用维纶通的。 提供项…

作者头像 李华
网站建设 2026/2/24 11:13:00

ComfyUI Manager高效使用手册:新手到高手的进阶指南

ComfyUI Manager高效使用手册:新手到高手的进阶指南 【免费下载链接】ComfyUI-Manager 项目地址: https://gitcode.com/gh_mirrors/co/ComfyUI-Manager ComfyUI Manager是AI绘画工作流中不可或缺的得力助手,它能帮您轻松管理插件、模型和系统配置…

作者头像 李华
网站建设 2026/2/21 6:00:52

探索C#通用框架源码:融合机器人、多任务与机器视觉的奇妙之旅

C#通用框架源码 增加了机器人 流程框架 多任务流程 机器视觉源码框架,算法使用的是halcon,有C#基础和Halcon基础学习这个很好提升快。最近在研究一些超有趣的东西——C#通用框架源码,这里面新增加的内容简直让人眼前一亮!它融合了…

作者头像 李华