瀏覽代碼

yolo 学习,以及文档

zhzhenqin 5 月之前
當前提交
7cc6803a9d
共有 11 個文件被更改,包括 437 次插入0 次删除
  1. 27 0
      .gitignore
  2. 68 0
      docs/YOLO标注以及自定义数据集.md
  3. 60 0
      docs/YOLO模型训练.md
  4. 30 0
      docs/YOLO模型验证.md
  5. 22 0
      docs/YOLO环境安装.md
  6. 二進制
      docs/images/label-image-labels.png
  7. 二進制
      docs/images/labelimg.png
  8. 38 0
      rsync_local.sh
  9. 96 0
      split_data.py
  10. 22 0
      test1.py
  11. 74 0
      trans_images.py

+ 27 - 0
.gitignore

@@ -0,0 +1,27 @@
+*.log
+*.pyc
+*.svn
+*.iml
+*.day
+*.tnf
+*.tfz
+*.tdx
+*.egg
+.classpath
+.project
+*.bak
+*.egg-info
+
+# Package Files #
+.svn
+.idea
+.settings
+.ipynb_checkpoints
+.vscode
+target
+db
+runs
+datasets
+build
+dist
+logs

+ 68 - 0
docs/YOLO标注以及自定义数据集.md

@@ -0,0 +1,68 @@
+## YOLO标注工具
+
+YOLO 提供默认的标注工具:
+
+```shell
+pip install labelimg
+```
+
+安装后,执行 `labelimg` 打开标注工具。
+
+![labelimg](images/labelimg.png)
+
+数据集和标签选择:
+
+![数据集和标签](images/label-image-labels.png)
+
+## 自定义数据集
+
+自定义数据集再 datasets 下创建指定的数据集和名称。
+
+```log
+.
+|____datasets
+| |____coco128
+| | |____LICENSE
+| | |____images
+| | | |____train2017
+| | | | |____000000000009.jpg
+| | | | |____000000000025.jpg
+| | |____labels
+| | | |____train2017.cache
+| | | |____train2017
+| | | | |____000000000009.txt
+| | | | |____000000000025.txt
+```
+
+再 datasets 下创建 `coco128.yaml` 文件,内容如下:
+
+```yml
+path: /path/coco128
+train: images/train2017
+val: images/train2017
+nc: 80
+names: [person, bicycle, car, motorcycle, airplane, bus, ...]
+```
+
+或
+
+```yml
+names:
+  0: 'person'
+  1: 'bicycle'
+  2: 'car'
+  3: 'motorcycle'
+  4: 'airplane'
+  5: 'bus'
+nc: 6
+train: /path/train
+val: /path/val
+```
+
+## 参考
+
+- [如何使用YOLOv8训练自己的模型和进行预测](https://www.cnblogs.com/qqsj/p/17492360.html)
+- [Yolo V5标注图片](https://blog.csdn.net/geji001/article/details/133896362)
+- [目标检测VOC格式标注转YOLO标注](https://blog.csdn.net/qq_46300009/article/details/136074559)
+- [利用YOLO标注并训练自己的数据集](https://blog.csdn.net/qq_54452082/article/details/137070072)
+- [使用labelimg对YOLO数据进行标注](https://blog.csdn.net/qq_41940277/article/details/136302943)

+ 60 - 0
docs/YOLO模型训练.md

@@ -0,0 +1,60 @@
+## YOLO 采用命令训练数据集
+
+```shell
+yolo train data=coco128.yaml model=yolov8n.pt epochs=10 lr0=0.01
+
+yolo task=detect mode=train model=yolov8x.yaml data=mydata.yaml epochs=10 batch=16
+
+yolo task=segment mode=predict model=yolov8x-seg.pt source='/kaggle/input/personpng/1.jpg'
+```
+
+以上参数解释如下:
+
+- task:选择任务类型,可选['detect', 'segment', 'classify', 'init']
+- mode: 选择是训练、验证还是预测的任务蕾西 可选['train', 'val', 'predict']
+- model: 选择yolov8不同的模型配置文件,可选yolov8s.yaml、yolov8m.yaml、yolov8l.yaml、yolov8x.yam
+- data: 选择生成的数据集配置文件
+- epochs:指的就是训练过程中整个数据集将被迭代多少次,显卡不行你就调小点。
+- batch:一次看完多少张图片才进行权重更新,梯度下降的mini-batch,显卡不行你就调小点。
+
+## YOLO 采用代码测试数据集
+
+```python
+from ultralytics import YOLO
+
+# Create a new YOLO model from scratch
+model = YOLO('yolov8n.yaml')
+# Load a pretrained YOLO model (recommended for training)
+model = YOLO('yolov8n.pt')
+
+# Train the model using the 'coco128.yaml' dataset for 3 epochs
+results = model.train(data='coco128.yaml', epochs=3)
+# Evaluate the model's performance on the validation set
+results = model.val()
+# Perform object detection on an image using the model
+results = model('https://ultralytics.com/images/bus.jpg')
+# Export the model to ONNX format
+success = model.export(format='onnx')
+```
+
+训练参数:
+```python
+workers = 1
+batch = 8
+data_name = "TrafficSign"
+model = YOLO(abs_path('./weights/yolov5nu.pt', path_type='current'), task='detect')  # 加载预训练的YOLOv8模型
+results = model.train(  # 开始训练模型
+    data=data_path,  # 指定训练数据的配置文件路径
+    device='cpu',  # 指定使用CPU进行训练
+    workers=workers,  # 指定使用2个工作进程加载数据
+    imgsz=640,  # 指定输入图像的大小为640x640
+    epochs=100,  # 指定训练100个epoch
+    batch=batch,  # 指定每个批次的大小为8
+    name='train_v5_' + data_name  # 指定训练任务的名称
+)
+```
+
+## 参考
+
+- https://blog.csdn.net/qq_32892383/article/details/136505299
+- https://blog.csdn.net/wzk4869/article/details/131608489

+ 30 - 0
docs/YOLO模型验证.md

@@ -0,0 +1,30 @@
+## 采用命令
+
+```shell
+yolo predict model=yolov8n.pt source=/path/钢绳/人船.jpg
+```
+
+输出:
+
+```log
+Ultralytics YOLOv8.2.48 🚀 Python-3.8.10 torch-1.13.1 CPU (Intel Core(TM) i9-9880H 2.30GHz)
+YOLOv8n summary (fused): 168 layers, 3151904 parameters, 0 gradients, 8.7 GFLOPs
+
+image 1/1 /path/钢绳/人船.jpg: 448x640 1 person, 1 boat, 165.1ms
+Speed: 8.1ms preprocess, 165.1ms inference, 15.0ms postprocess per image at shape (1, 3, 448, 640)
+Results saved to runs/detect/predict3
+💡 Learn more at https://docs.ultralytics.com/modes/predict
+```
+
+## YOLO 模型导出 ONNX
+
+采用 yolo 导出为 onnx 格式。
+
+```shell
+yolo export model=yolov8n-cls.pt format=onnx imgsz=224,128
+```
+
+**注意:**
+
+(最新的yolo8改用默认GPU版的onnxruntime,要安装一下下面的库,否则ONNX转换会有警告)
+pip install onnxruntime-gpu -i https://pypi.tuna.tsinghua.edu.cn/simple

+ 22 - 0
docs/YOLO环境安装.md

@@ -0,0 +1,22 @@
+## 参考环境
+
+硬件:CPU(无显卡)
+系统:Debian 12.6
+Python: 3.8.19
+
+INFO:`Ultralytics YOLOv8.1.42 🚀 Python-3.8.19 torch-1.13.1+cu117 CPU (Intel Xeon E5-2670 v3 2.30GHz)`
+
+## 安装库
+
+采用 pip 安装第三方库
+
+```shell
+pip install matplotlib==3.6.2 matplotlib-inline==0.1.6
+pip install onnx==1.16.1 onnxruntime==1.16.3 netron==7.6.9 opencv-python==4.9.0.80
+pip install pandas==1.5.3
+pip install torch==1.13.1 torchvision==0.14.1 ultralytics==8.1.42 torchaudio==0.13.1 
+# pytorch-cuda=11.7 
+pip install ultralytics
+```
+
+因为没有显卡,所以无需安装 torch-cuda 以及 onnx-gpu 版本。

二進制
docs/images/label-image-labels.png


二進制
docs/images/labelimg.png


+ 38 - 0
rsync_local.sh

@@ -0,0 +1,38 @@
+#!/usr/bin/env bash
+
+SCRIPT="$0"
+# SCRIPT may be an arbitrarily deep series of symlinks. Loop until we have the concrete path.
+while [ -h "$SCRIPT" ] ; do
+  ls=`ls -ld "$SCRIPT"`
+  # Drop everything prior to ->
+  link=`expr "$ls" : '.*-> \(.*\)$'`
+  if expr "$link" : '/.*' > /dev/null; then
+    SCRIPT="$link"
+  else
+    SCRIPT=`dirname "$SCRIPT"`/"$link"
+  fi
+done
+
+APP_HOME=`dirname "$SCRIPT"`
+export APP_HOME=`cd "$APP_HOME"; pwd`
+
+NODE_USER=$1
+TO_PATH=$2
+
+if [ $NODE_USER = ""]; then
+    echo "Use: rsync_local.sh user@host /path/dir"
+    exit 2
+fi
+if [ $TO_PATH = ""]; then
+    echo "Use: rsync_local.sh user@host /path/dir"
+    exit 2
+fi
+
+echo "APP_HOME=$APP_HOME"
+echo "NODE_USER=$NODE_USER"
+echo "TO_PATH=$TO_PATH"
+
+echo "sync node: $NODE_USER"
+echo rsync -vazu --progress $APP_HOME/* $NODE_USER:$TO_PATH
+rsync -vazu --progress $APP_HOME/* "$NODE_USER":$TO_PATH
+

+ 96 - 0
split_data.py

@@ -0,0 +1,96 @@
+#!/usr/bin/env python
+# -*- coding:utf-8 -*-
+
+"""
+在split_data.py文件中放入以下代码并运行,这个文件是划分训练、验证、测试集。其中支持修改train_percent、val_percent、test_percent,改变训练集、验证集和测试集比例
+"""
+# 将图片和标注数据按比例切分为 训练集和测试集
+import shutil
+import random
+import os
+import argparse
+
+# 检查文件夹是否存在
+def mkdir(path):
+    if not os.path.exists(path):
+        os.makedirs(path)
+
+def main(image_dir, txt_dir, save_dir):
+    # 创建文件夹
+    mkdir(save_dir)
+    images_dir = os.path.join(save_dir, 'images')
+    labels_dir = os.path.join(save_dir, 'labels')
+
+    img_train_path = os.path.join(images_dir, 'train')
+    img_test_path = os.path.join(images_dir, 'test')
+    img_val_path = os.path.join(images_dir, 'val')
+
+    label_train_path = os.path.join(labels_dir, 'train')
+    label_test_path = os.path.join(labels_dir, 'test')
+    label_val_path = os.path.join(labels_dir, 'val')
+
+    mkdir(images_dir);
+    mkdir(labels_dir);
+    mkdir(img_train_path);
+    mkdir(img_test_path);
+    mkdir(img_val_path);
+    mkdir(label_train_path);
+    mkdir(label_test_path);
+    mkdir(label_val_path);
+
+    # 数据集划分比例,训练集80%,验证集10%,测试集10%,按需修改
+    train_percent = 0.8
+    val_percent = 0.1
+    test_percent = 0.1
+
+    total_txt = os.listdir(txt_dir)
+    num_txt = len(total_txt)
+    list_all_txt = range(num_txt)  # 范围 range(0, num)
+
+    num_train = int(num_txt * train_percent)
+    num_val = int(num_txt * val_percent)
+    num_test = num_txt - num_train - num_val
+
+    train = random.sample(list_all_txt, num_train)
+    # 在全部数据集中取出train
+    val_test = [i for i in list_all_txt if not i in train]
+    # 再从val_test取出num_val个元素,val_test剩下的元素就是test
+    val = random.sample(val_test, num_val)
+
+    print("训练集数目:{}, 验证集数目:{},测试集数目:{}".format(len(train), len(val), len(val_test) - len(val)))
+    for i in list_all_txt:
+        name = total_txt[i][:-4]
+
+        srcImage = os.path.join(image_dir, name + '.jpg')
+        srcLabel = os.path.join(txt_dir, name + '.txt')
+
+        if i in train:
+            dst_train_Image = os.path.join(img_train_path, name + '.jpg')
+            dst_train_Label = os.path.join(label_train_path, name + '.txt')
+            shutil.copyfile(srcImage, dst_train_Image)
+            shutil.copyfile(srcLabel, dst_train_Label)
+        elif i in val:
+            dst_val_Image = os.path.join(img_val_path, name + '.jpg')
+            dst_val_Label = os.path.join(label_val_path, name + '.txt')
+            shutil.copyfile(srcImage, dst_val_Image)
+            shutil.copyfile(srcLabel, dst_val_Label)
+        else:
+            dst_test_Image = os.path.join(img_test_path, name + '.jpg')
+            dst_test_Label = os.path.join(label_test_path, name + '.txt')
+            shutil.copyfile(srcImage, dst_test_Image)
+            shutil.copyfile(srcLabel, dst_test_Label)
+
+
+if __name__ == '__main__':
+    """
+    python split_datasets.py --image-dir my_datasets/color_rings/imgs --txt-dir my_datasets/color_rings/txts --save-dir my_datasets/color_rings/train_data
+    """
+    parser = argparse.ArgumentParser(description='split datasets to train,val,test params')
+    parser.add_argument('--image-dir', type=str, default=r"VOCdevkit\images", help='image path dir')
+    parser.add_argument('--txt-dir', type=str, default=r"VOCdevkit\txt", help='txt path dir')
+    parser.add_argument('--save-dir', default=r"VOCdevkit\datsets", type=str, help='save dir')
+    args = parser.parse_args()
+    image_dir = args.image_dir
+    txt_dir = args.txt_dir
+    save_dir = args.save_dir
+    main(image_dir, txt_dir, save_dir)

+ 22 - 0
test1.py

@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+# -*- coding:utf-8 -*-
+
+from ultralytics import YOLO
+
+# Create a new YOLO model from scratch
+model = YOLO('yolov8n.yaml')
+
+# Load a pretrained YOLO model (recommended for training)
+model = YOLO('yolov8n.pt')
+
+# Train the model using the 'coco128.yaml' dataset for 3 epochs
+results = model.train(data='coco128.yaml', epochs=3)
+
+# Evaluate the model's performance on the validation set
+results = model.val()
+
+# Perform object detection on an image using the model
+results = model('https://ultralytics.com/images/bus.jpg')
+
+# Export the model to ONNX format
+success = model.export(format='onnx')

+ 74 - 0
trans_images.py

@@ -0,0 +1,74 @@
+#!/usr/bin/env python
+# -*- coding:utf-8 -*-
+
+import os
+from PIL import Image
+
+folder_path = "/Users/zhenqin/Downloads/钢绳"  # Replace with the actual folder path
+
+
+# 1.将图片统一为纵向 --------------------------------------------------------------------------------------------------
+# Iterate over the files in the folder
+for filename in os.listdir(folder_path):
+    if filename.endswith(".jpg") or filename.endswith(".png"):  # Adjust file extensions as needed
+        file_path = os.path.join(folder_path, filename)
+
+        # Open the image
+        image = Image.open(file_path)
+        width, height = image.size
+
+        # Compare horizontal and vertical pixel values
+        if width > height:
+            # Rotate the image 90 degrees clockwise
+            rotated_image = image.rotate(-90, expand=True)
+
+            # Save the rotated image, overwrite the original file
+            rotated_image.save(file_path)
+
+            print(f"Image '{filename}' rotated.")
+        else:
+            print(f"No operation required for image '{filename}'.")
+
+
+# 2.统一图片分辨率 --------------------------------------------------------------------------------------------------
+def resize_images(folder_path, target_resolution):
+    # 遍历文件夹中的所有文件
+    for filename in os.listdir(folder_path):
+        file_path = os.path.join(folder_path, filename)
+
+        # 检查文件是否是图片
+        if not os.path.isfile(file_path) or not any(
+                file_path.endswith(extension) for extension in ['.jpg', '.jpeg', '.png']):
+            continue
+
+        # 打开图片
+        image = Image.open(file_path)
+
+        # 获取原始分辨率
+        original_resolution = image.size
+
+        # 计算调整比例
+        ratio = min(target_resolution[0] / original_resolution[0], target_resolution[1] / original_resolution[1])
+
+        # 计算调整后的尺寸
+        resized_size = (int(original_resolution[0] * ratio), int(original_resolution[1] * ratio))
+
+        # 调整图片分辨率
+        resized_image = image.resize(resized_size)
+
+        # 创建空白画布
+        canvas = Image.new('RGB', target_resolution, (255, 255, 255))
+
+        # 在画布上居中粘贴调整后的图片
+        offset = ((target_resolution[0] - resized_size[0]) // 2, (target_resolution[1] - resized_size[1]) // 2)
+        canvas.paste(resized_image, offset)
+
+        # 保存调整后的图片
+        canvas.save(file_path)
+
+
+# 指定文件夹路径和目标分辨率
+target_resolution = (460, 460)  # 替换为你的目标分辨率
+
+# 调用函数进行图片分辨率统一
+resize_images(folder_path, target_resolution)