123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- # Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
- #
- # Licensed under the Apache License, Version 2.0 (the "License");
- # you may not use this file except in compliance with the License.
- # You may obtain a copy of the License at
- #
- # http://www.apache.org/licenses/LICENSE-2.0
- #
- # Unless required by applicable law or agreed to in writing, software
- # distributed under the License is distributed on an "AS IS" BASIS,
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- # See the License for the specific language governing permissions and
- # limitations under the License.
- import sys
- import os.path as osp
- import json
- import glob
- import cv2
- import argparse
- # add python path of PadleDetection to sys.path
- parent_path = osp.abspath(osp.join(__file__, *(['..'] * 3)))
- if parent_path not in sys.path:
- sys.path.append(parent_path)
- from ppdet.modeling.bbox_utils import poly2rbox
- from ppdet.utils.logger import setup_logger
- logger = setup_logger(__name__)
- class_name_15 = [
- 'plane', 'baseball-diamond', 'bridge', 'ground-track-field',
- 'small-vehicle', 'large-vehicle', 'ship', 'tennis-court',
- 'basketball-court', 'storage-tank', 'soccer-ball-field', 'roundabout',
- 'harbor', 'swimming-pool', 'helicopter'
- ]
- class_name_16 = [
- 'plane', 'baseball-diamond', 'bridge', 'ground-track-field',
- 'small-vehicle', 'large-vehicle', 'ship', 'tennis-court',
- 'basketball-court', 'storage-tank', 'soccer-ball-field', 'roundabout',
- 'harbor', 'swimming-pool', 'helicopter', 'container-crane'
- ]
- def dota_2_coco(image_dir,
- txt_dir,
- json_path='dota_coco.json',
- is_obb=True,
- dota_version='v1.0'):
- """
- image_dir: image dir
- txt_dir: txt label dir
- json_path: json save path
- is_obb: is obb or not
- dota_version: dota_version v1.0 or v1.5 or v2.0
- """
- img_lists = glob.glob("{}/*.png".format(image_dir))
- data_dict = {}
- data_dict['images'] = []
- data_dict['categories'] = []
- data_dict['annotations'] = []
- inst_count = 0
- # categories
- class_name2id = {}
- if dota_version == 'v1.0':
- for class_id, class_name in enumerate(class_name_15):
- class_name2id[class_name] = class_id + 1
- single_cat = {
- 'id': class_id + 1,
- 'name': class_name,
- 'supercategory': class_name
- }
- data_dict['categories'].append(single_cat)
- for image_id, img_path in enumerate(img_lists):
- single_image = {}
- basename = osp.basename(img_path)
- single_image['file_name'] = basename
- single_image['id'] = image_id
- img = cv2.imread(img_path)
- height, width, _ = img.shape
- single_image['width'] = width
- single_image['height'] = height
- # add image
- data_dict['images'].append(single_image)
- # annotations
- anno_txt_path = osp.join(txt_dir, osp.splitext(basename)[0] + '.txt')
- if not osp.exists(anno_txt_path):
- logger.warning('path of {} not exists'.format(anno_txt_path))
- for line in open(anno_txt_path):
- line = line.strip()
- # skip
- if line.find('imagesource') >= 0 or line.find('gsd') >= 0:
- continue
- # x1,y1,x2,y2,x3,y3,x4,y4 class_name, is_different
- single_obj_anno = line.split(' ')
- assert len(single_obj_anno) == 10
- single_obj_poly = [float(e) for e in single_obj_anno[0:8]]
- single_obj_classname = single_obj_anno[8]
- single_obj_different = int(single_obj_anno[9])
- single_obj = {}
- single_obj['category_id'] = class_name2id[single_obj_classname]
- single_obj['segmentation'] = []
- single_obj['segmentation'].append(single_obj_poly)
- single_obj['iscrowd'] = 0
- # rbox or bbox
- if is_obb:
- polys = [single_obj_poly]
- rboxs = poly2rbox(polys)
- rbox = rboxs[0].tolist()
- single_obj['bbox'] = rbox
- single_obj['area'] = rbox[2] * rbox[3]
- else:
- xmin, ymin, xmax, ymax = min(single_obj_poly[0::2]), min(single_obj_poly[1::2]), \
- max(single_obj_poly[0::2]), max(single_obj_poly[1::2])
- width, height = xmax - xmin, ymax - ymin
- single_obj['bbox'] = xmin, ymin, width, height
- single_obj['area'] = width * height
- single_obj['image_id'] = image_id
- data_dict['annotations'].append(single_obj)
- single_obj['id'] = inst_count
- inst_count = inst_count + 1
- # add annotation
- data_dict['annotations'].append(single_obj)
- with open(json_path, 'w') as f:
- json.dump(data_dict, f)
- if __name__ == '__main__':
- parser = argparse.ArgumentParser(description='dota anno to coco')
- parser.add_argument('--images_dir', help='path_to_images')
- parser.add_argument('--label_dir', help='path_to_labelTxt', type=str)
- parser.add_argument(
- '--json_path',
- help='save json path',
- type=str,
- default='dota_coco.json')
- parser.add_argument(
- '--is_obb', help='is_obb or not', type=bool, default=True)
- parser.add_argument(
- '--dota_version',
- help='dota_version, v1.0 or v1.5 or v2.0',
- type=str,
- default='v1.0')
- args = parser.parse_args()
- # process
- dota_2_coco(args.images_dir, args.label_dir, args.json_path, args.is_obb,
- args.dota_version)
- print('done!')
|