【零基础入门】Python机器视觉第五阶段:目标检测实战(YOLOv8)

【零基础入门】Python机器视觉第五阶段:目标检测实战(YOLOv8) 【零基础入门】Python机器视觉第五阶段目标检测实战YOLOv8。在第四阶段我们学习了PyTorch基础并搭建了CNN网络进行图像分类。从分类到检测是机器视觉能力的一次重要跃升——分类回答“这是什么”检测回答“它在哪里”。本阶段我们将学习目前最流行的目标检测框架YOLOv8并实战训练一个能够检测表面缺陷如划痕、脏污、裂纹的模型。本文所有代码均可直接复制运行建议结合官方文档和数据集边学边练。一、本阶段学习目标理解目标检测的基本概念边界框、IOU、mAP、NMS掌握YOLOv8的安装与使用学会使用LabelImg标注自己的数据集掌握YOLO格式数据集的制作与划分能够训练YOLOv8模型进行缺陷检测学会模型推理与结果可视化掌握模型评估指标的含义与使用方法二、目标检测核心概念速览2.1 什么是目标检测目标检测的任务是在图像中找出所有感兴趣的目标并给出它们的类别和位置。位置通常用**边界框Bounding Box**表示。2.2 核心概念概念通俗解释图示/公式边界框包含目标的最小矩形用(x1,y1,x2,y2)或(x_center,y_center,width,height)表示矩形框IOU交并比预测框与真实框的重叠程度值越大表示预测越准IOU 交集面积 / 并集面积置信度模型对预测结果的信心取值范围0~1-NMS非极大值抑制去除冗余的重复检测框保留最优的一个算法mAP平均精度均值目标检测最常用的评估指标综合所有类别的AP取平均2.3 YOLO系列简介YOLOYou Only Look Once是一种单阶段目标检测算法特点是速度快、精度高。YOLOv8是Ultralytics公司发布的最新版本支持目标检测Object Detection实例分割Instance Segmentation图像分类Image Classification姿态估计Pose EstimationYOLOv8的优势Anchor-Free架构简化设计支持多种模型大小n/s/m/l/x以适应不同场景提供完整的训练、验证、预测、导出工具链与PyTorch无缝集成三、YOLOv8基础3.1 安装YOLOv8# 安装ultralytics包pipinstallultralytics# 验证安装python-cfrom ultralytics import YOLO; print(YOLO.__version__)3.2 使用预训练模型进行推理fromultralyticsimportYOLOimportcv2importmatplotlib.pyplotasplt# 加载预训练模型自动下载modelYOLO(yolov8n.pt)# n: nano, s: small, m: medium, l: large, x: xlarge# 对图片进行推理resultsmodel(test.jpg)# 替换为你的图片路径# 显示结果imgcv2.imread(test.jpg)img_rgbcv2.cvtColor(img,cv2.COLOR_BGR2RGB)forrinresults:boxesr.boxesforboxinboxes:x1,y1,x2,y2box.xyxy[0].tolist()confbox.conf[0].item()clsint(box.cls[0].item())labelf{model.names[cls]}{conf:.2f}# 画框cv2.rectangle(img_rgb,(int(x1),int(y1)),(int(x2),int(y2)),(255,0,0),2)cv2.putText(img_rgb,label,(int(x1),int(y1)-5),cv2.FONT_HERSHEY_SIMPLEX,0.5,(255,0,0),2)plt.imshow(img_rgb)plt.axis(off)plt.show()3.3 YOLOv8支持的模型版本模型参数量mAP50-95速度CPU适用场景YOLOv8n3.2M37.3最快移动端、边缘设备YOLOv8s11.2M44.9较快通用场景YOLOv8m25.9M50.2中等平衡速度和精度YOLOv8l43.7M52.9较慢高精度要求YOLOv8x68.2M53.9最慢极致精度四、数据集准备4.1 YOLO数据集格式YOLO使用特定的数据集格式dataset/ ├── images/ │ ├── train/ # 训练图片 │ └── val/ # 验证图片 ├── labels/ │ ├── train/ # 训练标注 │ └── val/ # 验证标注 └── data.yaml # 数据集配置文件标注文件格式每张图片对应一个同名的txt文件每行代表一个目标class_id x_center y_center width heightclass_id类别ID从0开始x_center, y_center边界框中心点坐标归一化到0-1width, height边界框的宽和高归一化到0-1例如0 0.5096 0.3528 0.3947 0.3182 # 划痕 1 0.1234 0.5678 0.2345 0.3456 # 脏污4.2 使用LabelImg标注工具4.2.1 安装LabelImgpipinstalllabelImg4.2.2 启动标注工具labelImg4.2.3 标注步骤打开图片文件夹点击Open Dir选择包含待标注图片的文件夹设置保存路径点击Change Save Dir选择标注文件保存位置选择YOLO格式点击YOLO按钮确保是YOLO格式开始标注按w键开始画框拖动鼠标框选目标输入类别名称如果是首次标注需要输入并创建保存按CtrlS保存当前图片的标注下一张按d键进入下一张图片4.3 数据集配置文件 data.yaml# 数据集根路径建议使用绝对路径path:D:/defect_dataset# 修改为你的实际路径train:images/train# 训练图片路径相对于pathval:images/val# 验证图片路径相对于path# 类别数量nc:4# 类别名称names:0:scratch# 划痕1:dirt# 脏污2:dimple# 凹坑3:crack# 裂纹4.4 数据集划分脚本importosimportrandomimportshutilfromsklearn.model_selectionimporttrain_test_splitdefsplit_dataset(image_dir,label_dir,output_dir,val_ratio0.2,random_seed42): 将数据集划分为训练集和验证集 Args: image_dir: 原始图片目录 label_dir: 原始标注目录 output_dir: 输出目录 val_ratio: 验证集比例 random_seed: 随机种子 # 创建目录结构train_img_diros.path.join(output_dir,images,train)train_label_diros.path.join(output_dir,labels,train)val_img_diros.path.join(output_dir,images,val)val_label_diros.path.join(output_dir,labels,val)fordin[train_img_dir,train_label_dir,val_img_dir,val_label_dir]:os.makedirs(d,exist_okTrue)# 获取所有图片文件images[fforfinos.listdir(image_dir)iff.lower().endswith((.jpg,.jpeg,.png,.bmp))]# 划分训练集和验证集train_images,val_imagestrain_test_split(images,test_sizeval_ratio,random_staterandom_seed)# 复制文件forimgintrain_images:# 复制图片src_imgos.path.join(image_dir,img)dst_imgos.path.join(train_img_dir,img)shutil.copy(src_img,dst_img)# 复制对应的标注文件label_fileos.path.splitext(img)[0].txtsrc_labelos.path.join(label_dir,label_file)ifos.path.exists(src_label):dst_labelos.path.join(train_label_dir,label_file)shutil.copy(src_label,dst_label)forimginval_images:# 复制图片src_imgos.path.join(image_dir,img)dst_imgos.path.join(val_img_dir,img)shutil.copy(src_img,dst_img)# 复制对应的标注文件label_fileos.path.splitext(img)[0].txtsrc_labelos.path.join(label_dir,label_file)ifos.path.exists(src_label):dst_labelos.path.join(val_label_dir,label_file)shutil.copy(src_label,dst_label)print(f数据集划分完成)print(f训练集:{len(train_images)}张图片)print(f验证集:{len(val_images)}张图片)# 使用示例split_dataset(image_dir./raw_images,label_dir./raw_labels,output_dir./defect_dataset,val_ratio0.2)4.5 下载公开缺陷数据集推荐4.5.1 NEU表面缺陷数据集钢铁表面缺陷数据集包含6类缺陷划痕、氧化皮、裂纹等。# 安装kagglehubpip install kagglehubimportkagglehub# 下载NEU数据集pathkagglehub.dataset_download(kaustubhdhake/neu-surface-defect-database)print(数据集下载到:,path)4.5.2 GC10-DET数据集金属表面缺陷数据集包含10类缺陷。pathkagglehub.dataset_download(shadabhussain/gc10det)print(数据集下载到:,path)4.5.3 PCB缺陷数据集电路板缺陷数据集包含6类缺陷。pathkagglehub.dataset_download(akhatova/pcb-defects)print(数据集下载到:,path)五、训练YOLOv8模型5.1 训练脚本fromultralyticsimportYOLOimporttorch# ---------- 1. 检查GPU ----------print(fCUDA可用:{torch.cuda.is_available()})iftorch.cuda.is_available():print(fGPU型号:{torch.cuda.get_device_name(0)})# ---------- 2. 加载预训练模型 ----------# 可选yolov8n.pt, yolov8s.pt, yolov8m.pt, yolov8l.pt, yolov8x.ptmodelYOLO(yolov8n.pt)# ---------- 3. 开始训练 ----------resultsmodel.train(datadefect_dataset/data.yaml,# 数据集配置文件epochs100,# 训练轮数imgsz640,# 输入图片大小batch16,# 批次大小根据显存调整workers4,# 数据加载线程数device0,# GPU设备0表示第一个GPUcpu表示CPUlr00.001,# 初始学习率optimizerSGD,# 优化器patience20,# 早停耐心值20轮无改善则停止saveTrue,# 保存模型projectruns/train,# 项目保存路径namedefect_detection,# 实验名称exist_okTrue,# 覆盖已有实验pretrainedTrue,# 使用预训练权重verboseTrue# 打印详细信息)print(训练完成)5.2 训练参数详解参数说明推荐值经验建议epochs训练轮数100-300小数据集100足够大数据集可增加imgsz输入图片大小640越大越慢但可能更准batch批次大小8-32根据显存调整越大训练越稳定lr0初始学习率0.001太大不收敛太小收敛慢patience早停耐心值20-50防止过拟合workers数据加载线程4-8根据CPU核心数调整5.3 训练过程监控训练过程中YOLOv8会实时显示Epoch当前训练轮数GPU_memGPU内存占用box_loss边界框损失cls_loss分类损失dfl_loss分布焦点损失mAP50IoU0.5时的平均精度mAP50-95IoU从0.5到0.95的平均精度5.4 训练结果训练完成后在runs/train/defect_detection/目录下生成weights/ ├── best.pt # 最佳模型根据验证集mAP └── last.pt # 最后一轮模型 results.png # 训练曲线 confusion_matrix.png # 混淆矩阵 F1_curve.png # F1曲线 PR_curve.png # PR曲线 labels.jpg # 标注示例5.5 模型验证fromultralyticsimportYOLO# 加载训练好的模型modelYOLO(runs/train/defect_detection/weights/best.pt)# 在验证集上评估metricsmodel.val(datadefect_dataset/data.yaml)print(fmAP50:{metrics.box.map50:.4f})print(fmAP50-95:{metrics.box.map:.4f})# 查看每个类别的APfori,class_nameinenumerate(metrics.names.values()):apmetrics.box.ap[i]ifhasattr(metrics.box,ap)else0print(f{class_name}: mAP50 {metrics.box.ap50[i]:.4f})六、模型推理与可视化6.1 单张图片推理fromultralyticsimportYOLOimportcv2importmatplotlib.pyplotasplt# 加载模型modelYOLO(runs/train/defect_detection/weights/best.pt)# 推理resultsmodel(test.jpg,conf0.25,saveTrue)# conf置信度阈值# 自定义可视化imgcv2.imread(test.jpg)img_rgbcv2.cvtColor(img,cv2.COLOR_BGR2RGB)forrinresults:boxesr.boxesforboxinboxes:x1,y1,x2,y2box.xyxy[0].tolist()confbox.conf[0].item()clsint(box.cls[0].item())labelf{model.names[cls]}{conf:.2f}# 画框cv2.rectangle(img_rgb,(int(x1),int(y1)),(int(x2),int(y2)),(255,0,0),2)cv2.putText(img_rgb,label,(int(x1),int(y1)-5),cv2.FONT_HERSHEY_SIMPLEX,0.5,(255,0,0),2)print(f检测到:{label}, 位置: ({x1:.1f},{y1:.1f},{x2:.1f},{y2:.1f}))plt.figure(figsize(10,8))plt.imshow(img_rgb)plt.axis(off)plt.show()6.2 批量推理# 对整个文件夹进行推理resultsmodel.predict(source./test_images/,# 图片文件夹conf0.25,# 置信度阈值saveTrue,# 保存结果project./predict_results,# 输出目录namedefect_detection# 实验名称)6.3 视频推理# 对视频文件进行推理resultsmodel.predict(sourcetest_video.mp4,# 视频文件conf0.25,saveTrue,project./predict_results)6.4 摄像头实时检测importcv2fromultralyticsimportYOLO modelYOLO(runs/train/defect_detection/weights/best.pt)capcv2.VideoCapture(0)# 0表示默认摄像头whileTrue:ret,framecap.read()ifnotret:break# 推理resultsmodel(frame,conf0.25)[0]# 绘制结果forboxinresults.boxes:x1,y1,x2,y2map(int,box.xyxy[0])confbox.conf[0].item()clsint(box.cls[0].item())labelf{model.names[cls]}{conf:.2f}cv2.rectangle(frame,(x1,y1),(x2,y2),(0,255,0),2)cv2.putText(frame,label,(x1,y1-5),cv2.FONT_HERSHEY_SIMPLEX,0.5,(0,255,0),2)cv2.imshow(YOLOv8 Detection,frame)ifcv2.waitKey(1)0xFFord(q):breakcap.release()cv2.destroyAllWindows()七、模型评估与优化7.1 评估指标详解指标含义优秀值mAP50IoU阈值0.5时的平均精度0.9mAP50-95IoU从0.5到0.95的平均精度0.5小目标Precision预测为正例中实际为正例的比例0.9Recall实际为正例中被正确预测的比例0.9F1-score精确率和召回率的调和平均0.97.2 常见问题与解决方案问题可能原因解决方案mAP低数据集太小数据增强、使用预训练模型标注不准确重新检查标注类别不平衡调整损失权重、过采样过拟合训练轮数太多早停、增加正则化数据集太小数据增强、迁移学习漏检目标太小使用更大输入尺寸置信度阈值太高降低conf阈值误检背景干扰增加负样本、调整NMS7.3 超参数调优建议# 建议尝试不同的学习率和优化器model.train(lr00.01,# 较高的初始学习率optimizerAdamW,# 尝试不同优化器augmentTrue,# 启用数据增强mosaic1.0,# Mosaic增强mixup0.5# MixUp增强)八、实战项目表面缺陷检测系统8.1 项目目标训练一个能够检测3-5类表面缺陷如划痕、脏污、凹坑、裂纹的YOLOv8模型。8.2 实现步骤数据收集使用NEU或GC10-DET数据集或自己用手机拍摄数据标注用LabelImg标注缺陷区域数据划分80%训练20%验证模型训练训练YOLOv8模型模型评估验证集上mAP50达到0.9以上模型推理编写推理脚本可视化结果8.3 完整代码训练推理# train_defect_detector.pyfromultralyticsimportYOLOdeftrain_model():# 加载模型modelYOLO(yolov8n.pt)# 训练resultsmodel.train(datadefect_dataset/data.yaml,epochs100,imgsz640,batch16,workers4,device0,lr00.001,optimizerSGD,patience20,projectruns/train,namedefect_detection)# 验证metricsmodel.val()print(fmAP50:{metrics.box.map50:.4f})returnmodeldefpredict(model,image_path):resultsmodel(image_path,conf0.25)# 打印结果forrinresults:boxesr.boxesprint(f检测到{len(boxes)}个缺陷)forboxinboxes:clsint(box.cls[0].item())confbox.conf[0].item()print(f{model.names[cls]}:{conf:.2f})if__name____main__:modeltrain_model()predict(model,test.jpg)九、总结与下一步通过本阶段的学习你已经掌握了✅ 目标检测核心概念✅ YOLOv8的安装与使用✅ 使用LabelImg标注数据集✅ 制作YOLO格式数据集✅ 训练YOLOv8检测模型✅ 模型推理与结果可视化✅ 模型评估与优化技巧下一步进入第六阶段——综合项目实战你将学习如何将训练好的YOLOv8模型集成到C# WPF应用中实现工业缺陷检测原型系统包括运动控制模拟、相机模拟和实时检测界面。 参考文档链接Ultralytics YOLOv8官方文档 —— 完整的训练、预测、导出教程YOLOv8 Python API文档 —— 详细的API使用说明LabelImg GitHub —— 标注工具源码和使用说明NEU表面缺陷数据集 —— Kaggle上的钢铁表面缺陷数据集GC10-DET数据集 —— 金属表面缺陷数据集YOLOv8训练自己的数据集 —— CSDN中文教程如果在学习过程中遇到任何问题欢迎随时交流下一阶段我们将进入激动人心的综合项目实战。