目錄
1. 下載數據
2. 配置開發環境
3. 預處理數據
- 🍨 本文為🔗365天深度學習訓練營?中的學習記錄博客
- 🍖 原作者:K同學啊
1. 下載數據
百度網盤:百度網盤 請輸入提取碼
壓縮文件中有兩個文件夾,分別是Annotations和ImageSet文件夾,我的理解:
ImageSet:原始圖片
Annotations:針對原始圖片標注了有效信息的文件,比如位置信息等。
2. 配置開發環境
第1天課里已經下載了yolov5的github項目,將該項目作為項目文件,通過各類IDE打開即可。你可能需要安裝依賴包(pip install -r requirement.txt),可能需要配置python解釋器和虛擬環境。
在項目根目錄下本身有一個data文件,里面有很多預置的數據集文件。為了區分,我在根目錄下建立一個mydata的文件夾,然后將下載的數據解壓后的兩個文件夾copy到mydata中。
3. 預處理數據
腳本1:1. 數據集劃分 (split_train_val.py) :將數據分為訓練集、驗證集和測試集
輸出:
ImageSets/Main/train.txt:訓練集文件名列表
ImageSets/Main/val.txt:驗證集文件名列表
ImageSets/Main/test.txt:測試集文件名列表
腳本2:2. 格式轉換 (voc_label.py):將VOC格式(XML格式)轉換為YOLO格式(TXT格式,具體查詢資料)
輸出:
labels/:YOLO格式標注文件夾
train.txt:訓練集圖像路徑列表
val.txt:驗證集圖像路徑列表
split_train_val.py腳本代碼:
# 導入必要的庫
import os
import random
import argparse # 創建一個參數解析器
parser = argparse.ArgumentParser() # 添加命令行參數,用于指定XML文件的路徑,默認為 'Annotations' 文件夾
parser.add_argument('--xml_path', default='Annotations', type=str, help='input xml label path') # 添加命令行參數,用于指定輸出txt標簽文件的路徑,默認為 'ImageSets/Main' 文件夾
parser.add_argument('--txt_path', default='ImageSets/Main', type=str, help='output txt label path') # 解析命令行參數
opt = parser.parse_args() # 定義訓練驗證集和測試集的劃分比例
trainval_percent = 1.0 # 使用全部數據
train_percent = 0.9 # 訓練集占訓練驗證集的90% # 設置XML文件夾的路徑,根據命令行參數指定
xmlfilepath = opt.xml_path # 設置輸出txt標簽文件的路徑,根據命令行參數指定
txtsavepath = opt.txt_path # 獲取XML文件夾中的所有XML文件列表
total_xml = os.listdir(xmlfilepath) # 如果輸出txt標簽文件的文件夾不存在,創建它
if not os.path.exists(txtsavepath): os.makedirs(txtsavepath) # 獲取XML文件的總數
num = len(total_xml) # 創建一個包含所有XML文件索引的列表
list_index = range(num) # 計算訓練驗證集的數量
tv = int(num * trainval_percent) # 計算訓練集的數量
tr = int(tv * train_percent) # 從所有XML文件索引中隨機選擇出訓練驗證集的索引
trainval = random.sample(list_index, tv) # 從訓練驗證集的索引中隨機選擇出訓練集的索引
train = random.sample(trainval, tr) # 打開要寫入的訓練驗證集、測試集、訓練集、驗證集的txt文件
file_trainval = open(txtsavepath + '/trainval.txt', 'w')
file_test = open(txtsavepath + '/test.txt', 'w')
file_train = open(txtsavepath + '/train.txt', 'w')
file_val = open(txtsavepath + '/val.txt', 'w') # 遍歷所有XML文件的索引
for i in list_index: name = total_xml[i][:-4] + '\n' # 獲取XML文件的名稱(去掉后綴.xml),并添加換行符 # 如果該索引在訓練驗證集中 if i in trainval: file_trainval.write(name) # 寫入訓練驗證集txt文件 if i in train: # 如果該索引在訓練集中 file_train.write(name) # 寫入訓練集txt文件 else: file_val.write(name) # 否則寫入驗證集txt文件 else: file_test.write(name) # 否則寫入測試集txt文件 # 關閉所有打開的文件
file_trainval.close()
file_train.close()
file_val.close()
file_test.close()
voc_label.py代碼:
# -*- coding: utf-8 -*- # 導入必要的庫
import xml.etree.ElementTree as ET
import os
from os import getcwd # 定義數據集的名稱
sets = ['train', 'val', 'test'] # 定義類別列表,這里有兩個類別,可以根據需要添加更多類別
classes = ["A", "B"] # 請根據您的數據集修改這些類別名稱 # 獲取當前工作目錄的絕對路徑
abs_path = os.getcwd()
print(abs_path) # 定義一個函數,將邊界框的坐標從絕對值轉換為相對于圖像大小的比例
def convert(size, box): dw = 1. / (size[0]) # 計算圖像寬度的倒數 dh = 1. / (size[1]) # 計算圖像高度的倒數 x = (box[0] + box[1]) / 2.0 - 1 # 計算中心點的x坐標 y = (box[2] + box[3]) / 2.0 - 1 # 計算中心點的y坐標 w = box[1] - box[0] # 計算邊界框的寬度 h = box[3] - box[2] # 計算邊界框的高度 x = x * dw # 縮放x坐標 w = w * dw # 縮放寬度 y = y * dh # 縮放y坐標 h = h * dh # 縮放高度 return x, y, w, h # 定義一個函數,將標注文件從XML格式轉換為YOLO格式
def convert_annotation(image_id): in_file = open('./Annotations/%s.xml' % (image_id), encoding='UTF-8') # 打開XML標注文件 out_file = open('./labels/%s.txt' % (image_id), 'w') # 打開要寫入的YOLO格式標簽文件 tree = ET.parse(in_file) # 解析XML文件 root = tree.getroot() filename = root.find('filename').text # 獲取圖像文件名 filenameFormat = filename.split(".")[1] # 獲取文件格式 size = root.find('size') # 獲取圖像尺寸信息 w = int(size.find('width').text) # 獲取圖像寬度 h = int(size.find('height').text) # 獲取圖像高度 for obj in root.iter('object'): difficult = obj.find('difficult').text # 獲取對象的難度標志 cls = obj.find('name').text # 獲取對象的類別名稱 if cls not in classes or int(difficult) == 1: continue cls_id = classes.index(cls) # 獲取類別的索引 xmlbox = obj.find('bndbox') # 獲取邊界框坐標信息 b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text), float(xmlbox.find('ymax').text)) b1, b2, b3, b4 = b # 標注越界修正 if b2 > w: b2 = w if b4 > h: b4 = h b = (b1, b2, b3, b4) bb = convert((w, h), b) # 調用convert函數,將邊界框坐標轉換為YOLO格式 out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n') # 寫入YOLO格式標簽文件 return filenameFormat # 獲取當前工作目錄
wd = getcwd() # 遍歷每個數據集(train、val、test)
for image_set in sets: # 如果labels目錄不存在,創建它 if not os.path.exists('./labels/'): os.makedirs('./labels/') # 從數據集文件中獲取圖像ID列表 image_ids = open('./ImageSets/Main/%s.txt' % (image_set)).read().strip().split() # 打開要寫入的文件,寫入圖像的文件路徑和格式 list_file = open('./%s.txt' % (image_set), 'w') for image_id in image_ids: filenameFormat = convert_annotation(image_id) list_file.write(abs_path + '/images/%s.%s\n' % (image_id, filenameFormat)) # 注意你的圖片格式,如果是.jpg記得修改 list_file.close()
? ? ? ? ? ? ? ? ? ? ? ??