オリジナルであることは簡単ではありませんので、注目してサポートしてください。
目次
1. VOC フォーマットと YOLO フォーマットについて説明します。
序文
この記事では、VOC 形式を YOLO 形式に変換する方法について説明します。YOLO 形式から VOC 形式への変換については、別の記事を参照してください。
1. VOC フォーマットと YOLO フォーマットについて説明します。
1.VOCフォーマット
VOC データセットの形式は XML 形式であり、例は次のとおりです。
<annotation> <folder>img</folder> <filename>pikaqiu.jpg</filename> <path>E:\cv_code\image_processing\test\img\pikaqiu.jpg</path> <source> <database>不明</database> </source> <size> <width>1062</width> <height>974</height> <奥行き>3 </奥行き> </size > <segmented>0</segmented> <object> <name>pikaqiu</name> <pose>Unspecified</pose> <truncated>0</truncated> <difficult>0</difficult> <bndbox> <xmin> 83</xmin> <ymin>74</ymin> <xmax>987</xmax> <xmax>987</xmax> <xmax>987</xmax> <ymax>920</ymax> </bndbox></bndbox></bndbox> </object> </annotation>
使用する必要がある情報には、画像名: <filename>pikaqiu.jpg</filename>、画像の幅、高さ、およびチャネル番号情報: <size> <width>1062</width> <height>974 が含まれます。 </height > <奥行き>3</奥行き> </サイズ>、カテゴリ名: <name>pikaqiu</name>、ボックス情報: <xmin>83</xmin> <ymin>74</ymin> <xmax >987< /xmax> <ymax>920</ymax>。
2.YOLOフォーマット
(class,xCenter,yCenter,w,h)。それぞれ、内部分類、ラベル ボックスの中心座標、ラベル ボックスの相対的な幅と長さを表します。
2. 利用手順
1. ライブラリをインポートする
import xml.etree.ElementTree as ET
import os
2. ファイルアドレスとラベル情報を設定する
# xml文件所在目录
xml_dir = "E:/cv_code/image_processing/aug_datasets/Annotations/"
# Yolo格式文件保存目录
yolo_dir = "E:/cv_code/image_processing/aug_datasets/label/"
# 类别名称和数字标签的映射
class_map = {"pikaqiu": 0}
3. XML ファイル情報を走査して解析する
# 遍历XML文件夹中的所有文件
for xml_file in os.listdir(xml_dir):
if not xml_file.endswith(".xml"):
continue
# 解析XML文件
tree = ET.parse(os.path.join(xml_dir, xml_file))
root = tree.getroot()
4.TXT情報の書き込み
# 获取图像尺寸
size = root.find("size")
width = int(size.find("width").text)
height = int(size.find("height").text)
# 遍历所有目标
for obj in root.iter("object"):
# 获取类别和边界框坐标
cls_name = obj.find("name").text
if cls_name not in class_map:
continue
cls_id = class_map[cls_name]
bbox = obj.find("bndbox")
xmin = float(bbox.find("xmin").text)
ymin = float(bbox.find("ymin").text)
xmax = float(bbox.find("xmax").text)
ymax = float(bbox.find("ymax").text)
# 计算归一化坐标
x = (xmin + xmax) / (2 * width)
y = (ymin + ymax) / (2 * height)
w = (xmax - xmin) / width
h = (ymax - ymin) / height
# 将信息写入Yolo格式文件
yolo_file = os.path.splitext(xml_file)[0] + ".txt"
with open(os.path.join(yolo_dir, yolo_file), "a") as f:
f.write(f"{cls_id} {x:.6f} {y:.6f} {w:.6f} {h:.6f}\n")
5.トータルコード
import xml.etree.ElementTree as ET
import os
# xml文件所在目录
xml_dir = "E:/cv_code/image_processing/aug_datasets/Annotations/"
# Yolo格式文件保存目录
yolo_dir = "E:/cv_code/image_processing/aug_datasets/label/"
# 类别名称和数字标签的映射
class_map = {"pikaqiu": 0}
# 遍历XML文件夹中的所有文件
for xml_file in os.listdir(xml_dir):
if not xml_file.endswith(".xml"):
continue
# 解析XML文件
tree = ET.parse(os.path.join(xml_dir, xml_file))
root = tree.getroot()
# 获取图像尺寸
size = root.find("size")
width = int(size.find("width").text)
height = int(size.find("height").text)
# 遍历所有目标
for obj in root.iter("object"):
# 获取类别和边界框坐标
cls_name = obj.find("name").text
if cls_name not in class_map:
continue
cls_id = class_map[cls_name]
bbox = obj.find("bndbox")
xmin = float(bbox.find("xmin").text)
ymin = float(bbox.find("ymin").text)
xmax = float(bbox.find("xmax").text)
ymax = float(bbox.find("ymax").text)
# 计算归一化坐标
x = (xmin + xmax) / (2 * width)
y = (ymin + ymax) / (2 * height)
w = (xmax - xmin) / width
h = (ymax - ymin) / height
# 将信息写入Yolo格式文件
yolo_file = os.path.splitext(xml_file)[0] + ".txt"
with open(os.path.join(yolo_dir, yolo_file), "a") as f:
f.write(f"{cls_id} {x:.6f} {y:.6f} {w:.6f} {h:.6f}\n")