This script reads PascalVOC xml files, and crops the class instances into seperate image files.
Note: This script relies on ImageMagick for the crop (convert) functionality. It comes pre-installed on most recent versions of Ubuntu.
Disclaimer: This code is a modified version of Dat Tran's xml_to_csv.py
Let's say we have this image in our train folder:
Upon running the script, our train folder now looks like this:
And the class folders (head, leg) contain the following:
import os
import glob
import subprocess
import xml.etree.ElementTree as ET
classes_dict = {}
def crop_classes(path):
xml_list = []
for xml_file in glob.glob(path + '/*.xml'):
tree = ET.parse(xml_file)
root = tree.getroot()
for member in root.findall('object'):
value = (root.find('filename').text,
member[0].text,
int(member[4][0].text),
int(member[4][1].text),
int(member[4][2].text),
int(member[4][3].text)
)
class_name = member[0].text
save_folder = path + "/" + class_name
if not os.path.isdir(save_folder):
os.makedirs(save_folder)
if not class_name in classes_dict.keys():
classes_dict[class_name] = 1;
#http://www.imagemagick.org/Usage/crop/
#convert -crop {x2 - x1}x{y2 - y1}+{x1}+{y1} {folder_name}/{image_name} {folder_name}/{class_name}/{class_name}-{count}-{image_name}
call = ['convert', '-crop', str(value[4] - value[2]) + 'x' + str(value[5] - value[3]) + "+" + str(value[2]) + "+" + str(value[3]), path + "/" + value[0], save_folder + "/" + value[1] + "-" + str(classes_dict[class_name]) + "-" + value[0]]
subprocess.call(call)
classes_dict[class_name] += 1
def main():
for folder_name in ['train', 'val']:
image_path = os.path.join(os.getcwd(), folder_name)
crop_classes(image_path)
print('Successfully cropped classes in the ' + folder_name + ' folder.')
main()
I got error "wrong parameter", folders has been created but empty.
Here is output: