commit 1753cafaab8e27b5fd1e6d9a02d9b9142f8ab773 Author: yuzl6 Date: Tue Mar 10 17:15:05 2026 +0800 feat(yolo): 添加刀具识别AI模型训练与自动标注功能 - 新增 README.md 文档,包含完整的 YOLOv8 训练环境搭建指南 - 添加 docker-compose.yml 配置文件,支持 Mac M系列环境下的容器化部署 - 实现 train_and_export.py 核心脚本,集成模型训练、验证和ONNX格式导出功能 - 创建 data.yaml 数据集描述文件,定义刀具分类(普通刀具和管制刀具) - 开发 auto_label.py 自动标注脚本,支持AI辅助的数据集标注处理 - 集成 YOLOv8 中型模型,优化标注准确率和识别能力 - 添加数据集验证和可视化功能,便于标注质量检查 diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..6e1ac6f Binary files /dev/null and b/.DS_Store differ diff --git a/README.md b/README.md new file mode 100644 index 0000000..d008823 --- /dev/null +++ b/README.md @@ -0,0 +1,174 @@ +你好!我是 Gemini。为了确保你能顺利地在 Mac 环境下利用 Docker 完成 YOLOv8 模型的训练、验证以及最终导出(ONNX 格式),我为你整理了这份完整的文档和代码集。 + +这份文档将指导你完成从零构建训练环境到获得生产可用模型的全过程。 + +--- + +## 刀具认定 AI 模型训练与导出指南 (YOLOv8) + +### 1. 目录结构规划 + +在你的 Mac 上创建一个工作目录(例如 `knife-ai-training`),并按以下结构组织文件: + +```text +knife-ai-training/ +├── docker-compose.yml # Docker 容器配置 +├── train_and_export.py # 核心训练与导出脚本 +├── models/ # 存放生成的模型权重 (.pt, .onnx) +└── datasets/ # 存放训练数据 + └── knife_data/ + ├── data.yaml # YOLO 数据集描述文件 + ├── images/ # 存放图片 + │ ├── train/ # 训练集 + │ └── val/ # 验证集 + └── labels/ # 存放标注 (.txt) + ├── train/ + └── val/ + +``` + +--- + +### 2. 环境配置文件 (`docker-compose.yml`) + +该文件定义了一个运行 YOLOv8 所需的 Python 环境。 + +**返回的是完整代码:** + +```yaml +services: + yolov8-train: + image: ultralytics/ultralytics:latest-cpu + container_name: yolov8_knife + volumes: + # 将当前工作目录挂载到容器内的 /usr/src/app + - .:/usr/src/app + # 适配 Mac M系列(ARM64) 运行 Linux amd64 镜像 + platform: linux/amd64 + working_dir: /usr/src/app + # 保持容器持续运行,方便执行 exec 命令 + command: sleep infinity + +``` + +--- + +### 3. 数据集描述文件 (`datasets/knife_data/data.yaml`) + +此文件告诉 YOLOv8 你的数据在哪里,以及有哪些分类。 + +**返回的是完整代码:** + +```yaml +# 这里的路径必须是容器内部的绝对路径 +path: /usr/src/app/datasets/knife_data +train: images/train +val: images/val + +# 类别定义 (根据你的业务字典自定义) +names: + 0: normal_knife # 普通民用刀具 + 1: prohibited_knife # 管制刀具 + +``` + +--- + +### 4. 核心训练与导出脚本 (`train_and_export.py`) + +该脚本集成了加载预训练权重、正式训练、模型验证、以及导出为 Java 推理所需的 ONNX 格式。 + +**返回的是完整代码:** + +```python +import os +from ultralytics import YOLO + +def main(): + # 1. 选择基础模型 (yolov8n 是最轻量级,适合嵌入式和实时推理) + print(">>> 正在加载预训练模型...") + model = YOLO('yolov8n.pt') + + # 2. 开始训练 + # data: 指向 data.yaml 路径 + # epochs: 训练轮数 (模拟测试可设为 1-5,正式环境建议 100+) + # imgsz: 图片输入尺寸 (标准为 640) + # device: 'cpu' (Docker 模拟环境建议用 cpu) + print(">>> 启动模型训练...") + results = model.train( + data='/usr/src/app/datasets/knife_data/data.yaml', + epochs=10, + imgsz=640, + device='cpu', + project='models', + name='knife_task' + ) + + # 3. 验证模型 (在验证集上跑一遍结果) + print(">>> 正在执行模型验证...") + metrics = model.val() + print(f"模型精度 (mAP@50-95): {metrics.box.map}") + + # 4. 导出为 ONNX 格式 (Java / Spring Boot 推理必选) + # format: 'onnx' + # opset: 推荐 12-17,确保 Java 库的兼容性 + # slim: 压缩模型,减少体积 + print(">>> 正在导出为 ONNX 格式...") + onnx_path = model.export( + format='onnx', + imgsz=640, + opset=12, + simplify=True + ) + + print(f"\n[成功] 模型训练、验证与导出已完成!") + print(f"最终推理模型位于: {onnx_path}") + +if __name__ == "__main__": + main() + +``` + +--- + +### 5. 执行流程操作步骤 + +#### 步骤 A:启动容器 + +在 `knife-ai-training` 目录下打开 Mac 终端执行: + +```bash +docker-compose up -d + +``` + +#### 步骤 B:执行训练与导出 + +容器启动后,直接通过以下命令触发 Python 脚本: + +```bash +docker exec -it yolov8_knife python3 train_and_export.py #训练模型 +docker exec -it yolov8_knife python3 auto_label.py #标注模型 + + +``` + +#### 步骤 C:获取产出物 + +脚本运行结束后,检查你的 Mac 本地目录: + +* **训练权重**:`models/knife_task/weights/best.pt` +* **生产模型**:`models/knife_task/weights/best.onnx` (将此文件重命名为 `knife_v8.onnx` 放入 Java 项目的 `resources` 下)。 + +--- + +### 6. 给后续数据集增加的建议 + +1. **数据清洗**:确保 `images` 下的每个图片都有对应的同名 `.txt` 标签文件。 +2. **标注格式**:YOLO 格式为 `class_id x_center y_center width height`(归一化到 0-1 之间)。 +3. **样本平衡**:尽量保证管制刀具与普通刀具的图片数量比例接近 1:1,否则模型会产生“偏见”。 + +这份代码和配置为你搭建了标准化的生产线。只要你往 `datasets` 里丢新数据并重新跑一遍脚本,就能获得精度更高的模型。 + +返回的是完整代码。 +你是否需要我继续为你详细讲解 **YOLO 标注文件 (.txt) 的内部数据结构**? \ No newline at end of file diff --git a/auto_label.py b/auto_label.py new file mode 100644 index 0000000..b1356a0 --- /dev/null +++ b/auto_label.py @@ -0,0 +1,91 @@ +import os +import shutil +from ultralytics import YOLO + +# ================= 配置区 ================= +DIR_NORMAL = 'datasets/raw_normal' +DIR_PROHIBITED = 'datasets/raw_prohibited' +IMG_TARGET = 'datasets/knife_data/images/train' +LBL_TARGET = 'datasets/knife_data/labels/train' +VERIFY_DIR = 'runs/verify_labels' + +# 【关键优化 1】:换用中型模型 (yolov8m.pt),识别能力比 n 强很多 +# 如果你的 Mac 内存足够(8G以上),可以直接写 yolov8x.pt 效果最好 +model = YOLO('yolov8m.pt') +# ========================================== + +def safe_makedirs(path): + if not os.path.exists(path): + os.makedirs(path, exist_ok=True) + +def process_folder(src_dir, target_class_id, prefix): + if not os.path.exists(src_dir) or not any(f.lower().endswith(('.jpg', '.png', '.jpeg')) for f in os.listdir(src_dir)): + return + + print(f"\n🚀 正在对【{prefix}】进行深度扫描,ID -> {target_class_id}") + + # 【关键优化 2】:调低 conf (置信度阈值) + # 0.1 代表只要有 10% 的把握是刀,就把它标出来。 + results = model.predict( + source=src_dir, + conf=0.1, + save_txt=True, + save=True, + classes=[43], + project='runs/detect', + name=f'tmp_{prefix}', + exist_ok=True + ) + + actual_save_dir = results[0].save_dir + tmp_label_dir = os.path.join(actual_save_dir, 'labels') + + # 1. 搬运并修正标签 + label_count = 0 + if os.path.exists(tmp_label_dir): + for f in os.listdir(tmp_label_dir): + if f.endswith('.txt'): + src_path = os.path.join(tmp_label_dir, f) + dst_path = os.path.join(LBL_TARGET, f) + + with open(src_path, 'r') as file: + lines = file.readlines() + + corrected_lines = [f"{target_class_id} " + " ".join(l.split()[1:]) + "\n" for l in lines] + + with open(dst_path, 'w') as file: + file.writelines(corrected_lines) + label_count += 1 + + # 2. 同步图片 + img_count = 0 + for f in os.listdir(src_dir): + if f.lower().endswith(('.jpg', '.jpeg', '.png')): + shutil.copy(os.path.join(src_dir, f), os.path.join(IMG_TARGET, f)) + img_count += 1 + + # 3. 整理验证图 + for f in os.listdir(actual_save_dir): + if f.lower().endswith(('.jpg', '.jpeg', '.png')): + shutil.move(os.path.join(actual_save_dir, f), os.path.join(VERIFY_DIR, f"{prefix}_{f}")) + + print(f" ✅ 完成:图片 {img_count} 张,AI 捕获标注 {label_count} 份") + +def run_workflow(): + # 初始化环境 + for d in [IMG_TARGET, LBL_TARGET, VERIFY_DIR]: + if os.path.exists(d): shutil.rmtree(d) + safe_makedirs(d) + + process_folder(DIR_NORMAL, 0, "normal") + process_folder(DIR_PROHIBITED, 1, "prohibited") + + print("\n" + "★"*40) + print(f"✅ 自动标注执行完毕") + print(f"📊 识别统计:共生成 {len(os.listdir(LBL_TARGET))} 个标签文件") + print(f"⚠️ 警告:如果标签文件少于图片总数,说明 AI 还是没认全。") + print(f"🛠️ 下一步建议:使用 LabelImg 打开 {IMG_TARGET} 手动补齐剩下的框。") + print("★"*40) + +if __name__ == "__main__": + run_workflow() \ No newline at end of file diff --git a/datasets/.DS_Store b/datasets/.DS_Store new file mode 100644 index 0000000..9e68d30 Binary files /dev/null and b/datasets/.DS_Store differ diff --git a/datasets/knife_data/.DS_Store b/datasets/knife_data/.DS_Store new file mode 100644 index 0000000..0af77d5 Binary files /dev/null and b/datasets/knife_data/.DS_Store differ diff --git a/datasets/knife_data/data.yaml b/datasets/knife_data/data.yaml new file mode 100644 index 0000000..7f9a800 --- /dev/null +++ b/datasets/knife_data/data.yaml @@ -0,0 +1,9 @@ +# 这里的路径必须是容器内部的绝对路径 +path: /usr/src/app/datasets/knife_data +train: images/train +val: images/val + +# 类别定义 (根据你的业务字典自定义) +names: + 0: normal_knife # 普通民用刀具 + 1: prohibited_knife # 管制刀具 \ No newline at end of file diff --git a/datasets/knife_data/images/.DS_Store b/datasets/knife_data/images/.DS_Store new file mode 100644 index 0000000..dcdf81a Binary files /dev/null and b/datasets/knife_data/images/.DS_Store differ diff --git a/datasets/knife_data/labels/.DS_Store b/datasets/knife_data/labels/.DS_Store new file mode 100644 index 0000000..9370b5b Binary files /dev/null and b/datasets/knife_data/labels/.DS_Store differ diff --git a/datasets/raw_normal/105d037e9c1f1cc8a7faa4bbd698ef5a~tplv-be4g95zd3a-image.jpeg b/datasets/raw_normal/105d037e9c1f1cc8a7faa4bbd698ef5a~tplv-be4g95zd3a-image.jpeg new file mode 100644 index 0000000..b299e4b Binary files /dev/null and b/datasets/raw_normal/105d037e9c1f1cc8a7faa4bbd698ef5a~tplv-be4g95zd3a-image.jpeg differ diff --git a/datasets/raw_normal/1c337fb7b27552b48ac3b2f3493aa549~tplv-be4g95zd3a-image.jpeg b/datasets/raw_normal/1c337fb7b27552b48ac3b2f3493aa549~tplv-be4g95zd3a-image.jpeg new file mode 100644 index 0000000..0fa56d7 Binary files /dev/null and b/datasets/raw_normal/1c337fb7b27552b48ac3b2f3493aa549~tplv-be4g95zd3a-image.jpeg differ diff --git a/datasets/raw_normal/21e79ca0401830ae4f1ae207803726d7~tplv-be4g95zd3a-image.jpeg b/datasets/raw_normal/21e79ca0401830ae4f1ae207803726d7~tplv-be4g95zd3a-image.jpeg new file mode 100644 index 0000000..02304e2 Binary files /dev/null and b/datasets/raw_normal/21e79ca0401830ae4f1ae207803726d7~tplv-be4g95zd3a-image.jpeg differ diff --git a/datasets/raw_normal/98a398ae5445bc4352d6d107f8a859db~tplv-be4g95zd3a-image.jpeg b/datasets/raw_normal/98a398ae5445bc4352d6d107f8a859db~tplv-be4g95zd3a-image.jpeg new file mode 100644 index 0000000..0bdaa4a Binary files /dev/null and b/datasets/raw_normal/98a398ae5445bc4352d6d107f8a859db~tplv-be4g95zd3a-image.jpeg differ diff --git a/datasets/raw_normal/GevuHYgl_m_3aeef5f221872c11a3cdb2c201919679_sx_132274_www800-800~tplv-be4g95zd3a-image.jpeg b/datasets/raw_normal/GevuHYgl_m_3aeef5f221872c11a3cdb2c201919679_sx_132274_www800-800~tplv-be4g95zd3a-image.jpeg new file mode 100644 index 0000000..74c0e3d Binary files /dev/null and b/datasets/raw_normal/GevuHYgl_m_3aeef5f221872c11a3cdb2c201919679_sx_132274_www800-800~tplv-be4g95zd3a-image.jpeg differ diff --git a/datasets/raw_normal/a43ad512c3686f8528a261de2dd9082e~tplv-be4g95zd3a-image.jpeg b/datasets/raw_normal/a43ad512c3686f8528a261de2dd9082e~tplv-be4g95zd3a-image.jpeg new file mode 100644 index 0000000..8056e72 Binary files /dev/null and b/datasets/raw_normal/a43ad512c3686f8528a261de2dd9082e~tplv-be4g95zd3a-image.jpeg differ diff --git a/datasets/raw_normal/ab2ab79110c5db967e280832c3c477bf~tplv-be4g95zd3a-image.jpeg b/datasets/raw_normal/ab2ab79110c5db967e280832c3c477bf~tplv-be4g95zd3a-image.jpeg new file mode 100644 index 0000000..fe7d357 Binary files /dev/null and b/datasets/raw_normal/ab2ab79110c5db967e280832c3c477bf~tplv-be4g95zd3a-image.jpeg differ diff --git a/datasets/raw_normal/cb809fac056dbebc339d02b7f6b1493b~tplv-be4g95zd3a-image.jpeg b/datasets/raw_normal/cb809fac056dbebc339d02b7f6b1493b~tplv-be4g95zd3a-image.jpeg new file mode 100644 index 0000000..35c2618 Binary files /dev/null and b/datasets/raw_normal/cb809fac056dbebc339d02b7f6b1493b~tplv-be4g95zd3a-image.jpeg differ diff --git a/datasets/raw_normal/fefbffc979217caf7de001105ff3366a~tplv-be4g95zd3a-image.jpeg b/datasets/raw_normal/fefbffc979217caf7de001105ff3366a~tplv-be4g95zd3a-image.jpeg new file mode 100644 index 0000000..b3908ed Binary files /dev/null and b/datasets/raw_normal/fefbffc979217caf7de001105ff3366a~tplv-be4g95zd3a-image.jpeg differ diff --git a/datasets/raw_normal/jpeg_m_3f62ab60451946ff6b2a6af882bc9789_sx_716199_www2000-2000~tplv-be4g95zd3a-image.jpeg b/datasets/raw_normal/jpeg_m_3f62ab60451946ff6b2a6af882bc9789_sx_716199_www2000-2000~tplv-be4g95zd3a-image.jpeg new file mode 100644 index 0000000..f35ddeb Binary files /dev/null and b/datasets/raw_normal/jpeg_m_3f62ab60451946ff6b2a6af882bc9789_sx_716199_www2000-2000~tplv-be4g95zd3a-image.jpeg differ diff --git a/datasets/raw_prohibited/0bacbfcf6f33c2beb5f6698dc69bfdad~tplv-be4g95zd3a-image.jpeg b/datasets/raw_prohibited/0bacbfcf6f33c2beb5f6698dc69bfdad~tplv-be4g95zd3a-image.jpeg new file mode 100644 index 0000000..dcda097 Binary files /dev/null and b/datasets/raw_prohibited/0bacbfcf6f33c2beb5f6698dc69bfdad~tplv-be4g95zd3a-image.jpeg differ diff --git a/datasets/raw_prohibited/0fb1ac98fd43494384b6cc6fbf3397dc~tplv-be4g95zd3a-image.jpeg b/datasets/raw_prohibited/0fb1ac98fd43494384b6cc6fbf3397dc~tplv-be4g95zd3a-image.jpeg new file mode 100644 index 0000000..ccd307c Binary files /dev/null and b/datasets/raw_prohibited/0fb1ac98fd43494384b6cc6fbf3397dc~tplv-be4g95zd3a-image.jpeg differ diff --git a/datasets/raw_prohibited/3183512f0d0cea2374ee20377f8eeac3~tplv-be4g95zd3a-image.jpeg b/datasets/raw_prohibited/3183512f0d0cea2374ee20377f8eeac3~tplv-be4g95zd3a-image.jpeg new file mode 100644 index 0000000..3612926 Binary files /dev/null and b/datasets/raw_prohibited/3183512f0d0cea2374ee20377f8eeac3~tplv-be4g95zd3a-image.jpeg differ diff --git a/datasets/raw_prohibited/3911d522f35816a3a734f7bb8f0feb69~tplv-be4g95zd3a-image.jpeg b/datasets/raw_prohibited/3911d522f35816a3a734f7bb8f0feb69~tplv-be4g95zd3a-image.jpeg new file mode 100644 index 0000000..11fb7b8 Binary files /dev/null and b/datasets/raw_prohibited/3911d522f35816a3a734f7bb8f0feb69~tplv-be4g95zd3a-image.jpeg differ diff --git a/datasets/raw_prohibited/44207f6c4f4602f0b9a48708f032053f~tplv-be4g95zd3a-image.jpeg b/datasets/raw_prohibited/44207f6c4f4602f0b9a48708f032053f~tplv-be4g95zd3a-image.jpeg new file mode 100644 index 0000000..e51d8f5 Binary files /dev/null and b/datasets/raw_prohibited/44207f6c4f4602f0b9a48708f032053f~tplv-be4g95zd3a-image.jpeg differ diff --git a/datasets/raw_prohibited/83af32d1c23d64366dba3212274a32ff~tplv-be4g95zd3a-image.jpeg b/datasets/raw_prohibited/83af32d1c23d64366dba3212274a32ff~tplv-be4g95zd3a-image.jpeg new file mode 100644 index 0000000..2b52499 Binary files /dev/null and b/datasets/raw_prohibited/83af32d1c23d64366dba3212274a32ff~tplv-be4g95zd3a-image.jpeg differ diff --git a/datasets/raw_prohibited/d36027a558ae5a07e583387cada60116~tplv-be4g95zd3a-image.jpeg b/datasets/raw_prohibited/d36027a558ae5a07e583387cada60116~tplv-be4g95zd3a-image.jpeg new file mode 100644 index 0000000..bd52e02 Binary files /dev/null and b/datasets/raw_prohibited/d36027a558ae5a07e583387cada60116~tplv-be4g95zd3a-image.jpeg differ diff --git a/datasets/raw_prohibited/db1815b98c1379541fe6682da9c1639f~tplv-be4g95zd3a-image.jpeg b/datasets/raw_prohibited/db1815b98c1379541fe6682da9c1639f~tplv-be4g95zd3a-image.jpeg new file mode 100644 index 0000000..4504a85 Binary files /dev/null and b/datasets/raw_prohibited/db1815b98c1379541fe6682da9c1639f~tplv-be4g95zd3a-image.jpeg differ diff --git a/datasets/raw_prohibited/jpeg_m_729f1c786fd74e44ad9efd3044f9fe22_sx_178191_www800-800~tplv-be4g95zd3a-image.jpeg b/datasets/raw_prohibited/jpeg_m_729f1c786fd74e44ad9efd3044f9fe22_sx_178191_www800-800~tplv-be4g95zd3a-image.jpeg new file mode 100644 index 0000000..bc932de Binary files /dev/null and b/datasets/raw_prohibited/jpeg_m_729f1c786fd74e44ad9efd3044f9fe22_sx_178191_www800-800~tplv-be4g95zd3a-image.jpeg differ diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..19d62f7 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,12 @@ +services: + yolov8-train: + image: ultralytics/ultralytics:latest-cpu + container_name: yolov8_knife + volumes: + # 将当前工作目录挂载到容器内的 /usr/src/app + - .:/usr/src/app + # 适配 Mac M系列(ARM64) 运行 Linux amd64 镜像 + platform: linux/amd64 + working_dir: /usr/src/app + # 保持容器持续运行,方便执行 exec 命令 + command: sleep infinity \ No newline at end of file diff --git a/runs/.DS_Store b/runs/.DS_Store new file mode 100644 index 0000000..26a2f22 Binary files /dev/null and b/runs/.DS_Store differ diff --git a/runs/verify_labels/normal_105d037e9c1f1cc8a7faa4bbd698ef5a~tplv-be4g95zd3a-image.jpg b/runs/verify_labels/normal_105d037e9c1f1cc8a7faa4bbd698ef5a~tplv-be4g95zd3a-image.jpg new file mode 100644 index 0000000..373a9ad Binary files /dev/null and b/runs/verify_labels/normal_105d037e9c1f1cc8a7faa4bbd698ef5a~tplv-be4g95zd3a-image.jpg differ diff --git a/runs/verify_labels/normal_1c337fb7b27552b48ac3b2f3493aa549~tplv-be4g95zd3a-image.jpg b/runs/verify_labels/normal_1c337fb7b27552b48ac3b2f3493aa549~tplv-be4g95zd3a-image.jpg new file mode 100644 index 0000000..c89a307 Binary files /dev/null and b/runs/verify_labels/normal_1c337fb7b27552b48ac3b2f3493aa549~tplv-be4g95zd3a-image.jpg differ diff --git a/runs/verify_labels/normal_21e79ca0401830ae4f1ae207803726d7~tplv-be4g95zd3a-image.jpg b/runs/verify_labels/normal_21e79ca0401830ae4f1ae207803726d7~tplv-be4g95zd3a-image.jpg new file mode 100644 index 0000000..ec31388 Binary files /dev/null and b/runs/verify_labels/normal_21e79ca0401830ae4f1ae207803726d7~tplv-be4g95zd3a-image.jpg differ diff --git a/runs/verify_labels/normal_98a398ae5445bc4352d6d107f8a859db~tplv-be4g95zd3a-image.jpg b/runs/verify_labels/normal_98a398ae5445bc4352d6d107f8a859db~tplv-be4g95zd3a-image.jpg new file mode 100644 index 0000000..fb1d7b0 Binary files /dev/null and b/runs/verify_labels/normal_98a398ae5445bc4352d6d107f8a859db~tplv-be4g95zd3a-image.jpg differ diff --git a/runs/verify_labels/normal_GevuHYgl_m_3aeef5f221872c11a3cdb2c201919679_sx_132274_www800-800~tplv-be4g95zd3a-image.jpg b/runs/verify_labels/normal_GevuHYgl_m_3aeef5f221872c11a3cdb2c201919679_sx_132274_www800-800~tplv-be4g95zd3a-image.jpg new file mode 100644 index 0000000..9a74aa2 Binary files /dev/null and b/runs/verify_labels/normal_GevuHYgl_m_3aeef5f221872c11a3cdb2c201919679_sx_132274_www800-800~tplv-be4g95zd3a-image.jpg differ diff --git a/runs/verify_labels/normal_a43ad512c3686f8528a261de2dd9082e~tplv-be4g95zd3a-image.jpg b/runs/verify_labels/normal_a43ad512c3686f8528a261de2dd9082e~tplv-be4g95zd3a-image.jpg new file mode 100644 index 0000000..8559183 Binary files /dev/null and b/runs/verify_labels/normal_a43ad512c3686f8528a261de2dd9082e~tplv-be4g95zd3a-image.jpg differ diff --git a/runs/verify_labels/normal_ab2ab79110c5db967e280832c3c477bf~tplv-be4g95zd3a-image.jpg b/runs/verify_labels/normal_ab2ab79110c5db967e280832c3c477bf~tplv-be4g95zd3a-image.jpg new file mode 100644 index 0000000..5490cf8 Binary files /dev/null and b/runs/verify_labels/normal_ab2ab79110c5db967e280832c3c477bf~tplv-be4g95zd3a-image.jpg differ diff --git a/runs/verify_labels/normal_cb809fac056dbebc339d02b7f6b1493b~tplv-be4g95zd3a-image.jpg b/runs/verify_labels/normal_cb809fac056dbebc339d02b7f6b1493b~tplv-be4g95zd3a-image.jpg new file mode 100644 index 0000000..e953b06 Binary files /dev/null and b/runs/verify_labels/normal_cb809fac056dbebc339d02b7f6b1493b~tplv-be4g95zd3a-image.jpg differ diff --git a/runs/verify_labels/normal_fefbffc979217caf7de001105ff3366a~tplv-be4g95zd3a-image.jpg b/runs/verify_labels/normal_fefbffc979217caf7de001105ff3366a~tplv-be4g95zd3a-image.jpg new file mode 100644 index 0000000..59f228a Binary files /dev/null and b/runs/verify_labels/normal_fefbffc979217caf7de001105ff3366a~tplv-be4g95zd3a-image.jpg differ diff --git a/runs/verify_labels/normal_jpeg_m_3f62ab60451946ff6b2a6af882bc9789_sx_716199_www2000-2000~tplv-be4g95zd3a-image.jpg b/runs/verify_labels/normal_jpeg_m_3f62ab60451946ff6b2a6af882bc9789_sx_716199_www2000-2000~tplv-be4g95zd3a-image.jpg new file mode 100644 index 0000000..02c76da Binary files /dev/null and b/runs/verify_labels/normal_jpeg_m_3f62ab60451946ff6b2a6af882bc9789_sx_716199_www2000-2000~tplv-be4g95zd3a-image.jpg differ diff --git a/runs/verify_labels/prohibited_0bacbfcf6f33c2beb5f6698dc69bfdad~tplv-be4g95zd3a-image.jpg b/runs/verify_labels/prohibited_0bacbfcf6f33c2beb5f6698dc69bfdad~tplv-be4g95zd3a-image.jpg new file mode 100644 index 0000000..ac23f31 Binary files /dev/null and b/runs/verify_labels/prohibited_0bacbfcf6f33c2beb5f6698dc69bfdad~tplv-be4g95zd3a-image.jpg differ diff --git a/runs/verify_labels/prohibited_0fb1ac98fd43494384b6cc6fbf3397dc~tplv-be4g95zd3a-image.jpg b/runs/verify_labels/prohibited_0fb1ac98fd43494384b6cc6fbf3397dc~tplv-be4g95zd3a-image.jpg new file mode 100644 index 0000000..d460145 Binary files /dev/null and b/runs/verify_labels/prohibited_0fb1ac98fd43494384b6cc6fbf3397dc~tplv-be4g95zd3a-image.jpg differ diff --git a/runs/verify_labels/prohibited_3183512f0d0cea2374ee20377f8eeac3~tplv-be4g95zd3a-image.jpg b/runs/verify_labels/prohibited_3183512f0d0cea2374ee20377f8eeac3~tplv-be4g95zd3a-image.jpg new file mode 100644 index 0000000..3e3cdd8 Binary files /dev/null and b/runs/verify_labels/prohibited_3183512f0d0cea2374ee20377f8eeac3~tplv-be4g95zd3a-image.jpg differ diff --git a/runs/verify_labels/prohibited_3911d522f35816a3a734f7bb8f0feb69~tplv-be4g95zd3a-image.jpg b/runs/verify_labels/prohibited_3911d522f35816a3a734f7bb8f0feb69~tplv-be4g95zd3a-image.jpg new file mode 100644 index 0000000..1efeced Binary files /dev/null and b/runs/verify_labels/prohibited_3911d522f35816a3a734f7bb8f0feb69~tplv-be4g95zd3a-image.jpg differ diff --git a/runs/verify_labels/prohibited_44207f6c4f4602f0b9a48708f032053f~tplv-be4g95zd3a-image.jpg b/runs/verify_labels/prohibited_44207f6c4f4602f0b9a48708f032053f~tplv-be4g95zd3a-image.jpg new file mode 100644 index 0000000..08ca9f6 Binary files /dev/null and b/runs/verify_labels/prohibited_44207f6c4f4602f0b9a48708f032053f~tplv-be4g95zd3a-image.jpg differ diff --git a/runs/verify_labels/prohibited_83af32d1c23d64366dba3212274a32ff~tplv-be4g95zd3a-image.jpg b/runs/verify_labels/prohibited_83af32d1c23d64366dba3212274a32ff~tplv-be4g95zd3a-image.jpg new file mode 100644 index 0000000..df6e88d Binary files /dev/null and b/runs/verify_labels/prohibited_83af32d1c23d64366dba3212274a32ff~tplv-be4g95zd3a-image.jpg differ diff --git a/runs/verify_labels/prohibited_d36027a558ae5a07e583387cada60116~tplv-be4g95zd3a-image.jpg b/runs/verify_labels/prohibited_d36027a558ae5a07e583387cada60116~tplv-be4g95zd3a-image.jpg new file mode 100644 index 0000000..3856998 Binary files /dev/null and b/runs/verify_labels/prohibited_d36027a558ae5a07e583387cada60116~tplv-be4g95zd3a-image.jpg differ diff --git a/runs/verify_labels/prohibited_db1815b98c1379541fe6682da9c1639f~tplv-be4g95zd3a-image.jpg b/runs/verify_labels/prohibited_db1815b98c1379541fe6682da9c1639f~tplv-be4g95zd3a-image.jpg new file mode 100644 index 0000000..9c3e52a Binary files /dev/null and b/runs/verify_labels/prohibited_db1815b98c1379541fe6682da9c1639f~tplv-be4g95zd3a-image.jpg differ diff --git a/runs/verify_labels/prohibited_jpeg_m_729f1c786fd74e44ad9efd3044f9fe22_sx_178191_www800-800~tplv-be4g95zd3a-image.jpg b/runs/verify_labels/prohibited_jpeg_m_729f1c786fd74e44ad9efd3044f9fe22_sx_178191_www800-800~tplv-be4g95zd3a-image.jpg new file mode 100644 index 0000000..9f5e89d Binary files /dev/null and b/runs/verify_labels/prohibited_jpeg_m_729f1c786fd74e44ad9efd3044f9fe22_sx_178191_www800-800~tplv-be4g95zd3a-image.jpg differ diff --git a/train_and_export.py b/train_and_export.py new file mode 100644 index 0000000..2774329 --- /dev/null +++ b/train_and_export.py @@ -0,0 +1,45 @@ +import os +from ultralytics import YOLO + +def main(): + # 1. 选择基础模型 (yolov8n 是最轻量级,适合嵌入式和实时推理) + print(">>> 正在加载预训练模型...") + model = YOLO('yolov8n.pt') + + # 2. 开始训练 + # data: 指向 data.yaml 路径 + # epochs: 训练轮数 (模拟测试可设为 1-5,正式环境建议 100+) + # imgsz: 图片输入尺寸 (标准为 640) + # device: 'cpu' (Docker 模拟环境建议用 cpu) + print(">>> 启动模型训练...") + results = model.train( + data='/usr/src/app/datasets/knife_data/data.yaml', + epochs=10, + imgsz=640, + device='cpu', + project='models', + name='knife_task' + ) + + # 3. 验证模型 (在验证集上跑一遍结果) + print(">>> 正在执行模型验证...") + metrics = model.val() + print(f"模型精度 (mAP@50-95): {metrics.box.map}") + + # 4. 导出为 ONNX 格式 (Java / Spring Boot 推理必选) + # format: 'onnx' + # opset: 推荐 12-17,确保 Java 库的兼容性 + # slim: 压缩模型,减少体积 + print(">>> 正在导出为 ONNX 格式...") + onnx_path = model.export( + format='onnx', + imgsz=640, + opset=12, + simplify=True + ) + + print(f"\n[成功] 模型训练、验证与导出已完成!") + print(f"最终推理模型位于: {onnx_path}") + +if __name__ == "__main__": + main() \ No newline at end of file