yolov5訓練自定義數據集


yolov5訓練自定義數據

step1:參考文獻及代碼

  1. 博客 https://blog.csdn.net/weixin_41868104/article/details/107339535
  2. github代碼 https://github.com/DataXujing/YOLO-v5
  3. 官方代碼 https://github.com/ultralytics/yolov5
  4. 官方教程 https://github.com/ultralytics/yolov5/wiki/Train-Custom-Data

step2:准備數據集

  • --yolov5需要的數據集格式為txt格式的(即一個圖片對應一個txt文件)
  • 參考文獻1利用其將xml格式的代碼轉換成txt格式的代碼

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

  • 更新:2021/2/6 0:42
  • 找到了跟好的轉換數據集的github庫---->可應用與yolov3和yolov5的訓練
  • github地址:https://github.com/pprp/voc2007_for_yolo_torch
  • 如果自己的圖片格式不是.jpg需要修改tools/make_for_yolov3_torch.py里面的代碼

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

訓練

  • 利用參考文獻而將參考文獻1中的labels中的txt數據集和images中的圖片放入到參考文獻二中

附錄:

用於抽取訓練集和測試集

  1. 抽取圖片:抽取.py
import os
import random
import shutil
 
# source_file:源路徑, target_ir:目標路徑
def cover_files(source_dir, target_ir):
    for file in os.listdir(source_dir):
        source_file = os.path.join(source_dir, file)
 
        if os.path.isfile(source_file):
            shutil.copy(source_file, target_ir)
 
def ensure_dir_exists(dir_name):
    """Makes sure the folder exists on disk.
  Args:
    dir_name: Path string to the folder we want to create.
  """
    if not os.path.exists(dir_name):
        os.makedirs(dir_name)
 
 
def moveFile(file_dir, save_dir):
    ensure_dir_exists(save_dir)
    path_dir = os.listdir(file_dir)  
    filenumber = len(path_dir)
    rate = 0.1  # 自定義抽取圖片的比例,比方說100張抽10張,那就是0.1
    picknumber = int(filenumber * rate)  # 按照rate比例從文件夾中取一定數量圖片
    sample = random.sample(path_dir, picknumber)  # 隨機選取picknumber數量的樣本圖片
    # print (sample)
    for name in sample:
        shutil.move(file_dir + name, save_dir + name)
 
#切記win10路徑D:你的路徑\\,最后一定要有\\才能進入目標文件  
if __name__ == '__main__':
    file_dir = 'G:\\ECANet-master\\train\\0\\'  # 源圖片文件夾路徑
    save_dir = 'G:\\ECANet-master\\train\\00\\'  # 移動到目標文件夾路徑
    moveFile(file_dir, save_dir)

json2xml:(json格式轉換成xml格式)

  • 將下面三個文件放入到json_to_xml文件夾下
  1. create_xml_anno.py
# -*- coding: utf-8 -*-
from xml.dom.minidom import Document
 
 
class CreateAnno:
    def __init__(self,):
        self.doc = Document()  # 創建DOM文檔對象
        self.anno = self.doc.createElement('annotation')  # 創建根元素
        self.doc.appendChild(self.anno)
 
        self.add_folder()
        self.add_path()
        self.add_source()
        self.add_segmented()
 
        # self.add_filename()
        # self.add_pic_size(width_text_str=str(width), height_text_str=str(height), depth_text_str=str(depth))
 
    def add_folder(self, floder_text_str='JPEGImages'):
        floder = self.doc.createElement('floder')  ##建立自己的開頭
        floder_text = self.doc.createTextNode(floder_text_str)  ##建立自己的文本信息
        floder.appendChild(floder_text)  ##自己的內容
        self.anno.appendChild(floder)
 
    def add_filename(self, filename_text_str='00000.jpg'):
        filename = self.doc.createElement('filename')
        filename_text = self.doc.createTextNode(filename_text_str)
        filename.appendChild(filename_text)
        self.anno.appendChild(filename)
 
    def add_path(self, path_text_str="None"):
        path = self.doc.createElement('path')
        path_text = self.doc.createTextNode(path_text_str)
        path.appendChild(path_text)
        self.anno.appendChild(path)
 
    def add_source(self, database_text_str="Unknow"):
        source = self.doc.createElement('source')
        database = self.doc.createElement('database')
        database_text = self.doc.createTextNode(database_text_str)  # 元素內容寫入
        database.appendChild(database_text)
        source.appendChild(database)
        self.anno.appendChild(source)
 
    def add_pic_size(self, width_text_str="0", height_text_str="0", depth_text_str="3"):
        size = self.doc.createElement('size')
        width = self.doc.createElement('width')
        width_text = self.doc.createTextNode(width_text_str)  # 元素內容寫入
        width.appendChild(width_text)
        size.appendChild(width)
 
        height = self.doc.createElement('height')
        height_text = self.doc.createTextNode(height_text_str)
        height.appendChild(height_text)
        size.appendChild(height)
 
        depth = self.doc.createElement('depth')
        depth_text = self.doc.createTextNode(depth_text_str)
        depth.appendChild(depth_text)
        size.appendChild(depth)
 
        self.anno.appendChild(size)
 
    def add_segmented(self, segmented_text_str="0"):
        segmented = self.doc.createElement('segmented')
        segmented_text = self.doc.createTextNode(segmented_text_str)
        segmented.appendChild(segmented_text)
        self.anno.appendChild(segmented)
 
    def add_object(self,
                   name_text_str="None",
                   xmin_text_str="0",
                   ymin_text_str="0",
                   xmax_text_str="0",
                   ymax_text_str="0",
                   pose_text_str="Unspecified",
                   truncated_text_str="0",
                   difficult_text_str="0"):
        object = self.doc.createElement('object')
        name = self.doc.createElement('name')
        name_text = self.doc.createTextNode(name_text_str)
        name.appendChild(name_text)
        object.appendChild(name)
 
        pose = self.doc.createElement('pose')
        pose_text = self.doc.createTextNode(pose_text_str)
        pose.appendChild(pose_text)
        object.appendChild(pose)
 
        truncated = self.doc.createElement('truncated')
        truncated_text = self.doc.createTextNode(truncated_text_str)
        truncated.appendChild(truncated_text)
        object.appendChild(truncated)
 
        difficult = self.doc.createElement('difficult')
        difficult_text = self.doc.createTextNode(difficult_text_str)
        difficult.appendChild(difficult_text)
        object.appendChild(difficult)
 
        bndbox = self.doc.createElement('bndbox')
        xmin = self.doc.createElement('xmin')
        xmin_text = self.doc.createTextNode(xmin_text_str)
        xmin.appendChild(xmin_text)
        bndbox.appendChild(xmin)
 
        ymin = self.doc.createElement('ymin')
        ymin_text = self.doc.createTextNode(ymin_text_str)
        ymin.appendChild(ymin_text)
        bndbox.appendChild(ymin)
 
        xmax = self.doc.createElement('xmax')
        xmax_text = self.doc.createTextNode(xmax_text_str)
        xmax.appendChild(xmax_text)
        bndbox.appendChild(xmax)
 
        ymax = self.doc.createElement('ymax')
        ymax_text = self.doc.createTextNode(ymax_text_str)
        ymax.appendChild(ymax_text)
        bndbox.appendChild(ymax)
        object.appendChild(bndbox)
 
        self.anno.appendChild(object)
 
    def get_anno(self):
        return self.anno
 
    def get_doc(self):
        return self.doc
 
    def save_doc(self, save_path):
        with open(save_path, "w") as f:
            self.doc.writexml(f, indent='\t', newl='\n', addindent='\t', encoding='utf-8')
  1. main.py
import os
from tqdm import tqdm
 
from read_json import ReadAnno
from create_xml_anno import CreateAnno
 
 
def json_transform_xml(json_path, xml_path, process_mode="polygon"):
    json_path = json_path
    json_anno = ReadAnno(json_path, process_mode=process_mode)
    width, height = json_anno.get_width_height()
    filename = json_anno.get_filename()
    coordis = json_anno.get_coordis()
 
    xml_anno = CreateAnno()
    xml_anno.add_filename(filename)
    xml_anno.add_pic_size(width_text_str=str(width), height_text_str=str(height), depth_text_str=str(3))
    for xmin,ymin,xmax,ymax,label in coordis:
        xml_anno.add_object(name_text_str=str(label),
                            xmin_text_str=str(int(xmin)),
                            ymin_text_str=str(int(ymin)),
                            xmax_text_str=str(int(xmax)),
                            ymax_text_str=str(int(ymax)))
 
    xml_anno.save_doc(xml_path)
 
if __name__ == "__main__":
    root_json_dir = r"/home/aibc/ouyang/temp_dataset/jjson"
    root_save_xml_dir = r"/home/aibc/ouyang/temp_dataset/xml"
    for json_filename in tqdm(os.listdir(root_json_dir)):
        json_path = os.path.join(root_json_dir, json_filename)
        save_xml_path = os.path.join(root_save_xml_dir, json_filename.replace(".json", ".xml"))
        json_transform_xml(json_path, save_xml_path, process_mode="polygon")
  1. read_json.py
# -*- coding: utf-8 -*-
import numpy as np
import json
 
 
class ReadAnno:
    def __init__(self, json_path, process_mode="rectangle"):
        self.json_data = json.load(open(json_path))
        self.filename = self.json_data['imagePath']
        self.width = self.json_data['imageWidth']
        self.height = self.json_data['imageHeight']
 
        self.coordis = []
        assert process_mode in ["rectangle", "polygon"]
        if process_mode == "rectangle":
            self.process_polygon_shapes()
        elif process_mode == "polygon":
            self.process_polygon_shapes()
 
    def process_rectangle_shapes(self):
        for single_shape in self.json_data['shapes']:
            bbox_class = single_shape['label']
            xmin = single_shape['points'][0][0]
            ymin = single_shape['points'][0][1]
            xmax = single_shape['points'][1][0]
            ymax = single_shape['points'][1][1]
            self.coordis.append([xmin,ymin,xmax,ymax,bbox_class])
 
    def process_polygon_shapes(self):
        for single_shape in self.json_data['shapes']:
            bbox_class = single_shape['label']
            temp_points = []
            for couple_point in single_shape['points']:
                x = float(couple_point[0])
                y = float(couple_point[1])
                temp_points.append([x,y])
            temp_points = np.array(temp_points)
            xmin, ymin = temp_points.min(axis=0)
            xmax, ymax = temp_points.max(axis=0)
            self.coordis.append([xmin,ymin,xmax,ymax,bbox_class])
 
    def get_width_height(self):
        return self.width, self.height
 
    def get_filename(self):
        return self.filename
 
    def get_coordis(self):
        return self.coordis


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM