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

YOLOv5环境配置到Qt集成的完整指南

第一部分:环境配置

1.1 创建虚拟环境

推荐使用 Anaconda 管理 Python 环境

conda create -n yolov5 python=3.8 conda activate yolov5

注意:Python 版本要求 3.8 或更高。

1.2 安装 PyTorch

根据是否有 NVIDIA GPU 及 CUDA 版本选择对应命令

# CPU 版本 pip install torch torchvision torchaudio # GPU 版本(示例:CUDA 11.3) pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu113

PyTorch 版本要求 >=1.8。

1.3 克隆 YOLOv5 仓库并安装依赖

git clone https://github.com/ultralytics/yolov5.git cd yolov5 pip install -r requirements.txt

同时安装常用工具库:

pip install opencv-python matplotlib tqdm

1.4 验证安装

python detect.py --weights yolov5s.pt --source data/images/zidane.jpg

若能正常输出检测结果,则环境配置成功-

第二部分:数据集准备
2.1 数据集目录结构
YOLOv5 要求遵循以下标准目录结构

custom_dataset/ ├── images/ │ ├── train/ # 训练集图片 │ └── val/ # 验证集图片 └── labels/ ├── train/ # 训练集标注(.txt) └── val/ # 验证集标注(.txt)

图片与标签文件需同名(如 img1.jpg 对应 img1.txt)

2.2 标注文件格式

每个.txt标注文件每行代表一个检测框,格式为

<class_id> <x_center> <y_center> <width> <height>

所有坐标需归一化到 [0, 1] 区间。示例:

0 0.542 0.678 0.215 0.332

2.3 标注工具推荐
• LabelImg:基础矩形框标注,适合简单场景-
• CVAT:支持多边形、关键点标注,适合复杂场景-
• Roboflow:自动标注 + 数据增强-

2.4 创建数据集配置文件
在 data/ 目录下创建 custom.yaml

train: ../custom_dataset/images/train val: ../custom_dataset/images/val nc: 3 # 类别数量 names: ['defect1', 'defect2', 'defect3'] # 类别名称

第三部分:模型训练

3.1 选择模型规模

YOLOv5 提供五种规模模型:

模型速度特点
YOLOv5n最快(1.4ms/img)纳米版,适合边缘设备
YOLOv5s快(3.7ms/img)适合嵌入式设备
YOLOv5m平衡(5.6ms/img)平衡型
YOLOv5l高精度(7.8ms/img)高精度
YOLOv5x最高精度(11.7ms/img)最高精度

3.2 启动训练

python train.py --img 640 --batch 16 --epochs 300 \ --data custom.yaml --weights yolov5s.pt \ --cfg models/yolov5s.yaml --name custom_model

关键参数说明

显存不足时可减小 --batch-size

3.3 训练过程监控
使用 TensorBoard 可视化训练过程

tensorboard --logdir runs/train/exp

重点关注指标-

• box_loss:边界框回归损失
• obj_loss:目标存在性损失
• cls_loss:分类损失
• mAP@0.5:IoU=0.5 时的平均精度
训练完成后,模型权重保存在 runs/train/custom_model/weights/best.pt。

第四部分:模型导出(ONNX)
为了在 Qt 中部署,需要将 PyTorch 模型(.pt)转换为 ONNX 格式-
4.1 使用官方导出脚本

python models/export.py --weights runs/train/custom_model/weights/best.pt \ --include onnx --img 640 --batch 1

4.2 手动导出(备选方案)

import torch from models.experimental import attempt_load def convert_to_onnx(model_path, output_path, img_size=(640, 640), opset_version=12): model = attempt_load(model_path, map_location='cpu') model.eval() # 创建示例输入 img = torch.zeros(1, 3, *img_size) # 导出 ONNX torch.onnx.export( model, img, output_path, opset_version=opset_version, input_names=['images'], output_names=['output'] ) print(f"Model exported to {output_path}") convert_to_onnx('best.pt', 'best.onnx')

ONNX opset 版本建议 ≥11

第五部分:集成到 Qt 缺陷检测程序
集成方式主要有两种:Python(PyQt5)方案 和 C++(Qt + ONNX Runtime)方案。

方案一:Python + PyQt5(推荐快速开发)
这是最直接的方式,适合快速构建原型-
5.1 环境准备

pip install PyQt5 onnxruntime opencv-python
5.2 核心推理代码
import cv2 import onnxruntime as ort import numpy as np from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QPushButton, QFileDialog from PyQt5.QtGui import QPixmap, QImage from PyQt5.QtCore import Qt class YOLOv5Detector: def __init__(self, model_path): self.session = ort.InferenceSession(model_path) self.input_name = self.session.get_inputs()[0].name self.output_name = self.session.get_outputs()[0].name self.img_size = 640 def preprocess(self, img): # 调整大小并归一化 img = cv2.resize(img, (self.img_size, self.img_size)) img = img.transpose(2, 0, 1) # HWC -> CHW img = img.astype(np.float32) / 255.0 return np.expand_dims(img, axis=0) def detect(self, img): input_tensor = self.preprocess(img) outputs = self.session.run([self.output_name], {self.input_name: input_tensor}) # 后处理 NMS,提取检测框 return self.postprocess(outputs[0]) def postprocess(self, output): # 根据实际输出格式解析检测结果 # 返回: [(x1, y1, x2, y2, class_id, confidence), ...] pass
5.3 PyQt5 界面集成
class DefectDetectionWindow(QMainWindow): def __init__(self): super().__init__() self.detector = YOLOv5Detector('best.onnx') self.initUI() def initUI(self): self.setWindowTitle('缺陷检测系统') self.setGeometry(100, 100, 800, 600) # 图像显示标签 self.image_label = QLabel(self) self.image_label.setAlignment(Qt.AlignCenter) self.image_label.setStyleSheet("border: 1px solid gray;") # 按钮 self.btn_open = QPushButton('打开图片', self) self.btn_open.clicked.connect(self.open_image) self.btn_detect = QPushButton('开始检测', self) self.btn_detect.clicked.connect(self.detect_image) # 布局(略) def open_image(self): file_path, _ = QFileDialog.getOpenFileName( self, '选择图片', '', 'Images (*.png *.jpg *.jpeg)') if file_path: self.current_image = cv2.imread(file_path) self.display_image(self.current_image) def detect_image(self): if hasattr(self, 'current_image'): results = self.detector.detect(self.current_image) # 在图像上绘制检测框 annotated = self.draw_boxes(self.current_image.copy(), results) self.display_image(annotated) def display_image(self, img): # cv2 图像转 QPixmap rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) h, w, ch = rgb.shape bytes_per_line = ch * w qt_img = QImage(rgb.data, w, h, bytes_per_line, QImage.Format_RGB888) pixmap = QPixmap.fromImage(qt_img).scaled( self.image_label.width(), self.image_label.height(), Qt.KeepAspectRatio, Qt.SmoothTransformation) self.image_label.setPixmap(pixmap)
5.4 打包为独立可执行文件
pip install pyinstaller pyinstaller --onefile --windowed --add-data "best.onnx;." main.py

参考项目:yolov5-onnx-pyqt-exe

https://github.com/hhx518/yolov5-onnx-pyqt-exe

方案二:C++ + Qt + ONNX Runtime(高性能生产级)
适合对性能要求较高的工业场景

5.5 C++ 环境搭建
安装 Qt:
• 推荐 Qt 5.15.2 LTS
• 勾选 MinGW 64-bit 或 MSVC 编译器
安装 ONNX Runtime:
• 从 GitHub releases 下载预编译包
• 或自行编译-

安装 OpenCV:

# Ubuntu sudo apt install libopencv-dev # Windows: 从官网下载预编译二进制文件
5.6 Qt 项目配置(.pro 文件)
QT += core widgets gui CONFIG += c++17 INCLUDEPATH += /path/to/opencv/include \ /path/to/onnxruntime/include LIBS += -L/path/to/opencv/lib -lopencv_world450 \ -L/path/to/onnxruntime/lib -lonnxruntime SOURCES += main.cpp mainwindow.cpp detector.cpp HEADERS += mainwindow.h detector.h
5.7 ONNX Runtime 推理代码(detector.h)
#ifndef DETECTOR_H #define DETECTOR_H #include <opencv2/opencv.hpp> #include <onnxruntime/core/session/onnxruntime_cxx_api.h> #include <vector> struct Detection { cv::Rect box; int class_id; float confidence; }; class YOLOv5Detector { public: YOLOv5Detector(const std::string& model_path); std::vector<Detection> detect(const cv::Mat& image); private: Ort::Session session; Ort::MemoryInfo memory_info; std::vector<int64_t> input_shape; int img_size = 640; cv::Mat preprocess(const cv::Mat& image); std::vector<Detection> postprocess(const std::vector<float>& output, float conf_threshold = 0.5, float nms_threshold = 0.4); }; #endif
5.8 ONNX Runtime 推理代码(detector.cpp)
#include "detector.h" #include <onnxruntime/core/providers/cpu/cpu_provider_factory.h> YOLOv5Detector::YOLOv5Detector(const std::string& model_path) : memory_info(Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault)) { Ort::Env env(ORT_LOGGING_LEVEL_WARNING, "YOLOv5"); Ort::SessionOptions session_options; session_options.SetIntraOpNumThreads(1); // 使用 CPU 推理(可改为 CUDA) session_options.AppendExecutionProvider_CPU(0); session = Ort::Session(env, model_path.c_str(), session_options); // 获取输入形状 auto input_info = session.GetInputTypeInfo(0); auto input_tensor_info = input_info.GetTensorTypeAndShapeInfo(); input_shape = input_tensor_info.GetShape(); } cv::Mat YOLOv5Detector::preprocess(const cv::Mat& image) { cv::Mat resized; cv::resize(image, resized, cv::Size(img_size, img_size)); resized.convertTo(resized, CV_32FC3, 1.0 / 255.0); // HWC -> CHW cv::Mat channels[3]; cv::split(resized, channels); cv::Mat chw; cv::vconcat(channels[0], channels[1], chw); cv::vconcat(chw, channels[2], chw); return chw; } std::vector<Detection> YOLOv5Detector::detect(const cv::Mat& image) { cv::Mat input_tensor = preprocess(image); // 准备输入 std::vector<int64_t> input_shape = {1, 3, img_size, img_size}; Ort::Value input_tensor_ort = Ort::Value::CreateTensor<float>( memory_info, (float*)input_tensor.data, input_tensor.total() * input_tensor.elemSize(), input_shape.data(), input_shape.size() ); // 推理 auto output_tensors = session.Run( Ort::RunOptions{nullptr}, {"images"}, &input_tensor_ort, 1, {"output"}, 1 ); // 获取输出 float* output_data = output_tensors[0].GetTensorMutableData<float>(); auto output_shape = output_tensors[0].GetTensorTypeAndShapeInfo().GetShape(); size_t output_size = output_shape[1] * output_shape[2]; std::vector<float> output(output_data, output_data + output_size); // 后处理(NMS) return postprocess(output); }
5.9 Qt 主窗口集成
// mainwindow.h class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); private slots: void onOpenImage(); void onDetect(); private: Ui::MainWindow *ui; YOLOv5Detector* detector; cv::Mat current_image; QImage cvMatToQImage(const cv::Mat& mat); void displayImage(const cv::Mat& image); }; // mainwindow.cpp void MainWindow::onDetect() { if (current_image.empty()) return; auto detections = detector->detect(current_image); cv::Mat result = current_image.clone(); for (const auto& det : detections) { cv::rectangle(result, det.box, cv::Scalar(0, 255, 0), 2); std::string label = "Defect: " + std::to_string(det.class_id) + " " + std::to_string(det.confidence); cv::putText(result, label, cv::Point(det.box.x, det.box.y - 5), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 255, 0), 2); } displayImage(result); } QImage MainWindow::cvMatToQImage(const cv::Mat& mat) { cv::Mat rgb; cv::cvtColor(mat, rgb, cv::COLOR_BGR2RGB); return QImage(rgb.data, rgb.cols, rgb.rows, rgb.step, QImage::Format_RGB888); } void MainWindow::displayImage(const cv::Mat& image) { QImage qimg = cvMatToQImage(image); QPixmap pixmap = QPixmap::fromImage(qimg); ui->imageLabel->setPixmap(pixmap.scaled(ui->imageLabel->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); }

第六部分:性能优化建议

  1. GPU 推理:若硬件支持,将模型加载到 GPU 上推理

  2. 多线程处理:使用 QThread 将检测放在子线程,避免界面卡顿

  3. 图像预处理优化:减少不必要的图像处理步骤

  4. 批量推理:多张图片同时处理时使用 batch 推理

总结流程图

环境配置(Python 3.8 + PyTorch + YOLOv5) ↓ 准备数据集(images/ + labels/ + custom.yaml) ↓ 模型训练(python train.py ...) ↓ 模型导出(.pt → .onnx) ↓ ┌────┴────┐ ↓ ↓ PyQt5方案 C++方案 (Python) (Qt+ONNXRuntime) ↓ ↓ 打包部署 编译部署

以上步骤涵盖了从环境搭建、数据集准备、模型训练到 Qt 集成的完整流程。根据实际需求选择 Python(PyQt5)或 C++(Qt + ONNX Runtime)方案即可。

http://www.jsqmd.com/news/1145046/

相关文章:

  • 3 种工业镜头景深计算方案对比:公式、查表与仿真工具实测
  • 许可管理系统的四大核心功能,你都了解吗?
  • DMA 传输方向 + 配合ADC/UART/SPI 速记笔记
  • 如何高效推广GEO优化,抢占AI本地流量蓝海
  • 2026 福州全屋定制性价比排行:不同预算的选型参考
  • Gemini-3-Pro 提示词工程规范与 Python SDK 高级集成指南
  • 智能电视上有哪些好用的软件?
  • 泛程序收录低?这些优化解决方法值得一试
  • 彻底解决Python多版本冲突!下载安装+环境变量配置全流程详解!
  • 为什么说许可管理是企业数字化的基础工程?
  • 论文 AI 降重工具选型全指南:从安全、改写逻辑、查重适配三维筛选靠谱服务
  • Docker 镜像拉取失败:`failed commit on ref` 错误排查与 4 种镜像源修复方案
  • 豆包智能体对话怎么批量导出?Word/PDF/Excel 归档流程
  • OpenAI 微调权限收口后,先把评测和回退链路补起来
  • Postgresql 数据库 自增字段,Vastbase 无效的问题
  • 找到高薪工作的第一步:初步了解python
  • 磁吸转轴支架主流防松结构设计全解:5 类方案对比与选型指南
  • 如何用novel-downloader轻松下载全网100+小说网站?终极指南来了!
  • Linux 内核软中断子系统 九章编译法,AI直译完成汇编码
  • 我是如何利用 WorkBuddy 创建一个项目经营分析表解读 Skill 的
  • Spark 4.1.2 + Scala 2.13 开发环境:IntelliJ IDEA 2024.3 与 SBT 1.9.9 配置实战
  • 第二章Netty,EventLoop线程切换源码分析
  • Vben精讲:07-Vben环境配置详解
  • linux 7.1新版 | 大模型repo推荐
  • 迁安本地人认可的家电清洗机构家电清洗行业基础标准及要点解读
  • 模型量化 INT8 实战:PyTorch 静态量化 3 步实现 ResNet-18 推理加速 2.5 倍
  • BilibiliDown:B站视频下载的终极实战指南
  • 2026下半年环县事业单位机构TOP3测评|精准择校指南
  • 2026年AI站点开发系统有哪些,零代码与代码工具盘点
  • IPA 工作流、IPA Agent、GUI Agent:程序员视角下到底有什么区别?