Created
July 21, 2020 19:59
-
-
Save MinaGabriel/68f20c1fd386cb450aceefb404e148ae to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #! /usr/bin/env python | |
| # coding=utf-8 | |
| # ================================================================ | |
| # Copyright (C) 2020 Mina Gabriel All rights reserved. | |
| # | |
| # Editor : PyCharm | |
| # File name : preprocessing.py | |
| # Author : Mina Gabriel | |
| # Created date: 5/23/20 06:55 | |
| # Description : | |
| # | |
| # ================================================================ | |
| import os | |
| from datetime import datetime | |
| from shutil import copy | |
| import xml.etree.ElementTree as ET | |
| from absl import app, flags, logging | |
| FLAGS = flags.FLAGS | |
| flags.DEFINE_string('images', None, 'train images folder') | |
| flags.DEFINE_string('annotation', None, 'train annotation folder') | |
| flags.DEFINE_bool('rebuild', True, 'true if not all images has equivalent annotation files') | |
| flags.DEFINE_bool('VOCtoYOLO', False, 'add a new directory with Yolo annotation from VOC') | |
| flags.DEFINE_string('classes', None, 'classes file location, .names file in root directory') | |
| flags.DEFINE_bool('new_name', True, 'Change images and annotation file name') | |
| flags.mark_flag_as_required('images') # path to train images……… | |
| flags.mark_flag_as_required('annotation') # path to train annotation | |
| def convert(size, box): | |
| dw = 1. / (size[0]) | |
| dh = 1. / (size[1]) | |
| x = (box[0] + box[1]) / 2.0 - 1 | |
| y = (box[2] + box[3]) / 2.0 - 1 | |
| w = box[1] - box[0] | |
| h = box[3] - box[2] | |
| x = x * dw | |
| w = w * dw | |
| y = y * dh | |
| h = h * dh | |
| return (x, y, w, h) | |
| def main(argv): | |
| images = FLAGS.images | |
| annotation = FLAGS.annotation | |
| rebuild = FLAGS.rebuild | |
| VOCtoYOLO = FLAGS.VOCtoYOLO | |
| # create new directory for validation anyway | |
| now = datetime.now() | |
| # create two new folders | |
| new_dir = 'images-' + now.strftime('%m-%d-%Y-%H-%M-%S') | |
| os.makedirs(new_dir) | |
| classes = [] | |
| if FLAGS.classes is not None: | |
| # copy the classes file it self to the new directory | |
| copy(FLAGS.classes, | |
| new_dir) | |
| # create the classes list | |
| with open(FLAGS.classes) as f: | |
| classes = [my_class.strip() for my_class in f] | |
| if rebuild: | |
| new_dir_images = new_dir + '/images' | |
| new_dir_annotation = new_dir + '/annotation' | |
| yolo_dir = new_dir + '/YOLO_annotation' | |
| # create two folders in the new images: images and annotation | |
| os.makedirs(new_dir_images) | |
| os.makedirs(new_dir_annotation) | |
| if VOCtoYOLO: | |
| os.makedirs(yolo_dir) | |
| counter = 0 | |
| if os.path.exists(annotation): | |
| # count the number of annotation files | |
| annotation_count = len([file for file in os.listdir(annotation)]) | |
| train_count = annotation_count - (annotation_count // 3) | |
| # create train and validation files | |
| train = open(os.path.join(new_dir, 'train.txt'), 'w') | |
| validation = open(os.path.join(new_dir, 'validation.txt'), 'w') | |
| for annotation_file_name in os.listdir(annotation): | |
| annotation_file = os.path.splitext(annotation_file_name)[0] | |
| image_file_name = annotation_file + '.jpg' | |
| # if image exists move both annotation and images to new directory | |
| if os.path.exists(os.path.join(images, image_file_name)): | |
| # copy annotation | |
| copy(os.path.join(annotation, annotation_file_name), | |
| os.path.join(new_dir_annotation, annotation_file_name)) | |
| copy(os.path.join(images, image_file_name), | |
| os.path.join(new_dir_images, image_file_name)) | |
| #print('copying ' + annotation_file_name + ' & ' + image_file_name + ' >>> ' + new_dir) | |
| print(annotation_file + " " + "-1") | |
| counter += 1 | |
| if counter < train_count: | |
| train.write('data/custom/images/' + image_file_name + '\n') | |
| else: | |
| validation.write('data/custom/images/' + image_file_name + '\n') | |
| # if convert VOC to YOLO | |
| if VOCtoYOLO and classes: | |
| # create the new Yolo file | |
| yolo_file = open(os.path.join(yolo_dir, annotation_file) + '.txt', 'w') | |
| tree = ET.parse(os.path.join(annotation, annotation_file_name)) | |
| root = tree.getroot() | |
| size = root.find('size') | |
| w = int(size.find('width').text) | |
| h = int(size.find('height').text) | |
| for obj in root.iter('object'): | |
| cls = obj.find('name').text | |
| 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)) | |
| bb = convert((w, h), b) | |
| yolo_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n') | |
| logging.info('Copied ' + str(counter) + ' Images and Annotation') | |
| if __name__ == '__main__': | |
| app.run(main) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment