https://github.com/yu-ken0207/PascalVOCtoYolo
要將Pascal VOC格式的標註轉換為YOLO格式,您可以按照以下步驟進行:
xmin
、ymin
、xmax
、ymax
。<class_id> <x_center> <y_center> <width> <height>
其中,x_center、y_center、width、height都是相對於圖像寬度和高度的正規化的值,範圍在0到1之間。
對於每個標註對象,執行以下步驟:
獲取圖像尺寸(寬度和高度):
提取邊界框坐標:
計算邊界框的寬度和高度:
bbox_width = xmax - xmin
bbox_height = ymax - ymin
計算邊界框中心點坐標:
x_center = xmin + (bbox_width / 2)
y_center = ymin + (bbox_height / 2)
正歸化座標:
x_center_norm = x_center / image_width
y_center_norm = y_center / image_height
bbox_width_norm = bbox_width / image_width
bbox_height_norm = bbox_height / image_height
獲取類別ID:
使用此資料集為例
Monkey, Cat and Dog detection
https://www.kaggle.com/datasets/tarunbisht11/yolo-animal-detection-small/data
import os
import xml.etree.ElementTree as ET
def convert_bbox(size, box):
dw = 1. / size[0]
dh = 1. / size[1]
x = (box[0] + box[2]) / 2.0 - 1
y = (box[1] + box[3]) / 2.0 - 1
w = box[2] - box[0]
h = box[3] - box[1]
x = x * dw
w = w * dw
y = y * dh
h = h * dh
return (x, y, w, h)
xml_folder = 'C:/Users/ken50/OneDrive/桌面/yolo-animal-detection-small/test'
txt_folder = 'C:/Users/ken50/OneDrive/桌面/yolo-animal-detection-small/test'
xml_folder:存放 Pascal VOC 格式標註文件的資料夾路徑。
txt_folder:存放轉換為 YOLO 格式後的標註文件的資料夾路徑。
if not os.path.exists(txt_folder):
os.makedirs(txt_folder)
檢查 txt_folder 是否存在。如果不存在,則建立這個資料夾,確保轉換後的 TXT 標註可以被儲存。
classes = ["cat", "monkey", "dog"]
定義類別清單,這些類別名稱必須與 YAML 文件中的類別名稱一致,並且順序也要保持一致。
for file in os.listdir(xml_folder):
if file.endswith(".xml"):
tree = ET.parse(os.path.join(xml_folder, file))
root = tree.getroot()
os.listdir(xml_folder):列出 xml_folder 中所有的文件。
if file.endswith(".xml"):只處理副檔名為 .xml 的文件。
ET.parse():解析 XML 文件並生成樹狀結構。
root:XML 樹的根節點,這裡用來尋找圖像的大小和標註的物件。
size = root.find('size')
w = int(size.find('width').text)
h = int(size.find('height').text)
透過 XML 文件中的 標籤,取得圖像的 width(寬度)和 height(高度),這些數值會用於轉換邊界框的尺寸。
txt_file = os.path.join(txt_folder, file.replace('.xml', '.txt'))
with open(txt_file, 'w') as out_file:
為每個 XML 文件創建一個相應的 TXT 文件,並將其命名為與原來的 XML 文件相同,但副檔名為 .txt。
使用 open() 函數以寫入模式打開該文件。
for obj in root.iter('object'):
cls = obj.find('name').text
if cls not in classes:
continue
cls_id = classes.index(cls)
xmlbox = obj.find('bndbox')
b = (float(xmlbox.find('xmin').text), float(xmlbox.find('ymin').text),
float(xmlbox.find('xmax').text), float(xmlbox.find('ymax').text))
bbox = convert_bbox((w, h), b)
out_file.write(f"{cls_id} {' '.join([str(a) for a in bbox])}\n")
遍歷 XML 文件中每個 標籤,這些標籤表示圖像中的物體。
取得物件的類別名稱 cls,並確認該名稱是否在預定義的 classes 清單中,如果不在則跳過。
找到類別對應的 ID (cls_id)。
取得物件的邊界框座標 ,轉換成 YOLO 格式,並寫入到對應的 TXT 文件中。
這段程式碼的主要目的是自動將 Pascal VOC 格式的 XML 文件轉換為 YOLO 格式的 TXT 文件,使用者只需指定資料夾路徑和類別名稱,即可進行大批量的格式轉換。