yolov8(8.2.10版本)训练自己的目标检测数据集(windows10)

、一 数据标注与处理

(一)数据标注

   使用labelme标注数据 

标注完后在图片文件夹李会有对应的json文件(如图)

使用此代码可视化检查数据

# 导入工具包
import os
import cv2
import numpy as np
import json

import matplotlib.pyplot as plt



num = 0
# 图片与标签json的文件夹路径
files_path = r"D:\Myself_project\YOLOV8pose\data_me\Goal_Detect_data\xxxxx\images"
for file in os.listdir(files_path):
    if file.endswith(".jpg"):
        img_path = os.path.join(files_path, file)
        img_bgr = cv2.imread(img_path)

        file_profix = os.path.splitext(file)[0]
        labelme_name = file_profix + '.json'                         # DSC_0219.json
        labelme_path = os.path.join(files_path, labelme_name)
        # 载入labelme格式的json标注文件
        with open(labelme_path, 'r', encoding='utf-8') as f:
            labelme = json.load(f)

        # <<<<<<<<<<<<<<<<<<可视化框(rectangle)标注>>>>>>>>>>>>>>>>>>>>>
        # 框可视化配置
        bbox_color = (255, 129, 0)  # 框的颜色
        bbox_thickness = 5  # 框的线宽

        # 框类别文字
        bbox_labelstr = {
            'font_size': 6,  # 字体大小
            'font_thickness': 14,  # 字体粗细
            'offset_x': 0,  # X 方向,文字偏移距离,向右为正
            'offset_y': -80,  # Y 方向,文字偏移距离,向下为正
        }
        # 画框
        for each_ann in labelme['shapes']:  # 遍历每一个标注
            if each_ann['shape_type'] == 'rectangle':  # 筛选出框标注
                # 框的类别
                bbox_label = each_ann['label']
                # 框的两点坐标
                bbox_keypoints = each_ann['points']
                bbox_keypoint_A_xy = bbox_keypoints[0]
                bbox_keypoint_B_xy = bbox_keypoints[1]
                # 左上角坐标
                bbox_top_left_x = int(min(bbox_keypoint_A_xy[0], bbox_keypoint_B_xy[0]))
                bbox_top_left_y = int(min(bbox_keypoint_A_xy[1], bbox_keypoint_B_xy[1]))
                # 右下角坐标
                bbox_bottom_right_x = int(max(bbox_keypoint_A_xy[0], bbox_keypoint_B_xy[0]))
                bbox_bottom_right_y = int(max(bbox_keypoint_A_xy[1], bbox_keypoint_B_xy[1]))

                # 画矩形:画框
                img_bgr = cv2.rectangle(img_bgr, (bbox_top_left_x, bbox_top_left_y), (bbox_bottom_right_x, bbox_bottom_right_y),
                                        bbox_color, bbox_thickness)
                # 写框类别文字:图片,文字字符串,文字左上角坐标,字体,字体大小,颜色,字体粗细
                img_bgr = cv2.putText(img_bgr, bbox_label, (
                    bbox_top_left_x + bbox_labelstr['offset_x'],
                    bbox_top_left_y + bbox_labelstr['offset_y']),
                                      cv2.FONT_HERSHEY_SIMPLEX, bbox_labelstr['font_size'], bbox_color,
                                      bbox_labelstr['font_thickness'])
        # 可视化
        plt.imshow(img_bgr[:, :, ::-1])  # 将bgr通道转换成rgb通道 (为防止图片过大 cv2不好展示所有用pil)
        plt.show()

运行结果:

(二)数据处理

   用下面代码把上面文件夹下的图片与json标签分开

import os
import shutil

# 图片与json标签的同一文件夹路径
source_folder = 'images'
# 分出后用来只存放图片的路径
out_img_folder = 'data_me/images'
# 分出后用来只存放json标签的路径
out_json_folder = "data_me/label_json"

# 确保目标文件夹存在,如果不存在则创建
os.makedirs(out_img_folder, exist_ok=True)
os.makedirs(out_json_folder, exist_ok=True)

for file_name in os.listdir(source_folder):
    source_file_path = os.path.join(source_folder, file_name)
    if file_name.endswith('.jpg'):
        source_img_file_path = os.path.join(source_folder, file_name)
        destination_img_file_path = os.path.join(out_img_folder, file_name)
        shutil.move(source_img_file_path, destination_img_file_path)

    elif file_name.endswith('.json'):
        source_json_file_path = os.path.join(source_folder, file_name)
        destination_json_file_path = os.path.join(out_json_folder, file_name)
        shutil.move(source_json_file_path, destination_json_file_path)
print("=======ok")

运行完成后得到如下:

使用以下代码划分数据集

import os
import shutil

from tqdm import tqdm
import random

""" 使用:只需要修改 1. Dataset_folde,    
                  2. os.chdir(os.path.join(Dataset_folder, 'images'))里的 images, 
                  3. val_scal = 0.2 
                  4. os.chdir('../label_json')          label_json换成自己json标签文件夹名称   """


# 图片文件夹与json标签文件夹的根目录
Dataset_folder = r'D:\Myself_project\YOLOV8pose\data_me\Goal_Detect_data\xxxxx'

# 把当前工作目录改为指定路径
os.chdir(os.path.join(Dataset_folder, 'images'))   # images : 图片文件夹的名称
folder = '.'                  # 代表os.chdir(os.path.join(Dataset_folder, 'images'))这个路径
imgs_list = os.listdir(folder)

random.seed(123)              # 固定随机种子,防止运行时出现bug后再次运行导致imgs_list 里面的图片名称顺序不一致

random.shuffle(imgs_list)     # 打乱

val_scal = 0.2                # 验证集比列
val_number = int(len(imgs_list) * val_scal)
val_files = imgs_list[:val_number]
train_files = imgs_list[val_number:]

print('all_files:', len(imgs_list))
print('train_files:', len(train_files))
print('val_files:', len(val_files))


os.mkdir('train')
for each in tqdm(train_files):
    shutil.move(each, 'train')

os.mkdir('val')
for each in tqdm(val_files):
    shutil.move(each, 'val')

os.chdir('../label_json')

os.mkdir('train')
for each in tqdm(train_files):
    json_file = os.path.splitext(each)[0] + '.json'
    shutil.move(json_file, 'train')

os.mkdir('val')
for each in tqdm(val_files):
    json_file = os.path.splitext(each)[0] + '.json'
    shutil.move(json_file, 'val')

print('划分完成')




结果:

适应代码把json标签转yolo的txt格式

import os
import json
import numpy as np
import shutil

"""使用: 1.修改类别 classes     你是几个类别就添加,比如你是类别cat,dog 则修改成classes = {'cat':0, 'dog':1} 
         2.修改 Dataset_root 成自己路径
         3.修改os.chdir('json_label/train') 与 os.chdir('json_label/val ') ---> 标签文件夹下的train与val文件夹路径                        """

# 图片与标签json文件的路径(Dataset_root下是图片文件夹与json标签文件夹)
Dataset_root = 'D:\Myself_project\YOLOV8pose\data_me\Goal_Detect_data\Set_Square'


classes = {
    'sjb_rect':0,
}


os.chdir(Dataset_root)

os.mkdir('labels')
os.mkdir('labels/train')
os.mkdir('labels/val')


def process_single_json(labelme_path, save_folder='../../labels/train'):
    # 载入 labelme格式的 json 标注文件
    with open(labelme_path, 'r', encoding='utf-8') as f:
        labelme = json.load(f)

    img_width = labelme['imageWidth']  # 图像宽度
    img_height = labelme['imageHeight']  # 图像高度

    # 生成 YOLO 格式的 txt 文件
    suffix = labelme_path.split('.')[-2]
    yolo_txt_path = suffix + '.txt'

    with open(yolo_txt_path, 'w', encoding='utf-8') as f:
        for each_ann in labelme['shapes']:  # 遍历每个框

            if each_ann['shape_type'] == 'rectangle':  # 筛选出框

                # 获取类别 ID
                bbox_class_id = classes[each_ann['label']]

                # 左上角和右下角的 XY 像素坐标
                bbox_top_left_x = int(min(each_ann['points'][0][0], each_ann['points'][1][0]))
                bbox_bottom_right_x = int(max(each_ann['points'][0][0], each_ann['points'][1][0]))
                bbox_top_left_y = int(min(each_ann['points'][0][1], each_ann['points'][1][1]))
                bbox_bottom_right_y = int(max(each_ann['points'][0][1], each_ann['points'][1][1]))

                # 框中心点的 XY 像素坐标
                bbox_center_x = int((bbox_top_left_x + bbox_bottom_right_x) / 2)
                bbox_center_y = int((bbox_top_left_y + bbox_bottom_right_y) / 2)

                # 框宽度
                bbox_width = bbox_bottom_right_x - bbox_top_left_x

                # 框高度
                bbox_height = bbox_bottom_right_y - bbox_top_left_y

                # 框中心点归一化坐标
                bbox_center_x_norm = bbox_center_x / img_width
                bbox_center_y_norm = bbox_center_y / img_height

                # 框归一化宽度
                bbox_width_norm = bbox_width / img_width
                # 框归一化高度
                bbox_height_norm = bbox_height / img_height

                # 生成 YOLO 格式的一行标注,指定保留小数点后几位
                bbox_yolo_str = '{} {:.4f} {:.4f} {:.4f} {:.4f}'.format(bbox_class_id, bbox_center_x_norm,
                                                                        bbox_center_y_norm, bbox_width_norm,
                                                                        bbox_height_norm)
                # 写入 txt 文件中
                f.write(bbox_yolo_str + '\n')


    shutil.move(yolo_txt_path, save_folder)
    print('{} --> {} 转换完成'.format(labelme_path, yolo_txt_path))


os.chdir('json_label/train')                      # 标签文件夹下的train文件夹路径
save_folder = '../../labels/train'
for labelme_path in os.listdir():
    process_single_json(labelme_path, save_folder=save_folder)
print('YOLO格式的txt标注文件已保存至 ', save_folder)

os.chdir(Dataset_root)

os.chdir('json_label/val')                         # 标签文件夹下的val文件夹路径
save_folder = '../../labels/val'
for labelme_path in os.listdir():
    process_single_json(labelme_path, save_folder=save_folder)
print('YOLO格式的txt标注文件已保存至 ', save_folder)

结果:

此时数据已经全部处理好

二、环境配置与训练

假设conda已经安装,环境配置已完成

(一)、环境配置

  cmd打开终端创建虚拟环境:

conda create -n yolo8 python==3.8

       激活虚拟环境:

conda  activate yolo8

       安装匹配cuda的torch(我这里是cuda11.6)

     安装pytorch

pip install torch==1.12.1+cu116 torchvision==0.13.1+cu116 torchaudio==0.12.1 --extra-index-url https://download.pytorch.org/whl/cu116

进入github仓库

使用命令克隆项目 或者直接 DownloadZip

git clone https://github.com/ultralytics/ultralytics.git

在项目文件夹下创建一个yaml配置文件,内容如下

在终端安装 各种包:

pip install numpy opencv-python pillow pandas matplotlib seaborn tqdm wandb seedir emoji -i https://pypi.tuna.tsinghua.edu.cn/simple

训练:命令或者python

命令训练:


yolo detect train data=yolov8n.yaml model=yolov8n.pt epochs=8 imgsz=640 batch=8 workers=2 device=0  

python训练:

from ultralytics import YOLO

# 加载模型
model = YOLO('yolov8n.pt')                            # 加载预训练权重开始训练
# model = YOLO('yolov8n.yaml')                        # 从 YAML 构建一个新模型开始训练
# model = YOLO('yolov8n.yaml').load('yolov8n.pt')     # 从YAML构建新模型并转移权重开始训练

if __name__ == '__main__':
    # 训练模型   batch默认16     workers默认最大一般是8     pretrained默认True(如果不想加载预训练权重就设置False)
    # (如果出现:OSError: [WinError 1455] 页面文件太小,无法完成操作)降低workers的值
    results = model.train(data='triangle_goal_detect.yaml', epochs=10, imgsz=640, batch=8, device=0, workers=0)

    # metrics = model.val()

训练完成后用python  接口侦测或者命令侦测;

命令侦测:

yolo task=detect mode=predict model=runs\detect\train11\weights\last.pt source=3.jpg device=0 save=True

python侦测:


from IPython import display
import ultralytics
from ultralytics import YOLO, settings
from os import path

def predict():
    model = YOLO(r"D:\Myself_project\yolov8_pose_pre_whight\ultralytics\runs\detect\train\weights\last.pt")
    image_file1 = r"bus.jpg"
    image_file2 = r"2.jpg"
    image_file3 = r"3.jpg"
    # 预测一张图片:source=[image_file1]          预测多张图片:source=[image_file1, image_file2]
    results_list = model.predict(source=[image_file3], show=False, save=True, save_conf=True, conf=0.5,
                                 save_txt=False)
    for results in results_list:
        boxes = results.boxes
        print(boxes.xyxy)                     # 所有框在原图上的左上角与右下角坐标
        print()
        for box in boxes.xyxy:
            print(box)                        # 每个框在原图上的左上角与右下角坐标

if __name__ == '__main__':
    predict()

欧克  全部完成

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值