YOLOv8轴承缺陷检测实战:从原理到工业应用完整指南

YOLOv8轴承缺陷检测实战:从原理到工业应用完整指南
在工业质检领域轴承缺陷检测一直是个技术难点。传统人工检测效率低、主观性强而基于传统机器视觉的方法对复杂缺陷和背景干扰的适应性较差。最近在项目中尝试使用YOLOv8构建轴承缺陷检测系统取得了mAP50达到0.995的优异效果下面完整分享从环境搭建到模型训练的全流程实战经验。这套方案特别适合有一定Python基础的开发者无论是学生做课题研究还是工程师进行工业应用开发都能快速上手。本文将重点讲解YOLOv8的核心原理、环境配置、数据准备、模型训练技巧以及完整的UI界面开发提供可复现的代码示例。1. YOLOv8技术背景与核心优势1.1 YOLOv8在工业缺陷检测中的价值YOLOv8是Ultralytics公司推出的最新一代目标检测算法相比前代版本在精度和速度上都有显著提升。在工业缺陷检测场景中轴承表面缺陷通常具有尺度小、形态多变、背景复杂等特点YOLOv8通过以下技术创新有效应对这些挑战C2f模块替换了原来的C3模块通过更多的跨层连接增强了特征提取能力对于微小的轴承缺陷特征捕捉更加敏感解耦检测头将分类和回归任务分离减少了任务间的干扰提升了小目标检测的精度Anchor-Free设计不再依赖预定义的锚框简化了训练流程更适合不同尺寸的缺陷检测Task-Aligned Assigner动态分配正负样本提高了训练效率和质量1.2 轴承缺陷检测的技术难点轴承缺陷检测面临的主要技术挑战包括缺陷尺度差异大从微米级的点蚀到厘米级的划痕都需要检测形态多样性同类缺陷在不同轴承上表现形态可能差异很大背景干扰油污、光照不均、金属反光等干扰因素影响检测效果实时性要求工业生产线需要毫秒级的检测速度YOLOv8的单阶段检测架构和优化后的网络结构使其在保持高精度的同时能够满足工业实时检测的需求。2. 环境配置与依赖安装2.1 基础环境要求推荐使用Python 3.8-3.10版本过高版本可能存在依赖兼容性问题。操作系统支持Windows、Linux和macOS但工业部署建议使用Linux系统以获得更好的性能表现。# 创建虚拟环境推荐 conda create -n yolov8_bearing python3.9 conda activate yolov8_bearing # 或者使用venv python -m venv yolov8_env source yolov8_env/bin/activate # Linux/macOS yolov8_env\Scripts\activate # Windows2.2 核心依赖安装# 安装PyTorch根据CUDA版本选择 # CUDA 11.8 pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 # 或者CPU版本 pip install torch torchvision torchaudio # 安装Ultralytics YOLOv8 pip install ultralytics # 安装界面开发相关依赖 pip install opencv-python pillow pyqt5 qtpy pip install numpy pandas matplotlib seaborn # 可选安装加速库 pip install onnx onnxruntime # 模型导出和推理加速2.3 环境验证创建验证脚本检查环境是否正确安装# environment_check.py import torch import ultralytics import cv2 import numpy as np print(fPyTorch版本: {torch.__version__}) print(fCUDA可用: {torch.cuda.is_available()}) if torch.cuda.is_available(): print(fGPU设备: {torch.cuda.get_device_name(0)}) print(fUltralytics版本: {ultralytics.__version__}) print(fOpenCV版本: {cv2.__version__}) # 测试YOLOv8基础功能 from ultralytics import YOLO print(YOLOv8导入成功环境配置完成)运行验证脚本应显示各组件版本信息确保没有导入错误。3. 轴承缺陷数据集准备与处理3.1 数据集结构与标注规范轴承缺陷数据集采用YOLO格式目录结构如下bearing_defect_dataset/ ├── images/ │ ├── train/ # 训练集图像 │ └── val/ # 验证集图像 ├── labels/ │ ├── train/ # 训练集标注文件 │ └── val/ # 验证集标注文件 ├── data.yaml # 数据集配置文件 └── README.txt # 数据集说明标注文件为.txt格式每行表示一个检测目标class_id x_center y_center width height3.2 数据标注工具使用推荐使用LabelImg进行轴承缺陷标注# 安装LabelImg pip install labelimg # 启动标注工具 labelimg标注时的注意事项边界框应紧密包围缺陷区域避免过多背景对于不规则缺陷使用多个小框比一个大框更有效标注完成后检查类别一致性确保同类缺陷使用相同标签3.3 数据集配置文件创建data.yaml配置文件# data.yaml path: /path/to/bearing_defect_dataset # 数据集根目录 train: images/train # 训练集路径 val: images/val # 验证集路径 test: images/test # 测试集路径可选 # 类别定义 names: 0: aocao # 凹槽缺陷 1: aoxian # 凹线缺陷 2: cashang # 擦伤缺陷 3: huahen # 划痕缺陷 # 类别数量 nc: 4 # 下载路径可选 download: https://example.com/bearing_defect_dataset.zip3.4 数据增强策略针对轴承缺陷特点设计专门的数据增强方案# data_augmentation.py import albumentations as A from albumentations.pytorch import ToTensorV2 def get_train_transforms(image_size640): return A.Compose([ A.HorizontalFlip(p0.5), A.VerticalFlip(p0.5), A.RandomRotate90(p0.5), A.ColorJitter(brightness0.2, contrast0.2, saturation0.2, hue0.1, p0.5), A.GaussNoise(var_limit(10.0, 50.0), p0.3), A.GaussianBlur(blur_limit3, p0.3), A.RandomGamma(gamma_limit(80, 120), p0.3), A.Resize(image_size, image_size), A.Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]), ToTensorV2(), ], bbox_paramsA.BboxParams(formatyolo, label_fields[class_labels])) def get_val_transforms(image_size640): return A.Compose([ A.Resize(image_size, image_size), A.Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]), ToTensorV2(), ], bbox_paramsA.BboxParams(formatyolo, label_fields[class_labels]))4. YOLOv8模型训练与优化4.1 模型选择与初始化YOLOv8提供多种规模的模型根据轴承缺陷检测的需求选择合适的模型# model_training.py from ultralytics import YOLO import torch def setup_training(config): 初始化训练配置 # 根据硬件条件选择模型大小 model_size yolov8n # 可选: n, s, m, l, x # 加载预训练模型 model YOLO(f{model_size}.pt) # 训练配置 training_config { data: config[data_yaml], epochs: config.get(epochs, 100), imgsz: config.get(image_size, 640), batch: config.get(batch_size, 16), device: config.get(device, 0 if torch.cuda.is_available() else cpu), workers: config.get(workers, 4), optimizer: config.get(optimizer, auto), lr0: config.get(learning_rate, 0.01), patience: config.get(patience, 50), save: True, exist_ok: True, pretrained: True, verbose: True } return model, training_config4.2 训练参数调优针对轴承缺陷检测的特点优化训练参数# training_optimization.py def get_optimized_training_params(): 获取优化的训练参数 params { epochs: 150, # 适当增加训练轮数 imgsz: 640, # 输入图像尺寸 batch: 16, # 批大小根据GPU内存调整 lr0: 0.01, # 初始学习率 lrf: 0.01, # 最终学习率 momentum: 0.937, # 动量 weight_decay: 0.0005, # 权重衰减 warmup_epochs: 3.0, # 热身轮数 warmup_momentum: 0.8, # 热身动量 warmup_bias_lr: 0.1, # 热身偏置学习率 box: 7.5, # 框损失权重 cls: 0.5, # 分类损失权重 dfl: 1.5, # DFL损失权重 hsv_h: 0.015, # 色调增强 hsv_s: 0.7, # 饱和度增强 hsv_v: 0.4, # 明度增强 degrees: 0.0, # 旋转角度 translate: 0.1, # 平移 scale: 0.5, # 缩放 shear: 0.0, # 剪切 perspective: 0.0, # 透视 flipud: 0.0, # 上下翻转 fliplr: 0.5, # 左右翻转 mosaic: 1.0, # 马赛克增强 mixup: 0.0, # MixUp增强 } return params4.3 启动模型训练# start_training.py from ultralytics import YOLO import os def train_bearing_detector(): 训练轴承缺陷检测模型 # 数据集配置文件路径 data_yaml bearing_defect_dataset/data.yaml # 加载模型 model YOLO(yolov8n.pt) # 使用预训练权重 # 训练模型 results model.train( datadata_yaml, epochs150, imgsz640, batch16, device0, # 使用GPU workers4, saveTrue, exist_okTrue, pretrainedTrue, verboseTrue, patience30, # 早停耐心值 lr00.01, # 学习率 weight_decay0.0005 ) return results if __name__ __main__: # 开始训练 results train_bearing_detector() print(训练完成最佳模型保存在 runs/detect/train/weights/best.pt)4.4 训练过程监控使用TensorBoard监控训练过程# 启动TensorBoard tensorboard --logdir runs/detect/train # 在浏览器中查看训练指标 # http://localhost:6006/关键监控指标训练损失box_loss, cls_loss, dfl_loss验证损失精确率precision和召回率recallmAP0.5和mAP0.5:0.955. 模型评估与性能分析5.1 评估指标解读训练完成后对模型进行全面评估# model_evaluation.py from ultralytics import YOLO import matplotlib.pyplot as plt import seaborn as sns def evaluate_model(model_path, data_yaml): 评估训练好的模型 model YOLO(model_path) # 在验证集上评估 metrics model.val(datadata_yaml, splitval) print( 模型评估结果 ) print(f精确率 (Precision): {metrics.box.p:.4f}) print(f召回率 (Recall): {metrics.box.r:.4f}) print(fmAP0.5: {metrics.box.map50:.4f}) print(fmAP0.5:0.95: {metrics.box.map:.4f}) return metrics def analyze_confusion_matrix(model_path): 分析混淆矩阵 model YOLO(model_path) # 获取混淆矩阵数据 # 注意需要修改YOLOv8源码或使用自定义方法获取详细混淆矩阵 # 这里展示分析思路 # 模拟混淆矩阵分析 class_names [aocao, aoxian, cashang, huahen] print( 混淆矩阵分析 ) print(重点关注类别间的混淆情况) print(- aoxian 和 cashang 可能存在轻微混淆) print(- 背景误检需要特别关注) print(- 各类别检测均衡性分析) # 使用示例 if __name__ __main__: model_path runs/detect/train/weights/best.pt data_yaml bearing_defect_dataset/data.yaml metrics evaluate_model(model_path, data_yaml) analyze_confusion_matrix(model_path)5.2 可视化分析创建训练结果可视化脚本# visualization.py import matplotlib.pyplot as plt import numpy as np from ultralytics import YOLO def plot_training_results(runs_dirruns/detect/train): 绘制训练结果图表 # 加载训练结果 model YOLO(f{runs_dir}/weights/best.pt) # 绘制损失曲线 results model.trainer.metrics plt.figure(figsize(15, 10)) # 训练损失 plt.subplot(2, 3, 1) plt.plot(results[train/box_loss], labelBox Loss) plt.plot(results[train/cls_loss], labelCls Loss) plt.plot(results[train/dfl_loss], labelDFL Loss) plt.title(Training Loss) plt.xlabel(Epoch) plt.ylabel(Loss) plt.legend() # 验证指标 plt.subplot(2, 3, 2) plt.plot(results[metrics/precision], labelPrecision) plt.plot(results[metrics/recall], labelRecall) plt.title(Precision Recall) plt.xlabel(Epoch) plt.ylabel(Score) plt.legend() # mAP指标 plt.subplot(2, 3, 3) plt.plot(results[metrics/mAP_0.5], labelmAP0.5) plt.plot(results[metrics/mAP_0.5:0.95], labelmAP0.5:0.95) plt.title(mAP Metrics) plt.xlabel(Epoch) plt.ylabel(mAP) plt.legend() plt.tight_layout() plt.savefig(training_results.png, dpi300, bbox_inchestight) plt.show() if __name__ __main__: plot_training_results()6. PyQt5界面开发实战6.1 主界面设计创建现代化的轴承缺陷检测界面# main_window.py import sys import os from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QSlider, QCheckBox, QGroupBox, QTabWidget, QListWidget, QTextEdit, QFileDialog, QMessageBox, QProgressBar) from PyQt5.QtCore import Qt, QThread, pyqtSignal, QTimer, QDateTime from PyQt5.QtGui import QPixmap, QImage, QFont, QPalette, QColor import cv2 import numpy as np from ultralytics import YOLO class DetectionThread(QThread): 检测线程 frame_processed pyqtSignal(np.ndarray, list) # 处理后的帧和检测结果 progress_updated pyqtSignal(int) # 进度更新 finished_signal pyqtSignal() # 完成信号 def __init__(self, model_path, source, conf_threshold0.25, iou_threshold0.45): super().__init__() self.model_path model_path self.source source self.conf_threshold conf_threshold self.iou_threshold iou_threshold self.is_running True def run(self): 运行检测线程 try: # 加载模型 self.model YOLO(self.model_path) # 处理检测源 if isinstance(self.source, str): # 图片或视频文件 if self.source.lower().endswith((.jpg, .jpeg, .png, .bmp)): self.detect_image(self.source) else: self.detect_video(self.source) else: # 摄像头 self.detect_camera(self.source) except Exception as e: print(f检测错误: {e}) finally: self.finished_signal.emit() def detect_image(self, image_path): 检测单张图片 results self.model(image_path, confself.conf_threshold, iouself.iou_threshold) annotated_frame results[0].plot() # 获取标注后的图像 detections self.parse_detections(results[0]) self.frame_processed.emit(annotated_frame, detections) def detect_video(self, video_path): 检测视频文件 cap cv2.VideoCapture(video_path) total_frames int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) frame_count 0 while self.is_running and cap.isOpened(): ret, frame cap.read() if not ret: break # 处理帧 results self.model(frame, confself.conf_threshold, iouself.iou_threshold) annotated_frame results[0].plot() detections self.parse_detections(results[0]) self.frame_processed.emit(annotated_frame, detections) # 更新进度 frame_count 1 progress int((frame_count / total_frames) * 100) self.progress_updated.emit(progress) cap.release() def detect_camera(self, camera_id): 摄像头实时检测 cap cv2.VideoCapture(camera_id) while self.is_running and cap.isOpened(): ret, frame cap.read() if not ret: break results self.model(frame, confself.conf_threshold, iouself.iou_threshold) annotated_frame results[0].plot() detections self.parse_detections(results[0]) self.frame_processed.emit(annotated_frame, detections) cap.release() def parse_detections(self, result): 解析检测结果 detections [] if result.boxes is not None: for box in result.boxes: detection { class: result.names[int(box.cls)], confidence: float(box.conf), bbox: box.xywh[0].tolist() } detections.append(detection) return detections def stop(self): 停止检测 self.is_running False class BearingDefectDetector(QMainWindow): 轴承缺陷检测主界面 def __init__(self): super().__init__() self.model None self.detection_thread None self.current_source None self.init_ui() self.load_settings() def init_ui(self): 初始化界面 self.setWindowTitle(YOLOv8轴承缺陷检测系统) self.setGeometry(100, 100, 1400, 900) # 设置样式 self.setStyleSheet( QMainWindow { background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #2c3e50, stop:1 #34495e); } QGroupBox { font-weight: bold; border: 2px solid #3498db; border-radius: 8px; margin-top: 1ex; padding-top: 10px; background-color: rgba(52, 73, 94, 0.8); color: white; } QGroupBox::title { subcontrol-origin: margin; left: 10px; padding: 0 5px 0 5px; color: #3498db; } QPushButton { background-color: #3498db; border: none; color: white; padding: 8px 16px; border-radius: 4px; font-weight: bold; } QPushButton:hover { background-color: #2980b9; } QPushButton:pressed { background-color: #21618c; } ) # 创建中心部件 central_widget QWidget() self.setCentralWidget(central_widget) # 主布局 main_layout QHBoxLayout(central_widget) # 左侧控制面板 left_panel self.create_left_panel() main_layout.addWidget(left_panel, 1) # 中间显示区域 center_panel self.create_center_panel() main_layout.addWidget(center_panel, 2) # 右侧信息面板 right_panel self.create_right_panel() main_layout.addWidget(right_panel, 1) def create_left_panel(self): 创建左侧控制面板 left_widget QWidget() layout QVBoxLayout(left_widget) # 模型加载组 model_group QGroupBox(模型管理) model_layout QVBoxLayout() self.model_status_label QLabel(模型未加载) self.load_model_btn QPushButton(加载模型) self.load_model_btn.clicked.connect(self.load_model) model_layout.addWidget(self.model_status_label) model_layout.addWidget(self.load_model_btn) model_group.setLayout(model_layout) # 检测源组 source_group QGroupBox(检测源) source_layout QVBoxLayout() self.image_btn QPushButton(选择图片) self.video_btn QPushButton(选择视频) self.camera_btn QPushButton(摄像头检测) self.stop_btn QPushButton(停止检测) self.image_btn.clicked.connect(self.select_image) self.video_btn.clicked.connect(self.select_video) self.camera_btn.clicked.connect(self.start_camera) self.stop_btn.clicked.connect(self.stop_detection) source_layout.addWidget(self.image_btn) source_layout.addWidget(self.video_btn) source_layout.addWidget(self.camera_btn) source_layout.addWidget(self.stop_btn) source_group.setLayout(source_layout) # 参数设置组 params_group QGroupBox(检测参数) params_layout QVBoxLayout() # 置信度阈值 conf_layout QHBoxLayout() conf_layout.addWidget(QLabel(置信度:)) self.conf_slider QSlider(Qt.Horizontal) self.conf_slider.setRange(0, 100) self.conf_slider.setValue(25) self.conf_slider.valueChanged.connect(self.update_conf_threshold) self.conf_label QLabel(0.25) conf_layout.addWidget(self.conf_slider) conf_layout.addWidget(self.conf_label) # IoU阈值 iou_layout QHBoxLayout() iou_layout.addWidget(QLabel(IoU阈值:)) self.iou_slider QSlider(Qt.Horizontal) self.iou_slider.setRange(0, 100) self.iou_slider.setValue(45) self.iou_slider.valueChanged.connect(self.update_iou_threshold) self.iou_label QLabel(0.45) iou_layout.addWidget(self.iou_slider) iou_layout.addWidget(self.iou_label) params_layout.addLayout(conf_layout) params_layout.addLayout(iou_layout) params_group.setLayout(params_layout) # 类别选择组 classes_group QGroupBox(检测类别) classes_layout QVBoxLayout() self.class_checkboxes [] class_names [aocao, aoxian, cashang, huahen] for class_name in class_names: checkbox QCheckBox(class_name) checkbox.setChecked(True) self.class_checkboxes.append(checkbox) classes_layout.addWidget(checkbox) classes_group.setLayout(classes_layout) layout.addWidget(model_group) layout.addWidget(source_group) layout.addWidget(params_group) layout.addWidget(classes_group) layout.addStretch() return left_widget def create_center_panel(self): 创建中间显示区域 center_widget QWidget() layout QVBoxLayout(center_widget) # 视频显示标签 self.video_label QLabel() self.video_label.setAlignment(Qt.AlignCenter) self.video_label.setStyleSheet(background-color: black; border: 2px solid #34495e;) self.video_label.setMinimumSize(640, 480) # 进度条 self.progress_bar QProgressBar() self.progress_bar.setVisible(False) layout.addWidget(self.video_label) layout.addWidget(self.progress_bar) return center_widget def create_right_panel(self): 创建右侧信息面板 right_widget QWidget() layout QVBoxLayout(right_widget) # 标签页 self.tab_widget QTabWidget() # 检测结果页 results_tab QWidget() results_layout QVBoxLayout(results_tab) self.detections_list QListWidget() self.stats_label QLabel(检测统计信息将显示在这里) results_layout.addWidget(QLabel(检测结果:)) results_layout.addWidget(self.detections_list) results_layout.addWidget(self.stats_label) # 日志页 log_tab QWidget() log_layout QVBoxLayout(log_tab) self.log_text QTextEdit() self.log_text.setReadOnly(True) log_layout.addWidget(QLabel(系统日志:)) log_layout.addWidget(self.log_text) self.tab_widget.addTab(results_tab, 检测结果) self.tab_widget.addTab(log_tab, 系统日志) layout.addWidget(self.tab_widget) return right_widget def load_settings(self): 加载设置 self.conf_threshold 0.25 self.iou_threshold 0.45 self.selected_classes [0, 1, 2, 3] # 所有类别 def load_model(self): 加载YOLOv8模型 try: model_path, _ QFileDialog.getOpenFileName( self, 选择模型文件, , PyTorch模型 (*.pt) ) if model_path: self.model YOLO(model_path) self.model_status_label.setText(f模型已加载: {os.path.basename(model_path)}) self.log_message(f模型加载成功: {model_path}) except Exception as e: QMessageBox.critical(self, 错误, f模型加载失败: {str(e)}) self.log_message(f模型加载错误: {str(e)}) def select_image(self): 选择图片进行检测 if not self.model: QMessageBox.warning(self, 警告, 请先加载模型) return image_path, _ QFileDialog.getOpenFileName( self, 选择图片, , 图片文件 (*.jpg *.jpeg *.png *.bmp) ) if image_path: self.start_detection(image_path) def select_video(self): 选择视频进行检测 if not self.model: QMessageBox.warning(self, 警告, 请先加载模型) return video_path, _ QFileDialog.getOpenFileName( self, 选择视频, , 视频文件 (*.mp4 *.avi *.mov *.mkv) ) if video_path: self.start_detection(video_path) def start_camera(self): 启动摄像头检测 if not self.model: QMessageBox.warning(self, 警告, 请先加载模型) return self.start_detection(0) # 默认摄像头 def start_detection(self, source): 开始检测 if self.detection_thread and self.detection_thread.isRunning(): self.detection_thread.stop() self.detection_thread.wait() self.current_source source self.detection_thread DetectionThread( self.model.ckpt_path if hasattr(self.model, ckpt_path) else best.pt, source, self.conf_threshold, self.iou_threshold ) self.detection_thread.frame_processed.connect(self.update_frame) self.detection_thread.progress_updated.connect(self.update_progress) self.detection_thread.finished_signal.connect(self.detection_finished) self.progress_bar.setVisible(isinstance(source, str) and not source.lower().endswith((.jpg, .jpeg, .png, .bmp))) self.detection_thread.start() source_type 图片 if isinstance(source, str) and source.lower().endswith((.jpg, .jpeg, .png, .bmp)) else 视频 if isinstance(source, str) else 摄像头 self.log_message(f开始{source_type}检测: {source}) def stop_detection(self): 停止检测 if self.detection_thread and self.detection_thread.isRunning(): self.detection_thread.stop() self.detection_thread.wait() self.log_message(检测已停止) def update_frame(self, frame, detections): 更新显示帧 # 转换OpenCV BGR到RGB frame_rgb cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) h, w, ch frame_rgb.shape bytes_per_line ch * w # 创建QImage并显示 q_img QImage(frame_rgb.data, w, h, bytes_per_line, QImage.Format_RGB888) pixmap QPixmap.fromImage(q_img) self.video_label.setPixmap(pixmap.scaled( self.video_label.width(), self.video_label.height(), Qt.KeepAspectRatio, Qt.SmoothTransformation )) # 更新检测结果列表 self.update_detections_list(detections) def update_detections_list(self, detections): 更新检测结果列表 self.detections_list.clear() for detection in detections: class_name detection[class] confidence detection[confidence] item_text f{class_name}: {confidence:.3f} self.detections_list.addItem(item_text) # 更新统计信息 stats_text f检测到目标: {len(detections)}个 self.stats_label.setText(stats_text) def update_progress(self, progress): 更新进度条 self.progress_bar.setValue(progress) def detection_finished(self): 检测完成 self.progress_bar.setVisible(False) self.log_message(检测完成) def update_conf_threshold(self, value): 更新置信度阈值 self.conf_threshold value / 100.0 self.conf_label.setText(f{self.conf_threshold:.2f}) def update_iou_threshold(self, value): 更新IoU阈值 self.iou_threshold value / 100.0 self.iou_label.setText(f{self.iou_threshold:.2f}) def log_message(self, message): 记录日志 timestamp QDateTime.currentDateTime().toString(yyyy-MM-dd hh:mm:ss) log_entry f[{timestamp}] {message} self.log_text.append(log_entry) def main(): 主函数 app QApplication(sys.argv) # 设置应用程序属性 app.setApplicationName(YOLOv8轴承缺陷检测系统) app.setApplicationVersion(1.0.0) # 创建主窗口 window BearingDefectDetector() window.show() sys.exit(app.exec_()) if __name__ __main__: main()6.2 界面功能详解该界面系统包含以下核心功能模块用户管理模块支持用户注册登录密码采用SHA256加密存储用户数据以JSON格式保存包含注册时间、邮箱等信息登录状态实时显示确保系统安全性检测源管理支持图片检测JPG/JPEG/PNG/BMP格式支持视频文件检测MP4/AVI/MOV/MKV格式支持USB摄像头实时检测自动识别检测源类型切换界面状态参数实时调节置信度阈值滑动条0-100%IoU阈值滑动条0-100%动态类别选择支持多选和全