简约大气网站首页惠州网站建设制作
2026/5/24 4:18:26 网站建设 项目流程
简约大气网站首页,惠州网站建设制作,服务器运维,增加浏览量的软件还是老板子#xff1a;rk3399#xff0c;需要进行目标检测#xff0c;类似人脸框检测吧#xff0c;看了下还是用yolov8吧#xff0c;速度精度都还可以#xff0c;开始准备选择是naodet 但是可能是我的数据质量问题吧#xff0c;精度一直达不到#xff0c;所以最后综合考…还是老板子rk3399需要进行目标检测类似人脸框检测吧看了下还是用yolov8吧速度精度都还可以开始准备选择是naodet 但是可能是我的数据质量问题吧精度一直达不到所以最后综合考虑还是选择了yolo家族的yolov8n这里记录下训练过程方便后续记忆对比项YOLOv8nNanoDet模型结构更现代Anchor-free PAFPN轻量但较旧基于 ShuffleNet/GhostNet精度上限高COCO mAP ~37.3中COCO mAP ~20~25社区支持官方维护Ultralytics生态完善社区维护更新慢部署友好性支持 ONNX / TensorRT / NCNN / OpenVINO主要依赖 NCNNRK3399 适配需手动数据敏感度对标注质量要求高但容错更强小模型对噪声更敏感易欠拟合地址https://github.com/ultralytics/ultralytics代码准备git clone https://github.com/ultralytics/ultralytics.git一、数据准备首先准备数据检测对象的数据网络爬取或者现场采集大约2000张各种不同种类的照片比如最简单采集的人脸照片这里不暴露项目内容采用人脸替代吧。1.1 数据标注LabelImg 下载地址https://github.com/HumanSignal/labelImg/releases通过标注矩形框进行数据标准可以先标注一部分然后训练出模型然后通过模型标注剩余的图片然后再手工微调这样数据标注就可以提速了也可以在少数数据量的情况下用数据增强原图旋转、翻转、加噪点、马赛克等数据标注之后会 一个xml文件具体如下就是把图片地址、尺寸及目标类型和矩形框的坐标进行标注了!-- 整个标注文档的根元素表示这是一个目标检测的标注 -- annotation !-- 图像所属的文件夹名称通常用于组织数据集结构 -- folderOXIIIT/folder !-- 图像文件名不含路径 -- filename4000.jpg/filename !-- 图像来源信息 -- source !-- 数据集名称 -- databaseDataset/database !-- 标注类型或来源此处为缩写 OXIIIT可能指 Oxford-IIIT -- annotationOXIIIT/annotation !-- 图像原始来源 -- imagenone/image /source !-- 图像尺寸信息 -- size !-- 图像宽度像素 -- width500/width !-- 图像高度像素 -- height667/height !-- 图像通道数3 表示 RGB 彩色图 -- depth3/depth /size !-- 是否包含分割掩码1 表示有0 表示无目标检测任务通常为 0 -- segmented0/segmented !-- 一个目标对象的标注信息可有多个 object -- object !-- 目标类别名称此处为 face但注意原 Oxford-IIIT Pet 数据集通常标注宠物品种这里可能是自定义修改 -- nameface/name !-- 目标姿态如 Frontal、Left、Right 等常用于人脸或物体朝向 -- poseFrontal/pose !-- 是否被截断1 表示目标在图像边界被裁切0 表示完整 -- truncated0/truncated !-- 是否被遮挡1 表示部分不可见0 表示完全可见 -- occluded0/occluded !-- 边界框坐标以像素为单位 -- bndbox !-- 左上角 x 坐标 -- xmin90/xmin !-- 左上角 y 坐标 -- ymin147/ymin !-- 右下角 x 坐标 -- xmax333/xmax !-- 右下角 y 坐标 -- ymax374/ymax /bndbox !-- 是否为“难例”1 表示模糊、极小或难以识别通常训练时可忽略0 表示正常样本 -- difficult0/difficult /object /annotation1.2 数据格式转换标注完成转换成yolov8的数据格式yolov8默认的图片和标注位置对应数据构造格式 data |__ images ├─ 001.jpg ├─ 002.jpg ├─ .. └─ NNN.jpg |__ labels ├─ 001.txt ├─ 002.txt ├─ .. └─ NNN.txt把xml格式转换为txt格式txt格式如下class_id x_center y_center width height0 0.631667 0.287500 0.153333 0.215000字段值含义class_id0类别索引表示第 0 类例如face、person等具体看你的data.yaml中的names定义x_center0.631667目标边界框中心点的 x 坐标归一化y_center0.287500目标边界框中心点的 y 坐标归一化width0.153333边界框宽度归一化height0.215000边界框高度归一化提供一段转换代码import io import os import shutil import xml.etree.ElementTree as ET from pathlib import Path def convert_voc_to_yolo(xml_file, output_dir,class_mappingNone): 将单个 Pascal VOC XML 文件转换为 YOLO 格式的 .txt 标签文件 Args: xml_file: 输入 XML 文件路径 output_dir: 输出 .txt 文件目录 class_mapping: 类别名到 ID 的映射例如 {cat: 0} if class_mapping is None: class_mapping {cat: 0, dog: 1} # 默认只处理 cat - 0 tree ET.parse(xml_file) root tree.getroot() # 获取图像尺寸 size root.find(size) if size is None: raise ValueError(fXML {xml_file} 缺少 size 标签) img_w int(size.find(width).text) img_h int(size.find(height).text) lines [] for obj in root.findall(object): name obj.find(name).text if name not in class_mapping: continue # 跳过非目标类别如 dog bndbox obj.find(bndbox) xmin float(bndbox.find(xmin).text) ymin float(bndbox.find(ymin).text) xmax float(bndbox.find(xmax).text) ymax float(bndbox.find(ymax).text) # 转换为 YOLO 格式 x_center (xmin xmax) / 2.0 / img_w y_center (ymin ymax) / 2.0 / img_h width (xmax - xmin) / img_w height (ymax - ymin) / img_h class_id class_mapping[name] lines.append(f{class_id} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}) # 写入 .txt 文件与 XML 同名 output_path output_dir \\ filename .txt with open(output_path, w) as f: f.write(\n.join(lines)) return filename #获取目录下的所有文件 def get_all_files_os_walk(root_dir): all_files [] for dirpath, dirnames, filenames in os.walk(root_dir): for filename in filenames: full_path os.path.join(dirpath, filename) all_files.append(full_path) return all_files #获取文件名称 def get_all_filenames_os_walk(root_dir): filenames [] for dirpath, dirnames, files in os.walk(root_dir): for file in files: filenames.append(file) # 只取文件名不含路径 return filenames #拷贝原始文件到目的 def copy(src, path): pass cur_path rF:\work\code\python\yolov8\ultralytics-train\ultralytics\data cur_path_img_images cur_path r\labels\test2017\img cur_path_label_xmls cur_path r\labels\test2017\xml cur_path_img_train cur_path r\images\train cur_path_label_train cur_path r\labels\train cur_path_label_val cur_path r\labels\val filenames get_all_filenames_os_walk(cur_path_img_images) #遍历 total_index 0 for filename in filenames: itmes filename.split(.) xmlFileName cur_path_label_xmls\\itmes[0].xml print(filename:str(total_index)) if (itmes[1] not in {jpg,png,JPEG,PNG} ): continue if os.path.exists(xmlFileName): index 0 hasType False with open(xmlFileName, r, encodingutf-8) as f: content f.read() # 返回 list每行末尾保留 \n content str(content) if content is None: shutil.copy2(cur_path_img_images \\ filename, cur_path_img_train \\no_ str(total_index) . itmes[1]) total_index 1 continue if content.find(face) 0: print(face) continue else: shutil.copy2(cur_path_img_images \\ filename, cur_path_img_train \\no_ str(total_index) . itmes[1]) total_index 1 continue # 拷贝文件保留元数据如修改时间 objname convert_voc_to_yolo(xmlFileName, cur_path_label_train) shutil.copy2(cur_path_img_images\\filename, cur_path_img_train\\objname.itmes[1]) print(cur_path_img_images\\filename) total_index 1 else: shutil.copy2(cur_path_img_images\\filename, cur_path_img_train\\no_str(total_index) .itmes[1]) total_index 1 print(it is ok)修改对应的目录即可遍历test2017/xml目录下的所有 Pascal VOC 格式.xml标注文件将每个.xml文件中的目标框信息转换为 YOLO 格式的归一化坐标.txt将对应的图像文件位于test2017/img复制到输出目录images/train/将生成的 YOLO 标注文件保存到labels/train/目录下文件名与图像一致自动创建目标目录若不存在并确保图像与标签一一对应。原始目录test2017/ ├── img/ │ ├── 0001.jpg │ ├── 0002.jpg │ └── ... └── xml/ ├── 0001.xml ├── 0002.xml └── ...输出目录images/ └── train/ ├── 0001.jpg ├── 0002.jpg └── ... labels/ └── train/ ├── 0001.txt ├── 0002.txt └── ...到这里数据格式就转换好了。二、训练2.1 修改配置文件我的数据放到 F:/work/code/python/yolov8/ultralytics-train/data下面我在这里创建一个yaml的配置文件face_yolov8n.yaml# Ultralytics AGPL-3.0 License - https://ultralytics.com/license # COCO8 dataset (first 8 images from COCO train2017) by Ultralytics # Documentation: https://docs.ultralytics.com/datasets/detect/coco8/ # Example usage: yolo train datacoco8.yaml # parent # ├── ultralytics # └── datasets # └── coco8 ← downloads here (1 MB) # Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..] # 数据集根目录路径所有图像和标签路径都相对于此路径 path: F:/work/code/python/yolov8/ultralytics-train/data # dataset root dir # 训练集图像所在目录相对 path 的路径 train: images/train_q # train images (relative to path) 4 images # 验证集图像所在目录相对 path 的路径 val: images/val # val images (relative to path) 4 images # 测试集图像所在目录可选若不使用测试集可删除或注释掉 test: images/test # test images (optional) # 类别名称列表按类别索引class_id顺序定义 # 注意YOLOv8 要求此处使用字典格式 {id: name}且 id 必须从 0 开始连续 names: 0: face # 类别 ID 0 对应的类别名称为 face实际训练图像路径为F:/work/code/python/yolov8/ultralytics-train/data/images/train/xxx.jpg标签文件位置YOLOv8 会自动在与images同级的labels目录下查找对应.txt文件。即若图像在images/train/001.jpg则标签应位于labels/train/001.txt2.2 环境python3.10 安装 pip install ultralytics pip install polars2.3 训练代码这边选择的是yolov8n.pt,图片大小选择320x320from ultralytics import YOLO # 加载预训练模型 model YOLO(yolov8n.pt) path rF:\work\code\python\yolov8\ultralytics-train\ultralytics\data datayaml path /data/face_yolov8n.yaml # Train the model on the COCO8 dataset for 100 epochs train_results model.train( datadatayaml, # Path to dataset configuration file epochs100, # Number of training epochs imgsz320, # Image size for training lr00.001, # 降低学习率避免破坏预训练特征 batch32, device0, # Device to run on (e.g., cpu, 0, [0,1,2,3]) nameface_detection ) # Evaluate the models performance on the validation set metrics model.val() # Perform object detection on an image # results model(pathdata/images/test/face_300.jpg) # Predict on an image # results[0].show() # Display results # Export the model to ONNX format for deployment path model.export(formatonnx) # Returns the path to the exported model执行完成后会在runs-yolov8n_320_320目录下包含训练后的模型F:\work\code\python\yolov8\ultralytics-train\ultralytics\runs-yolov8n_320_320\detect\face_detection4\weights 下面包含有beast.pt 最优的模型last.pt 最后生成的模型一般都是选择beast.pt 训练选择last.pt2.4 推理验证把模型拷贝到跟目录F:\work\code\python\yolov8\ultralytics-train\ultralytics然后模型名称修改为yolov8n_beast.pt推理一张图片是否正常显示画脸框import cv2 import torch from matplotlib import pyplot as plt from ultralytics import YOLO # 加载预训练模型自动下载 if not exists model YOLO(yolov8n_beast.pt) # 推理支持单张图、多图、视频、URL 等 print(model .model.nc) # 应该输出 2 # 方法1通过 Ultralytics API 查看 print(Detect layer output channels (cv3):, [m[-1].out_channels for m in model .model.model[-1].cv3]) # 方法2直接读取 state_dict ckpt torch.load(yolov8n_beast.pt, map_locationcpu) print(Checkpoint nc:, ckpt[model].nc if model in ckpt else Not found) # 检查检测头最后卷积层的权重形状应为 [2, ...] if model in ckpt: state_dict ckpt[model].state_dict() for k, v in state_dict.items(): if cv3 in k and weight in k: print(f{k}: {v.shape}) # 应该看到 torch.Size([2, ..., ..., ...]) results model.predict( sourcerF:\work\code\python\yolov8\ultralytics-train\ultralytics\data\images\test\1.jpg, # 输入源 conf0.25, # 置信度阈值 iou0.45, # NMS 的 IoU 阈值 saveTrue, # 是否保存结果 showFalse, # 是否实时显示需 GUI 环境 devicecpu # 或 cuda:0 ) # 遍历结果每张图一个 result 对象 for result in results: boxes result.boxes # 边界框 masks result.masks # 分割掩码如果模型支持 probs result.probs # 分类概率分类任务 orig_img result.orig_img # 原始图像 (HWC, BGR) annotated_frame result.plot() # 转 BGR - RGB因为 OpenCV 是 BGRmatplotlib 是 RGB rgb_img cv2.cvtColor(annotated_frame, cv2.COLOR_BGR2RGB) plt.figure(figsize(12, 8)) plt.imshow(rgb_img) plt.axis(off) plt.show() # 打印检测到的类别和坐标 for box in boxes: cls_id int(box.cls.item()) conf float(box.conf.item()) xyxy box.xyxy[0].tolist() # [x1, y1, x2, y2] print(fClass: {cls_id}, Conf: {conf:.2f}, Box: {xyxy})三、部署如果部署到rk板子有几种选择有npu的部署为rknn的模型如果没有如rk3399 没有npu那么部署onnx 或者ncnn模型这里推荐ncnn腾讯开源多年比较成熟。3.1 环境安装环境pip3 install -U ultralytics pnnx ncnn创建ncnn目录 mkdir ncnn cd ncnn3.2 导出torchscript把模型修改为yolov8n.pt 拷贝到ncnn下面执行命令yolo export modelyolov8n.pt formattorchscript导出了模型yolov8n.torchscriptpnnx yolov8n.torchscript3.3 修改pnnx文件编辑yolov8n_pnnx.py修改如下修改为v_168后面直接return掉然后后面的删除掉这里去掉后那么nms后面执行部分就需要再代码里面处理了这样可以优化速度不去除那么直接返回分类结果3.4 重新导出yolov8 torchscript执行如下命令重新导出ncnn这里我的文件是yolov8n_pnnx.py所以import 这个名称如果是其他的请导入其他名称python -c import yolov8n_pnnx; yolov8n_pnnx.export_torchscript()然后获取最新的ncnn文件后面部署到板子或者android请参考https://zhuanlan.zhihu.com/p/16030630352这里最新已经不需要先转onnx再转ncnn挺方便一步到位ncnn后续在rk3399的android下面发现执行需要大概300ms左右才能执行一帧速度有点慢后面再试试剪枝、蒸馏量化好像之前试过不加速反量化还可能耗费时间。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询