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

使用OpenCV训练自有模型的实践

技术博客:基于OpenCV与YOLOv8的自有模型训练实践

1. 项目背景与目标

在众多计算机视觉任务中,目标检测是一项核心且广泛应用于实际场景的技术。本项目旨在通过使用 OpenCV 和 YOLOv8 模型,实现对特定目标(如舌头)的检测。整个过程涵盖了数据准备、模型训练、验证评估及结果输出等多个环节。

2. 系统架构
2.1 数据集结构

数据集的组织结构直接影响到模型的训练效果。本项目的数据集结构如下:

dataset/
├── images/
│   ├── train/
│   │   ├── img1.jpg
│   │   └── img2.jpg
│   └── val/
│       ├── img1.jpg
│       └── img2.jpg
└── labels/├── train/│   ├── img1.xml│   └── img2.xml└── val/├── img1.txt└── img2.txt
  • images/:存放图像文件,分为 train(训练集)和 val(验证集)两个子目录。
  • labels/:存放对应的标注文件,格式为 YOLO 标注格式(.txt 文件)。
2.2 模型架构

本项目采用的是 YOLOv8 模型,该模型具有以下特点:

  • 高效性:YOLOv8 在保持高精度的同时,拥有较快的推理速度。
  • 灵活性:支持多种任务(如分类、检测、分割等),并且可以通过简单的配置进行定制。
  • 易用性:Ultralytics 提供了简洁的 API,方便用户快速上手。
3. 实现原理
3.1 YOLO 标注格式

YOLO 标注格式是一种简单且高效的标注方式,每个 .txt 文件对应一张图像,内容格式如下:

<class_id> <x_center> <y_center> <width> <height>
  • class_id:类别编号(从0开始)。
  • x_center, y_center:边界框中心点坐标(相对于图像宽度和高度的归一化值)。
  • width, height:边界框宽高(同样归一化)。
3.2 数据预处理

数据预处理是模型训练前的重要步骤,主要包括:

  • 图像读取与转换:使用 OpenCV 读取图像,并将其转换为适合模型输入的格式。
  • 标注文件解析:解析 YOLO 格式的标注文件,提取边界框和类别信息。
  • 数据增强:通过随机裁剪、翻转、颜色抖动等方法增加数据多样性,提升模型泛化能力。
3.3 模型训练

模型训练基于 YOLOv8 的标准流程,具体步骤如下:

  1. 加载模型:通过 YOLO('yolov8n.yaml') 或加载预训练模型来初始化模型。
  2. 配置数据集:编写 [custom_dataset.yaml]文件,指定训练集和验证集的路径。
  3. 启动训练:调用 model.train(data='custom_dataset.yaml') 方法开始训练。
train: ../images/train
val: ../images/valnc: 1  # 类别数量,根据你的数据集修改
names: ['tongue']  # 类别名称列表,例如 ['car'], ['person'] 等
3.4 模型验证

模型训练完成后,需要对其进行验证以评估性能。主要步骤包括:

  • 加载模型:使用训练好的模型权重文件(如 [best.pt](file:///Users/franks/workspace/AI/ModelTrain/models/yolov8_custom_train/weights/best.pt))。
  • 验证评估:调用 model.val() 方法进行验证,并输出 mAP 等指标。
4. 技术实现细节
4.1 数据集准备

数据集的准备主要包括图像采集、标注及格式转换。具体实现可参考 [valImg.py]文件:

import os
import xml.etree.ElementTree as ET
import cv2# 设置路径
ANNOTATION_DIR = 'data/labels/train'
IMAGE_DIR = 'data/images/train'
VAL_IMAGE_DIR = 'data/images/val'
VAL_LABEL_DIR = 'data/labels/val'os.makedirs(VAL_IMAGE_DIR, exist_ok=True)
os.makedirs(VAL_LABEL_DIR, exist_ok=True)def parse_voc_xml(xml_path):tree = ET.parse(xml_path)root = tree.getroot()filename = root.find('filename').textimg_path = os.path.join(IMAGE_DIR, filename)# 支持常见图像格式(.jpg .png .jpeg .webp)for ext in ['.jpg', '.png', '.jpeg', '.webp']:if os.path.exists(img_path.replace('.webp', ext)):img_path = img_path.replace('.webp', ext)breakif not os.path.exists(img_path):print(f"Image not found: {img_path}")return Nonesize = root.find('size')img_w = int(size.find('width').text)img_h = int(size.find('height').text)objects = []for obj in root.findall('object'):name = obj.find('name').textbndbox = obj.find('bndbox')xmin = int(bndbox.find('xmin').text)ymin = int(bndbox.find('ymin').text)xmax = int(bndbox.find('xmax').text)ymax = int(bndbox.find('ymax').text)objects.append({'class': name,'bbox': [xmin, ymin, xmax, ymax]})return img_path, img_w, img_h, objects# 处理所有 XML 文件
for xml_file in os.listdir(ANNOTATION_DIR):if not xml_file.endswith('.xml'):continuexml_path = os.path.join(ANNOTATION_DIR, xml_file)result = parse_voc_xml(xml_path)if not result:continueimg_path, img_w, img_h, objects = resultimg = cv2.imread(img_path)for i, obj in enumerate(objects):cls_name = obj['class']xmin, ymin, xmax, ymax = obj['bbox']# 裁剪图像cropped = img[ymin:ymax, xmin:xmax]# 保存为 val 图像base_name = os.path.splitext(os.path.basename(img_path))[0]new_img_name = f"{base_name}_{i}.jpg"new_img_path = os.path.join(VAL_IMAGE_DIR, new_img_name)cv2.imwrite(new_img_path, cropped)# 保存标注文件(YOLO 格式)xc = (xmin + xmax) / 2 / img_wyc = (ymin + ymax) / 2 / img_hw = (xmax - xmin) / img_wh = (ymax - ymin) / img_hlabel_path = os.path.join(VAL_LABEL_DIR, new_img_name.replace('.jpg', '.txt'))with open(label_path, 'w') as f:class_id = 0  # 假设只有一类 "tongue"f.write(f"{class_id} {xc:.6f} {yc:.6f} {w:.6f} {h:.6f}\n")print("✅ Val 图像及标注文件已生成!")
4.2 模型训练

模型训练的核心代码位于 train.py 文件中:

from ultralytics import YOLO# 加载预训练模型(如 yolov8n.pt, yolov8s.pt 等)
model = YOLO('models/yolov8s.pt')# 开始训练
results = model.train(data='data/custom_dataset.yaml',  # 自定义数据集配置文件路径epochs=100,                       # 总训练轮数imgsz=640,                        # 输入图像尺寸batch=16,                         # 批处理大小name='yolov8_custom_train',       # 训练结果保存的目录名project='models/',                # 模型保存的项目路径exist_ok=True                     # 是否允许覆盖已存在的训练结果目录
)
4.3 模型导出

模型训练完成后,可以将其导出为标准的 .pt 文件,便于部署和使用:

from ultralytics import YOLO# 加载自定义训练模型
model = YOLO('models/yolov8_custom_train/weights/best.pt')# 保存为标准 pt 文件(可选)
model.save('models/yolov8_model_tongue.pt')
5. 结果输出与分析
5.1 验证指标

模型验证的主要指标包括 mAP(Mean Average Precision):

  • mAP50:IoU 阈值为 0.5 时的平均精度。
  • mAP50-95:IoU 阈值在 [0.5, 0.95] 范围内的平均精度。

这些指标越高,表示模型的检测性能越好。通常,mAP50 > 0.7 即认为模型表现良好。

from ultralytics import YOLOmodel = YOLO('models/yolov8_custom_train/weights/best.pt')  # 加载训练好的模型
metrics = model.val()  # 开始验证
print(metrics.box.map)    # mAP50
print(metrics.box.map50)  # mAP50-95  这些指标越高越好,通常 mAP50 > 0.7 表示模型表现良好。
5.2 可视化结果

为了更直观地展示模型的检测效果,可以使用 Ultralytics 提供的可视化工具:

from ultralytics import YOLOmodel = YOLO('models/yolov8_custom_train/weights/best.pt')
model.val(data='data/custom_dataset.yaml')

这将显示每张图上的边界框,帮助我们验证标注是否准确以及模型的检测效果。

6. 总结与展望

本文介绍了基于 OpenCV 和 YOLOv8 的自有模型训练实践,从数据集准备、模型训练、验证评估到结果输出,提供了一套完整的解决方案。未来的工作可以进一步优化数据增强策略、调整模型超参数,以提升模型的检测精度和鲁棒性。

希望本文能为读者在目标检测领域的研究和应用提供有价值的参考。如果你有任何问题或建议,欢迎留言交流!

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

相关文章:

  • 飞算科技:以自主技术创新推动行业数字化升级
  • Java学习第五部分——API部分
  • 【DICOM后处理】qt+vs 实现DICOM数据四视图显示
  • LeetCode--39.组合总和
  • Oracle 数据塑形:行列转换与集合运算
  • QT记事本3——下拉框comboBox、下拉框编码值传给QTextStream类
  • 【BERT_Pretrain】Wikipedia_Bookcorpus数据预处理(二)
  • Electron 快速上手
  • vscode vim插件示例json意义
  • C++ 第四阶段 文件IO - 第一节:ifstream/ofstream操作
  • JavaScript---查询数组符合条件的元素
  • 解决 npm install canvas@2.11.2 失败的问题
  • 【公司环境下发布个人NPM包完整教程】
  • SPI、I2C和UART三种串行通信协议的--------简单总结
  • NLP:文本张量表示方法
  • 【安全工具】SQLMap 使用详解:从基础到高级技巧
  • 【字节跳动】数据挖掘面试题0001:打车场景下POI与ODR空间关联查询
  • C++实现状态机
  • 20250703|Leetcodehot100之739【】今天计划
  • Linux环境下使用 C++ 与 OpenCV 实现 ONNX 分类模型推理
  • 洛谷P2119 [NOIP 2016 普及组] 魔法阵【题解】【前缀和优化】
  • Java 大视界 -- Java 大数据在智能医疗健康管理中的慢性病风险预测与个性化干预(330)
  • Javaee 多线程 --进程和线程之间的区别和联系
  • nvm:NodeJs版本管理工具下载安装与使用教程
  • macOS挂载iOS应用沙盒文件夹
  • 飞算 JavaAI 智控引擎:全链路开发自动化新图景
  • 【字节跳动】数据挖掘面试题0003:有一个文件,每一行是一个数字,如何用 MapReduce 进行排序和求每个用户每个页面停留时间
  • 橡胶硬度计在不同领域中的应用
  • mybatis考试
  • 无人机一机多控技术的核心要点