ssd kerasの教師データをyolo用に変換
世の中の流れと逆行していますが,諸般の事情により必要となったので,スクリプトを書きました.
まずは,Pascal VOC形式のxmlファイルをPythonで読むを元に,xmlファイルのデータを取ってきて,変換して出力してみました.
# coding:utf-8
import xml.etree.ElementTree as ET
import sys
# FILE = '00001.xml'
args = sys.argv
for FILE in args:
# print FILE
if FILE != args[0]:
file = open(FILE)
tree = ET.parse(file)
root = tree.getroot()
all_list = []
img_file = root.find('filename').text # 画像ファイル名を取得
for obj in root.iter('object'):
cls = obj.find('name').text
xmlbox = obj.find('bndbox')
b = [int(xmlbox.find('xmin').text), int(xmlbox.find('ymin').text), int(xmlbox.find('xmax').text), int(xmlbox.find('ymax').text)]
all_list.append([img_file] + b + [cls])
# print all_list
# [['00102.jpg', 148, 369, 494, 957, 'WALL'], ['00102.jpg', 470, 16, 1176, 849, 'MPS']]
if cls == 'MPS':
print '0',
else:
print '1',
centerx = (int(xmlbox.find('xmin').text) + int(xmlbox.find('xmax').text)) / 2
centery = (int(xmlbox.find('ymin').text) + int(xmlbox.find('ymax').text)) / 2
widthx = (int(xmlbox.find('xmax').text) - int(xmlbox.find('xmin').text))
widthy = (int(xmlbox.find('ymax').text) - int(xmlbox.find('ymin').text))
print centerx, centery, widthx, widthy
複数ファイルに対応させておきながら,この出力結果を扱う方法が面倒くさかったので,その部分はbashで書いちゃいました.
#!/bin/bash
for FILE in `ls *.xml`; do
TXT="`echo $FILE|sed 's/\.[^\.]*$//'`.txt"
echo $TXT
python convert.py $FILE > $TXT
done
これで,xml ファイルからdarknet のtxt ファイルに一括変換できました.
※2019/11/15追加
学生からの指摘で,変換後は,画像のサイズで正規化する必要があるとのことでした.
つまり,int(サイズ) /2のところが,1920X1080の場合は,
centerx = (float(xmlbox.find('xmin').text) + float(xmlbox.find('xmax').text)) / 2 / 1920
centery = (float(xmlbox.find('ymin').text) + float(xmlbox.find('ymax').text)) / 2 /1080
widthx = (float(xmlbox.find('xmax').text) - float(xmlbox.find('xmin').text)) / 1980
widthy = (float(xmlbox.find('ymax').text) - float(xmlbox.find('ymin').text)) / 1080
となるとのことでした.
コメントを残す