From febf35fc4409732912e21f3d92e8504859684d3c Mon Sep 17 00:00:00 2001 From: yatenglg <767624851@qq.com> Date: Fri, 28 Apr 2023 22:13:50 +0800 Subject: [PATCH] update --- .idea/misc.xml | 2 +- UpdateLog.md | 8 +- isat.yaml | 2 +- tools/toCOCO.py | 294 +++++++++++++++++++++++++++++++++ tools/toVOC.py | 2 +- tools/tococo.py | 200 ---------------------- ui/COCO_to_ISAT_dialog.py | 109 ++++++++++++ ui/COCO_to_ISAT_dialog.ui | 211 +++++++++++++++++++++++ ui/ISAT_to_COCO_dialog.py | 98 +++++++++++ ui/ISAT_to_COCO_dialog.ui | 185 +++++++++++++++++++++ ui/MainWindow.py | 16 +- ui/MainWindow.ui | 27 ++- widgets/COCO_to_ISAT_dialog.py | 69 ++++++++ widgets/ISAT_to_COCO_dialog.py | 69 ++++++++ widgets/ISAT_to_VOC_dialog.py | 4 +- widgets/converter.py | 86 ---------- widgets/mainwindow.py | 18 +- 17 files changed, 1095 insertions(+), 305 deletions(-) create mode 100644 tools/toCOCO.py delete mode 100644 tools/tococo.py create mode 100644 ui/COCO_to_ISAT_dialog.py create mode 100644 ui/COCO_to_ISAT_dialog.ui create mode 100644 ui/ISAT_to_COCO_dialog.py create mode 100644 ui/ISAT_to_COCO_dialog.ui create mode 100644 widgets/COCO_to_ISAT_dialog.py create mode 100644 widgets/ISAT_to_COCO_dialog.py delete mode 100644 widgets/converter.py diff --git a/.idea/misc.xml b/.idea/misc.xml index 3f589e5..b47cefa 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,4 +1,4 @@ - + \ No newline at end of file diff --git a/UpdateLog.md b/UpdateLog.md index 0881d32..123910e 100644 --- a/UpdateLog.md +++ b/UpdateLog.md @@ -1,4 +1,4 @@ -# 20240424 +# - 添加了对labelme格式json的支持(只支持标注的多边形) @@ -16,6 +16,6 @@ - bug修复 # -- 添加转换voc格式png图片的功能 finish -- 添加转换coco格式json的功能 ing -- 添加转换coco格式json转ISAT格式json的功能 ing \ No newline at end of file +- 添加转换voc格式png图片的功能(单通道png) +- 添加转换coco格式json的功能(ISAT jsons to COCO json) +- 添加转换coco格式json转ISAT格式json的功能(COCO json to ISAT jsons) \ No newline at end of file diff --git a/isat.yaml b/isat.yaml index 9376fac..f5f0b9a 100644 --- a/isat.yaml +++ b/isat.yaml @@ -19,4 +19,4 @@ label: name: cake - color: '#5c3566' name: fence -language: zh +language: en diff --git a/tools/toCOCO.py b/tools/toCOCO.py new file mode 100644 index 0000000..cc2257d --- /dev/null +++ b/tools/toCOCO.py @@ -0,0 +1,294 @@ +# -*- coding: utf-8 -*- +# @Author : LG + +from json import load, dump +import os +from pycocotools import mask as coco_mask +import cv2 +import imgviz +import yaml +import numpy as np + + +class COCOConverter: + def convert_to_coco(self, isat_json_root:str, to_path:str): + coco_anno = {} + # info + coco_anno['info'] = {} + coco_anno['info']['description'] = 'coco from ISAT' + coco_anno['info']['version'] = None + coco_anno['info']['year'] = None + coco_anno['info']['contributor'] = None + coco_anno['info']['date_created'] = None + + # licenses + coco_anno['licenses'] = [] + license1 = {} + license1['url'] = None + license1['id'] = 0 + license1['name'] = None + coco_anno['licenses'].append(license1) + + # images and annotations + coco_anno['images'] = [] + coco_anno['annotations'] = [] + coco_anno['categories'] = [] + + categories_dict = {} + + jsons = [f for f in os.listdir(isat_json_root) if f.endswith('.json')] + for file_index, json in enumerate(jsons): + print('Load ISAT: {}'.format(json)) + try: + with open(os.path.join(isat_json_root, json), 'r') as f: + dataset = load(f) + info = dataset.get('info', {}) + description = info.get('description', '') + if not description.startswith('ISAT'): + # 不是ISAT格式json + continue + + img_name = info.get('name', '') + width = info.get('width', None) + height = info.get('height', None) + depth = info.get('depth', None) + note = info.get('note', '') + objects = dataset.get('objects', []) + + # image + coco_image_info = {} + coco_image_info['license'] = None + coco_image_info['url'] = None + coco_image_info['file_name'] = img_name + coco_image_info['height'] = height + coco_image_info['width'] = width + coco_image_info['date_captured'] = None + coco_image_info['id'] = file_index + coco_anno['images'].append(coco_image_info) + + objects_groups = [obj.get('group', 0) for obj in objects] + objects_groups.sort() + objects_groups = set(objects_groups) + # 同group + for group_index, group in enumerate(objects_groups): + objs_with_group = [obj for obj in objects if obj.get('group', 0) == group] + cats = [obj.get('category', 'unknow') for obj in objs_with_group] + cats = set(cats) + # 同category + for cat in cats: + if cat not in categories_dict: + categories_dict[cat] = len(categories_dict) + category_index = categories_dict.get(cat) + + objs_with_cat = [obj for obj in objs_with_group if obj.get('category', 0) == cat] + crowds = [obj.get('iscrowd', 'unknow') for obj in objs_with_group] + crowds = set(crowds) + # 同iscrowd + for crowd in crowds: + objs_with_crowd = [obj for obj in objs_with_cat if obj.get('iscrowd', 0) == crowd] + # anno + coco_anno_info = {} + coco_anno_info['iscrowd'] = crowd + coco_anno_info['image_id'] = file_index + coco_anno_info['image_name'] = img_name + coco_anno_info['category_id'] = category_index + coco_anno_info['id'] = len(coco_anno['annotations']) + coco_anno_info['segmentation'] = [] + coco_anno_info['area'] = 0. + coco_anno_info['bbox'] = [] + + for obj in objs_with_crowd: + + segmentation = obj.get('segmentation', []) + area = obj.get('area', 0) + bbox = obj.get('bbox', []) + if bbox is None: + segmentation_nd = np.array(segmentation) + bbox = [min(segmentation_nd[:, 0]), min(segmentation_nd[:, 1]), + max(segmentation_nd[:, 0]), max(segmentation_nd[:, 1])] + del segmentation_nd + segmentation = [e for p in segmentation for e in p] + + + + if bbox != []: + if coco_anno_info['bbox'] == []: + coco_anno_info['bbox'] = bbox + else: + bbox_tmp = coco_anno_info['bbox'] + bbox_tmp = [min(bbox_tmp[0], bbox[0]), min(bbox_tmp[1], bbox[1]), + max(bbox_tmp[2], bbox[2]), max(bbox_tmp[3], bbox[3])] + coco_anno_info['bbox'] = bbox_tmp + coco_anno_info['segmentation'].append(segmentation) + if area is not None: + coco_anno_info['area'] += float(area) + + # (xmin, ymin, xmax, ymax) 2 (xmin, ymin, w, h) + bbox_tmp = coco_anno_info['bbox'] + coco_anno_info['bbox'] = [bbox_tmp[0], bbox_tmp[1], + bbox_tmp[2] - bbox_tmp[0], bbox_tmp[3] - bbox_tmp[1]] + + coco_anno['annotations'].append(coco_anno_info) + except Exception as e: + print('Load ISAT: {}, error: {}'.format(json, e)) + + categories_dict = sorted(categories_dict.items(), key=lambda x:x[1]) + coco_anno['categories'] = [{'name': name, 'id': id, 'supercategory': None} for name, id in categories_dict] + + with open(to_path, 'w') as f: + try: + dump(coco_anno, f) + print('Save coco json to {}'.format(to_path)) + except Exception as e: + print('Save {} error :{}'.format(to_path, e)) + + + def convert_from_coco(self, coco_json_path:str, to_root:str, keep_crowd:bool=False): + assert coco_json_path.endswith('.json') + annos = {} + if os.path.exists(coco_json_path): + with open(coco_json_path, 'r') as f: + dataset = load(f) + images = {image.get('id', None):{ + 'file_name': image.get('file_name', ''), + 'height': image.get('height', ''), + 'width': image.get('width', ''), + } for image in dataset.get('images', [])} + annotations = dataset.get('annotations', []) + categories = {categorie.get('id', None): {'name': categorie.get('name', '')} for categorie in dataset.get('categories', [])} + for index, annotation in enumerate(annotations): + + annotation_index = annotation.get('id') + annotation_image_id = annotation.get('image_id') + annotation_category_id = annotation.get('category_id') + + file_name = images[annotation_image_id].get('file_name') + height = images[annotation_image_id].get('height') + width = images[annotation_image_id].get('width') + iscrowd = annotation["iscrowd"] + + if file_name == '000000279278.jpg': + continue + if annotation_image_id not in annos: + annos[annotation_image_id] = {} + + objects = annos[annotation_image_id].get('objects', []) + + if iscrowd == 0: + # polygon + segmentations = annotation.get('segmentation') + for segmentation in segmentations: + xs = segmentation[::2] + ys = segmentation[1::2] + points = [[x, y] for x ,y in zip(xs, ys)] + obj = { + 'category': categories.get(annotation_category_id).get('name'), + 'group': annotation_index, + 'area': None, + 'segmentation': points, + 'layer': 1, + 'bbox': None, + 'iscrowd': iscrowd, + 'note': '' + } + objects.append(obj) + elif iscrowd == 1 and keep_crowd: + segmentations = annotation.get('segmentation', {}) + if isinstance(segmentations, dict) and 'counts' in segmentations: + # RLE + rles = coco_mask.frPyObjects(segmentations, height, width) + masks = coco_mask.decode(rles) + contours, _ = cv2.findContours(masks, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_TC89_KCOS) + for contour in contours: + points = [] + for point in contour: + x, y = point[0] + points.append([float(x), float(y)]) + obj = { + 'category': categories.get(annotation_category_id).get('name'), + 'group': annotation_index, + 'area': None, + 'segmentation': points, + 'layer': 1, + 'bbox': None, + 'iscrowd': iscrowd, + 'note': '' + } + objects.append(obj) + else: + # polygon + for segmentation in segmentations: + xs = segmentation[::2] + ys = segmentation[1::2] + points = [[x, y] for x, y in zip(xs, ys)] + obj = { + 'category': categories.get(annotation_category_id).get('name'), + 'group': annotation_index, + 'area': None, + 'segmentation': points, + 'layer': 1, + 'bbox': None, + 'iscrowd': iscrowd, + 'note': '' + } + objects.append(obj) + else: + pass + annos[annotation_image_id]['objects'] = objects + + + for image_id, values in annos.items(): + image_path = images[image_id].get('file_name') + folder, name = os.path.split(image_path) + height = images[image_id].get('height') + width = images[image_id].get('width') + objects = values.get('objects', []) + + isat_anno = {} + isat_anno['info'] = {} + isat_anno['info']['description'] = 'ISAT' + isat_anno['info']['folder'] = folder + isat_anno['info']['name'] = name + isat_anno['info']['width'] = width + isat_anno['info']['height'] = height + isat_anno['info']['depth'] = None + isat_anno['info']['note'] = '' + isat_anno['objects'] = [] + # coco annotation的id 太大了,这里缩一下,每张图片重新开始计数 + groups_dict = {} + for obj in objects: + group = obj.get('group', 0) + if group not in groups_dict: + groups_dict[group] = len(groups_dict)+1 + for obj in objects: + object = {} + object['category'] = obj.get('category', '') + object['group'] = groups_dict.get(obj.get('group', 0)) + object['segmentation'] = obj.get('segmentation', []) + object['area'] = obj.get('area', None) + object['layer'] = obj.get('layer', None) + object['bbox'] = obj.get('bbox', None) + object['iscrowd'] = obj.get('iscrowd', 0) + object['note'] = obj.get('note', '') + isat_anno['objects'].append(object) + json_name = '.'.join(name.split('.')[:-1]) + '.json' + save_json = os.path.join(to_root, json_name) + with open(save_json, 'w') as f: + try: + dump(isat_anno, f) + print('Converted coco to ISAT: {}'.format(json_name)) + + except Exception as e: + print('Convert coco to ISAT {} ,error: {}'.format(json_name, e)) + + ### 类别文件 + cmap = imgviz.label_colormap() + sorted(categories) + for index, (k, categorie_dict) in enumerate(categories.items()): + r, g, b = cmap[index+1] + categorie_dict['color'] = "#{:02x}{:02x}{:02x}".format(r, g, b) + print(categories) + + s = yaml.dump({'label': list(categories.values())}) + with open(os.path.join(to_root, 'categorys.yaml'), 'w') as f: + f.write(s) diff --git a/tools/toVOC.py b/tools/toVOC.py index e5dd5e3..3baa54e 100644 --- a/tools/toVOC.py +++ b/tools/toVOC.py @@ -8,7 +8,7 @@ import mahotas import imgviz -class ToVOC: +class VOCConverter: def __init__(self, cfg, is_segmentation): self.is_segmentation = is_segmentation diff --git a/tools/tococo.py b/tools/tococo.py deleted file mode 100644 index 99aa07d..0000000 --- a/tools/tococo.py +++ /dev/null @@ -1,200 +0,0 @@ -# -*- coding: utf-8 -*- -# @Author : LG - -from json import load, dump -import os -from pycocotools import mask as coco_mask -import cv2 -import imgviz - - -class COCOConverter: - def __init__(self, ): - pass - # labels = cfg.get('label', []) - # for index, label_dict in enumerate(labels): - # category = label_dict.get('name', 'unknow') - # color = label_dict.get('color', '#000000') - - def convert_to_coco(self, isat_json_root:str, to_path:str): - coco_anno = {} - # info - coco_anno['info'] = {} - coco_anno['info']['description'] = 'coco from ISAT' - coco_anno['info']['version'] = None - coco_anno['info']['year'] = None - coco_anno['info']['contributor'] = None - coco_anno['info']['date_created'] = None - - # licenses - coco_anno['licenses'] = [] - coco_anno['licenses'][0] = {} - coco_anno['licenses'][0]['url'] = None - coco_anno['licenses'][0]['id'] = 0 - coco_anno['licenses'][0]['name'] = None - - # images and annotations - coco_anno['images'] = [] - coco_anno['annotations'] = [] - - jsons = [f for f in os.listdir(isat_json_root) if f.endswith('.json')] - for json in jsons: - coco_image_info = {} - - dataset = load(os.path.join(isat_json_root, json)) - info = dataset.get('info', {}) - description = info.get('description', '') - if not description.startswith('ISAT'): - # 不是ISAT格式json - continue - img_name = info.get('name', '') - width = info.get('width', None) - height = info.get('height', None) - depth = info.get('depth', None) - note = info.get('note', '') - objects = dataset.get('objects', []) - for obj in objects: - category = obj.get('category', 'unknow') - group = obj.get('group', 0) - if group is None: group = 0 - segmentation = obj.get('segmentation', []) - iscrowd = obj.get('iscrowd', 0) - note = obj.get('note', '') - area = obj.get('area', 0) - layer = obj.get('layer', 2) - bbox = obj.get('bbox', []) - - - - def convert_from_coco(self, coco_json:str, to_path:str, keep_crowd:bool=False): - assert coco_json.endswith('.json') - annos = {} - if os.path.exists(coco_json): - with open(coco_json, 'r') as f: - dataset = load(f) - images = {image.get('id', None):{ - 'file_name': image.get('file_name', ''), - 'height': image.get('height', ''), - 'width': image.get('width', ''), - } for image in dataset.get('images', [])} - annotations = dataset.get('annotations', []) - categories = {categorie.get('id', None): {'name': categorie.get('name', '')} for categorie in dataset.get('categories', [])} - for index, annotation in enumerate(annotations): - - annotation_index = annotation.get('id') - annotation_image_id = annotation.get('image_id') - annotation_category_id = annotation.get('category_id') - - file_name = images[annotation_image_id].get('file_name') - height = images[annotation_image_id].get('height') - width = images[annotation_image_id].get('width') - iscrowd = annotation["iscrowd"] - - if file_name == '000000279278.jpg': - continue - if annotation_image_id not in annos: - annos[annotation_image_id] = {} - - objects = annos[annotation_image_id].get('objects', []) - - if iscrowd == 0: - # polygon - segmentations = annotation.get('segmentation') - for segmentation in segmentations: - xs = segmentation[::2] - ys = segmentation[1::2] - points = [[x, y] for x ,y in zip(xs, ys)] - obj = { - 'category': categories.get(annotation_category_id).get('name'), - 'group': annotation_index, - 'area': None, - 'segmentation': points, - 'layer': 1, - 'bbox': None, - 'iscrowd': iscrowd, - 'note': '' - } - objects.append(obj) - elif iscrowd == 1 and keep_crowd: - # RLE - segmentations = annotation.get('segmentation', {}) - rles = coco_mask.frPyObjects(segmentations, height, width) - masks = coco_mask.decode(rles) - contours, _ = cv2.findContours(masks, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_TC89_KCOS) - for contour in contours: - points = [] - for point in contour: - x, y = point[0] - points.append([float(x), float(y)]) - obj = { - 'category': categories.get(annotation_category_id).get('name'), - 'group': annotation_index, - 'area': None, - 'segmentation': points, - 'layer': 1, - 'bbox': None, - 'iscrowd': iscrowd, - 'note': '' - } - objects.append(obj) - - else: - pass - annos[annotation_image_id]['objects'] = objects - - - for image_id, values in annos.items(): - image_path = images[image_id].get('file_name') - folder, name = os.path.split(image_path) - height = images[image_id].get('height') - width = images[image_id].get('width') - objects = values.get('objects', []) - - isat_anno = {} - isat_anno['info'] = {} - isat_anno['info']['description'] = 'ISAT' - isat_anno['info']['folder'] = folder - isat_anno['info']['name'] = name - isat_anno['info']['width'] = width - isat_anno['info']['height'] = height - isat_anno['info']['depth'] = None - isat_anno['info']['note'] = '' - isat_anno['objects'] = [] - # coco annotation的id 太大了,这里缩一下,每张图片重新开始计数 - groups_dict = {} - for obj in objects: - group = obj.get('group', 0) - if group not in groups_dict: - groups_dict[group] = len(groups_dict)+1 - for obj in objects: - object = {} - object['category'] = obj.get('category', '') - object['group'] = groups_dict.get(obj.get('group', 0)) - object['segmentation'] = obj.get('segmentation', []) - object['area'] = obj.get('area', None) - object['layer'] = obj.get('layer', None) - object['bbox'] = obj.get('bbox', None) - object['iscrowd'] = obj.get('iscrowd', 0) - object['note'] = obj.get('note', '') - isat_anno['objects'].append(object) - json_name = '.'.join(name.split('.')[:-1]) + '.json' - save_json = os.path.join(to_path, json_name) - with open(save_json, 'w') as f: - try: - dump(isat_anno, f) - print('Converted coco to ISAT: {}'.format(json_name)) - - except Exception as e: - print('Convert coco to ISAT {} ,error: {}'.format(json_name, e)) - - ### 类别文件 - cmap = imgviz.label_colormap() - - -if __name__ == '__main__': - coco = COCOConverter() - coco.convert_from_coco( - '/mnt/disk/coco/annotations/instances_val2017.json', - '/mnt/disk/coco/isat_json', - True - ) \ No newline at end of file diff --git a/ui/COCO_to_ISAT_dialog.py b/ui/COCO_to_ISAT_dialog.py new file mode 100644 index 0000000..b574486 --- /dev/null +++ b/ui/COCO_to_ISAT_dialog.py @@ -0,0 +1,109 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file 'COCO_to_ISAT_dialog.ui' +# +# Created by: PyQt5 UI code generator 5.15.7 +# +# WARNING: Any manual changes made to this file will be lost when pyuic5 is +# run again. Do not edit this file unless you know what you are doing. + + +from PyQt5 import QtCore, QtGui, QtWidgets + + +class Ui_Dialog(object): + def setupUi(self, Dialog): + Dialog.setObjectName("Dialog") + Dialog.setWindowModality(QtCore.Qt.NonModal) + Dialog.resize(514, 202) + font = QtGui.QFont() + font.setFamily("Times New Roman") + font.setPointSize(12) + Dialog.setFont(font) + Dialog.setSizeGripEnabled(False) + Dialog.setModal(False) + self.verticalLayout = QtWidgets.QVBoxLayout(Dialog) + self.verticalLayout.setObjectName("verticalLayout") + self.widget = QtWidgets.QWidget(Dialog) + self.widget.setObjectName("widget") + self.gridLayout = QtWidgets.QGridLayout(self.widget) + self.gridLayout.setContentsMargins(0, 0, 0, 0) + self.gridLayout.setObjectName("gridLayout") + self.pushButton_save_root = QtWidgets.QPushButton(self.widget) + self.pushButton_save_root.setObjectName("pushButton_save_root") + self.gridLayout.addWidget(self.pushButton_save_root, 3, 1, 1, 1) + self.pushButton_label_path = QtWidgets.QPushButton(self.widget) + self.pushButton_label_path.setObjectName("pushButton_label_path") + self.gridLayout.addWidget(self.pushButton_label_path, 2, 1, 1, 1) + self.lineEdit_save_root = QtWidgets.QLineEdit(self.widget) + self.lineEdit_save_root.setEnabled(True) + self.lineEdit_save_root.setReadOnly(True) + self.lineEdit_save_root.setObjectName("lineEdit_save_root") + self.gridLayout.addWidget(self.lineEdit_save_root, 3, 0, 1, 1) + self.lineEdit_label_path = QtWidgets.QLineEdit(self.widget) + self.lineEdit_label_path.setEnabled(True) + self.lineEdit_label_path.setReadOnly(True) + self.lineEdit_label_path.setObjectName("lineEdit_label_path") + self.gridLayout.addWidget(self.lineEdit_label_path, 2, 0, 1, 1) + self.verticalLayout.addWidget(self.widget) + self.widget_3 = QtWidgets.QWidget(Dialog) + self.widget_3.setObjectName("widget_3") + self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.widget_3) + self.horizontalLayout_2.setObjectName("horizontalLayout_2") + spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_2.addItem(spacerItem) + self.checkBox_keepcrowd = QtWidgets.QCheckBox(self.widget_3) + self.checkBox_keepcrowd.setObjectName("checkBox_keepcrowd") + self.horizontalLayout_2.addWidget(self.checkBox_keepcrowd) + self.verticalLayout.addWidget(self.widget_3) + self.widget_4 = QtWidgets.QWidget(Dialog) + self.widget_4.setObjectName("widget_4") + self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.widget_4) + self.horizontalLayout_3.setObjectName("horizontalLayout_3") + spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_3.addItem(spacerItem1) + self.label_info = QtWidgets.QLabel(self.widget_4) + self.label_info.setText("") + self.label_info.setObjectName("label_info") + self.horizontalLayout_3.addWidget(self.label_info) + self.verticalLayout.addWidget(self.widget_4) + self.widget_2 = QtWidgets.QWidget(Dialog) + self.widget_2.setObjectName("widget_2") + self.horizontalLayout = QtWidgets.QHBoxLayout(self.widget_2) + self.horizontalLayout.setContentsMargins(0, 0, 0, 0) + self.horizontalLayout.setObjectName("horizontalLayout") + self.label = QtWidgets.QLabel(self.widget_2) + self.label.setStyleSheet("color: rgb(255, 0, 0);") + self.label.setObjectName("label") + self.horizontalLayout.addWidget(self.label) + spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout.addItem(spacerItem2) + self.pushButton_cache = QtWidgets.QPushButton(self.widget_2) + icon = QtGui.QIcon() + icon.addPixmap(QtGui.QPixmap(":/icons/icons/关闭_close-one.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.pushButton_cache.setIcon(icon) + self.pushButton_cache.setObjectName("pushButton_cache") + self.horizontalLayout.addWidget(self.pushButton_cache) + self.pushButton_apply = QtWidgets.QPushButton(self.widget_2) + icon1 = QtGui.QIcon() + icon1.addPixmap(QtGui.QPixmap(":/icons/icons/校验_check-one.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.pushButton_apply.setIcon(icon1) + self.pushButton_apply.setObjectName("pushButton_apply") + self.horizontalLayout.addWidget(self.pushButton_apply) + self.verticalLayout.addWidget(self.widget_2) + + self.retranslateUi(Dialog) + QtCore.QMetaObject.connectSlotsByName(Dialog) + + def retranslateUi(self, Dialog): + _translate = QtCore.QCoreApplication.translate + Dialog.setWindowTitle(_translate("Dialog", "ISAT to VOC png")) + self.pushButton_save_root.setText(_translate("Dialog", "Save root")) + self.pushButton_label_path.setText(_translate("Dialog", "Json path")) + self.lineEdit_save_root.setPlaceholderText(_translate("Dialog", "ISAT jsons save root")) + self.lineEdit_label_path.setPlaceholderText(_translate("Dialog", "COCO json path")) + self.checkBox_keepcrowd.setText(_translate("Dialog", "Keep crowd")) + self.label.setText(_translate("Dialog", "Convert COCO json to ISAT jsons.")) + self.pushButton_cache.setText(_translate("Dialog", "cache")) + self.pushButton_apply.setText(_translate("Dialog", "convert")) +import icons_rc diff --git a/ui/COCO_to_ISAT_dialog.ui b/ui/COCO_to_ISAT_dialog.ui new file mode 100644 index 0000000..557a10b --- /dev/null +++ b/ui/COCO_to_ISAT_dialog.ui @@ -0,0 +1,211 @@ + + + Dialog + + + Qt::NonModal + + + + 0 + 0 + 514 + 202 + + + + + Times New Roman + 12 + + + + ISAT to VOC png + + + false + + + false + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Save root + + + + + + + Json path + + + + + + + true + + + true + + + ISAT jsons save root + + + + + + + true + + + true + + + COCO json path + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Keep crowd + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + color: rgb(255, 0, 0); + + + Convert COCO json to ISAT jsons. + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + cache + + + + :/icons/icons/关闭_close-one.svg:/icons/icons/关闭_close-one.svg + + + + + + + convert + + + + :/icons/icons/校验_check-one.svg:/icons/icons/校验_check-one.svg + + + + + + + + + + + + + diff --git a/ui/ISAT_to_COCO_dialog.py b/ui/ISAT_to_COCO_dialog.py new file mode 100644 index 0000000..a171bfc --- /dev/null +++ b/ui/ISAT_to_COCO_dialog.py @@ -0,0 +1,98 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file 'ISAT_to_COCO_dialog.ui' +# +# Created by: PyQt5 UI code generator 5.15.7 +# +# WARNING: Any manual changes made to this file will be lost when pyuic5 is +# run again. Do not edit this file unless you know what you are doing. + + +from PyQt5 import QtCore, QtGui, QtWidgets + + +class Ui_Dialog(object): + def setupUi(self, Dialog): + Dialog.setObjectName("Dialog") + Dialog.setWindowModality(QtCore.Qt.NonModal) + Dialog.resize(508, 155) + font = QtGui.QFont() + font.setFamily("Times New Roman") + font.setPointSize(12) + Dialog.setFont(font) + Dialog.setSizeGripEnabled(False) + Dialog.setModal(False) + self.verticalLayout = QtWidgets.QVBoxLayout(Dialog) + self.verticalLayout.setObjectName("verticalLayout") + self.widget = QtWidgets.QWidget(Dialog) + self.widget.setObjectName("widget") + self.gridLayout = QtWidgets.QGridLayout(self.widget) + self.gridLayout.setContentsMargins(0, 0, 0, 0) + self.gridLayout.setObjectName("gridLayout") + self.pushButton_save_path = QtWidgets.QPushButton(self.widget) + self.pushButton_save_path.setObjectName("pushButton_save_path") + self.gridLayout.addWidget(self.pushButton_save_path, 3, 1, 1, 1) + self.pushButton_label_root = QtWidgets.QPushButton(self.widget) + self.pushButton_label_root.setObjectName("pushButton_label_root") + self.gridLayout.addWidget(self.pushButton_label_root, 2, 1, 1, 1) + self.lineEdit_save_path = QtWidgets.QLineEdit(self.widget) + self.lineEdit_save_path.setEnabled(True) + self.lineEdit_save_path.setReadOnly(True) + self.lineEdit_save_path.setObjectName("lineEdit_save_path") + self.gridLayout.addWidget(self.lineEdit_save_path, 3, 0, 1, 1) + self.lineEdit_label_root = QtWidgets.QLineEdit(self.widget) + self.lineEdit_label_root.setEnabled(True) + self.lineEdit_label_root.setReadOnly(True) + self.lineEdit_label_root.setObjectName("lineEdit_label_root") + self.gridLayout.addWidget(self.lineEdit_label_root, 2, 0, 1, 1) + self.verticalLayout.addWidget(self.widget) + self.widget_3 = QtWidgets.QWidget(Dialog) + self.widget_3.setObjectName("widget_3") + self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.widget_3) + self.horizontalLayout_2.setObjectName("horizontalLayout_2") + spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_2.addItem(spacerItem) + self.label_info = QtWidgets.QLabel(self.widget_3) + self.label_info.setText("") + self.label_info.setObjectName("label_info") + self.horizontalLayout_2.addWidget(self.label_info) + self.verticalLayout.addWidget(self.widget_3) + self.widget_2 = QtWidgets.QWidget(Dialog) + self.widget_2.setObjectName("widget_2") + self.horizontalLayout = QtWidgets.QHBoxLayout(self.widget_2) + self.horizontalLayout.setContentsMargins(0, 0, 0, 0) + self.horizontalLayout.setObjectName("horizontalLayout") + self.label = QtWidgets.QLabel(self.widget_2) + self.label.setStyleSheet("color: rgb(255, 0, 0);") + self.label.setObjectName("label") + self.horizontalLayout.addWidget(self.label) + spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout.addItem(spacerItem1) + self.pushButton_cache = QtWidgets.QPushButton(self.widget_2) + icon = QtGui.QIcon() + icon.addPixmap(QtGui.QPixmap(":/icons/icons/关闭_close-one.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.pushButton_cache.setIcon(icon) + self.pushButton_cache.setObjectName("pushButton_cache") + self.horizontalLayout.addWidget(self.pushButton_cache) + self.pushButton_apply = QtWidgets.QPushButton(self.widget_2) + icon1 = QtGui.QIcon() + icon1.addPixmap(QtGui.QPixmap(":/icons/icons/校验_check-one.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.pushButton_apply.setIcon(icon1) + self.pushButton_apply.setObjectName("pushButton_apply") + self.horizontalLayout.addWidget(self.pushButton_apply) + self.verticalLayout.addWidget(self.widget_2) + + self.retranslateUi(Dialog) + QtCore.QMetaObject.connectSlotsByName(Dialog) + + def retranslateUi(self, Dialog): + _translate = QtCore.QCoreApplication.translate + Dialog.setWindowTitle(_translate("Dialog", "ISAT to VOC png")) + self.pushButton_save_path.setText(_translate("Dialog", "Save path")) + self.pushButton_label_root.setText(_translate("Dialog", "Jsons root")) + self.lineEdit_save_path.setPlaceholderText(_translate("Dialog", "COCO json save path")) + self.lineEdit_label_root.setPlaceholderText(_translate("Dialog", "ISAT jsons root")) + self.label.setText(_translate("Dialog", "Convert ISAT jsons to COCO json.")) + self.pushButton_cache.setText(_translate("Dialog", "cache")) + self.pushButton_apply.setText(_translate("Dialog", "convert")) +import icons_rc diff --git a/ui/ISAT_to_COCO_dialog.ui b/ui/ISAT_to_COCO_dialog.ui new file mode 100644 index 0000000..f1acc8c --- /dev/null +++ b/ui/ISAT_to_COCO_dialog.ui @@ -0,0 +1,185 @@ + + + Dialog + + + Qt::NonModal + + + + 0 + 0 + 508 + 155 + + + + + Times New Roman + 12 + + + + ISAT to VOC png + + + false + + + false + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Save path + + + + + + + Jsons root + + + + + + + true + + + true + + + COCO json save path + + + + + + + true + + + true + + + ISAT jsons root + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + color: rgb(255, 0, 0); + + + Convert ISAT jsons to COCO json. + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + cache + + + + :/icons/icons/关闭_close-one.svg:/icons/icons/关闭_close-one.svg + + + + + + + convert + + + + :/icons/icons/校验_check-one.svg:/icons/icons/校验_check-one.svg + + + + + + + + + + + + + diff --git a/ui/MainWindow.py b/ui/MainWindow.py index 9df6058..7e3321c 100644 --- a/ui/MainWindow.py +++ b/ui/MainWindow.py @@ -14,7 +14,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") - MainWindow.resize(1280, 760) + MainWindow.resize(1280, 764) MainWindow.setMinimumSize(QtCore.QSize(800, 600)) font = QtGui.QFont() font.setFamily("Times New Roman") @@ -260,6 +260,9 @@ class Ui_MainWindow(object): icon25.addPixmap(QtGui.QPixmap(":/icon/icons/coco.ico"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionToCOCO.setIcon(icon25) self.actionToCOCO.setObjectName("actionToCOCO") + self.actionFromCOCO = QtWidgets.QAction(MainWindow) + self.actionFromCOCO.setIcon(icon25) + self.actionFromCOCO.setObjectName("actionFromCOCO") self.menuFile.addAction(self.actionOpen_dir) self.menuFile.addAction(self.actionSave_dir) self.menuFile.addSeparator() @@ -282,6 +285,7 @@ class Ui_MainWindow(object): self.menuAbout.addAction(self.actionAbout) self.menuTools.addAction(self.actionToVOC) self.menuTools.addAction(self.actionToCOCO) + self.menuTools.addAction(self.actionFromCOCO) self.menuEdit.addAction(self.actionSegment_anything) self.menuEdit.addAction(self.actionPolygon) self.menuEdit.addAction(self.actionBackspace) @@ -389,9 +393,9 @@ class Ui_MainWindow(object): self.actionTo_bottom.setToolTip(_translate("MainWindow", "Move polygon to bottom layer")) self.actionTo_bottom.setStatusTip(_translate("MainWindow", "Move polygon to bottom layer.")) self.actionTo_bottom.setShortcut(_translate("MainWindow", "B")) - self.actionToVOC.setText(_translate("MainWindow", "ToVOC")) + self.actionToVOC.setText(_translate("MainWindow", "To VOC")) self.actionToVOC.setToolTip(_translate("MainWindow", "Convert ISAT to VOC")) - self.actionToVOC.setStatusTip(_translate("MainWindow", "Convert annotations to png image.")) + self.actionToVOC.setStatusTip(_translate("MainWindow", "Convert ISAT jsons to VOC png image.")) self.actionChinese.setText(_translate("MainWindow", "中文")) self.actionEnglish.setText(_translate("MainWindow", "English")) self.actionBackspace.setText(_translate("MainWindow", "Backspace")) @@ -413,6 +417,10 @@ class Ui_MainWindow(object): self.actionVisible.setText(_translate("MainWindow", "Visible")) self.actionVisible.setStatusTip(_translate("MainWindow", "Visible")) self.actionVisible.setShortcut(_translate("MainWindow", "V")) - self.actionToCOCO.setText(_translate("MainWindow", "ToCOCO")) + self.actionToCOCO.setText(_translate("MainWindow", "To COCO")) self.actionToCOCO.setToolTip(_translate("MainWindow", "Convert ISAT to COCO")) + self.actionToCOCO.setStatusTip(_translate("MainWindow", "Convert ISAT jsons to COCO json.")) + self.actionFromCOCO.setText(_translate("MainWindow", "From COCO")) + self.actionFromCOCO.setToolTip(_translate("MainWindow", "Convert COCO to ISAT")) + self.actionFromCOCO.setStatusTip(_translate("MainWindow", "Convert COCO json to ISAT jsons.")) import icons_rc diff --git a/ui/MainWindow.ui b/ui/MainWindow.ui index aa18d31..e7c16e7 100644 --- a/ui/MainWindow.ui +++ b/ui/MainWindow.ui @@ -7,7 +7,7 @@ 0 0 1280 - 760 + 764 @@ -152,6 +152,7 @@ + @@ -576,13 +577,13 @@ :/icon/icons/voc.png:/icon/icons/voc.png - ToVOC + To VOC Convert ISAT to VOC - Convert annotations to png image. + Convert ISAT jsons to VOC png image. @@ -709,11 +710,29 @@ :/icon/icons/coco.ico:/icon/icons/coco.ico - ToCOCO + To COCO Convert ISAT to COCO + + Convert ISAT jsons to COCO json. + + + + + + :/icon/icons/coco.ico:/icon/icons/coco.ico + + + From COCO + + + Convert COCO to ISAT + + + Convert COCO json to ISAT jsons. + diff --git a/widgets/COCO_to_ISAT_dialog.py b/widgets/COCO_to_ISAT_dialog.py new file mode 100644 index 0000000..8a5afb8 --- /dev/null +++ b/widgets/COCO_to_ISAT_dialog.py @@ -0,0 +1,69 @@ +# -*- coding: utf-8 -*- +# @Author : LG + +from PyQt5 import QtWidgets, QtCore, QtGui +from ui.COCO_to_ISAT_dialog import Ui_Dialog +from tools.toCOCO import COCOConverter + + +class COCOtoISATDialog(QtWidgets.QDialog, Ui_Dialog): + def __init__(self, parent, mainwindow): + super(COCOtoISATDialog, self).__init__(parent) + self.setupUi(self) + self.mainwindow = mainwindow + self.label_path = None + self.save_root = None + self.pause = False + + self.setWindowModality(QtCore.Qt.WindowModality.WindowModal) + + self.init_connect() + + def reset_gui(self): + self.lineEdit_label_path.clear() + self.lineEdit_save_root.clear() + + def _label_path(self): + path, suffix = QtWidgets.QFileDialog.getOpenFileName(self, caption='COCO json save file', + filter="json (*.json)") + if path: + self.label_path = path + self.lineEdit_label_path.setText(path) + else: + self.lineEdit_label_path.clear() + + def _save_root(self): + + dir = QtWidgets.QFileDialog.getExistingDirectory(self, caption='ISAT jsons root') + if dir: + + self.save_root = dir + self.lineEdit_save_root.setText(dir) + else: + self.lineEdit_save_root.clear() + + def cache(self): + self.pause = True + self.close() + + def apply(self): + self.pause = False + if self.label_path is None or self.save_root is None: + return + + converter = COCOConverter() + + self.pushButton_label_path.setEnabled(False) + self.pushButton_save_root.setEnabled(False) + self.label_info.setText('Convering...') + converter.convert_from_coco(self.label_path, self.save_root, keep_crowd=self.checkBox_keepcrowd.isChecked()) + self.label_info.setText('Finish!!!') + + self.pushButton_label_path.setEnabled(True) + self.pushButton_save_root.setEnabled(True) + + def init_connect(self): + self.pushButton_label_path.clicked.connect(self._label_path) + self.pushButton_save_root.clicked.connect(self._save_root) + self.pushButton_apply.clicked.connect(self.apply) + self.pushButton_cache.clicked.connect(self.cache) \ No newline at end of file diff --git a/widgets/ISAT_to_COCO_dialog.py b/widgets/ISAT_to_COCO_dialog.py new file mode 100644 index 0000000..67650a1 --- /dev/null +++ b/widgets/ISAT_to_COCO_dialog.py @@ -0,0 +1,69 @@ +# -*- coding: utf-8 -*- +# @Author : LG + +from PyQt5 import QtWidgets, QtCore, QtGui +from ui.ISAT_to_COCO_dialog import Ui_Dialog +from tools.toCOCO import COCOConverter + + +class ISATtoCOCODialog(QtWidgets.QDialog, Ui_Dialog): + def __init__(self, parent, mainwindow): + super(ISATtoCOCODialog, self).__init__(parent) + self.setupUi(self) + self.mainwindow = mainwindow + self.label_root = None + self.save_path = None + self.pause = False + + self.setWindowModality(QtCore.Qt.WindowModality.WindowModal) + + self.init_connect() + + def reset_gui(self): + self.lineEdit_label_root.clear() + self.lineEdit_save_path.clear() + + def _label_root(self): + dir = QtWidgets.QFileDialog.getExistingDirectory(self, caption='ISAT jsons root') + if dir: + self.label_root = dir + self.lineEdit_label_root.setText(dir) + else: + self.lineEdit_label_root.clear() + + def _save_path(self): + path, suffix = QtWidgets.QFileDialog.getSaveFileName(self, caption='COCO json save file', filter="json (*.json)") + if path: + if not path.endswith('.json'): + path += '.json' + self.save_path = path + self.lineEdit_save_path.setText(path) + else: + self.lineEdit_save_path.clear() + + def cache(self): + self.pause = True + self.close() + + def apply(self): + self.pause = False + if self.label_root is None or self.save_path is None: + return + + converter = COCOConverter() + + self.pushButton_label_root.setEnabled(False) + self.pushButton_save_path.setEnabled(False) + self.label_info.setText('Convering...') + + converter.convert_to_coco(self.label_root, self.save_path) + self.label_info.setText('Finish!!!') + + self.pushButton_label_root.setEnabled(True) + self.pushButton_save_path.setEnabled(True) + + def init_connect(self): + self.pushButton_label_root.clicked.connect(self._label_root) + self.pushButton_save_path.clicked.connect(self._save_path) + self.pushButton_apply.clicked.connect(self.apply) + self.pushButton_cache.clicked.connect(self.cache) \ No newline at end of file diff --git a/widgets/ISAT_to_VOC_dialog.py b/widgets/ISAT_to_VOC_dialog.py index 7c7a428..2062ff3 100644 --- a/widgets/ISAT_to_VOC_dialog.py +++ b/widgets/ISAT_to_VOC_dialog.py @@ -3,7 +3,7 @@ from PyQt5 import QtWidgets, QtCore, QtGui from ui.ISAT_to_VOC_dialog import Ui_Dialog -from tools.toVOC import ToVOC +from tools.toVOC import VOCConverter import os @@ -55,7 +55,7 @@ class ISATtoVOCDialog(QtWidgets.QDialog, Ui_Dialog): for index, label in enumerate(self.mainwindow.cfg.get('label', [])): f.write('{} {}\n'.format(label.get('name'), index)) - converter = ToVOC(self.mainwindow.cfg, self.checkBox_is_instance.isChecked()) + converter = VOCConverter(self.mainwindow.cfg, self.checkBox_is_instance.isChecked()) jsons = [f for f in os.listdir(self.label_root) if f.endswith('.json')] self.pushButton_label_root.setEnabled(False) diff --git a/widgets/converter.py b/widgets/converter.py deleted file mode 100644 index 2f33183..0000000 --- a/widgets/converter.py +++ /dev/null @@ -1,86 +0,0 @@ -# -*- coding: utf-8 -*- -# @Author : LG - -from PyQt5 import QtWidgets, QtCore, QtGui -from ui.ISAT_to_VOC_dialog import Ui_Dialog -from tools.toVOC import ToVOC -import os - - -class TOVOCDialog(QtWidgets.QDialog, Ui_Dialog): - def __init__(self, parent, mainwindow): - super(TOVOCDialog, self).__init__(parent) - self.setupUi(self) - self.mainwindow = mainwindow - self.label_root = None - self.save_root = None - self.pause = False - - self.setWindowModality(QtCore.Qt.WindowModality.WindowModal) - - self.init_connect() - - def reset_gui(self): - self.widget_process.setVisible(False) - self.lineEdit_label_root.clear() - self.lineEdit_save_root.clear() - - def _label_root(self): - dir = QtWidgets.QFileDialog.getExistingDirectory(self) - if dir: - self.label_root = dir - self.lineEdit_label_root.setText(dir) - else: - self.lineEdit_label_root.clear() - - def _save_root(self): - dir = QtWidgets.QFileDialog.getExistingDirectory(self) - if dir: - self.save_root = dir - self.lineEdit_save_root.setText(dir) - else: - self.lineEdit_save_root.clear() - - def cache(self): - self.pause = True - self.close() - - def apply(self): - self.pause = False - if self.label_root is None or self.save_root is None: - return - # 语义分割,保存类别文件 - if not self.checkBox_is_instance.isChecked(): - with open(os.path.join(self.save_root, 'classesition.txt'), 'w') as f: - for index, label in enumerate(self.mainwindow.cfg.get('label', [])): - f.write('{} {}\n'.format(label.get('name'), index)) - - converter = ToVOC(self.mainwindow.cfg, self.checkBox_is_instance.isChecked()) - jsons = [f for f in os.listdir(self.label_root) if f.endswith('.json')] - - self.pushButton_label_root.setEnabled(False) - self.pushButton_save_root.setEnabled(False) - self.checkBox_is_instance.setEnabled(False) - - self.widget_process.setVisible(True) - self.progressBar.setMaximum(len(jsons)) - self.all_num.setText('{}'.format(len(jsons))) - - for index, json in enumerate(jsons): - if self.pause: - break - label_path = os.path.join(self.label_root, json) - save_path = os.path.join(self.save_root, json[:-5]+'.png') - converter.convert(label_path, save_path) - self.progressBar.setValue(index+1) - self.current_num.setText('{}'.format(index+1)) - - self.pushButton_label_root.setEnabled(True) - self.pushButton_save_root.setEnabled(True) - self.checkBox_is_instance.setEnabled(True) - - def init_connect(self): - self.pushButton_label_root.clicked.connect(self._label_root) - self.pushButton_save_root.clicked.connect(self._save_root) - self.pushButton_apply.clicked.connect(self.apply) - self.pushButton_cache.clicked.connect(self.cache) \ No newline at end of file diff --git a/widgets/mainwindow.py b/widgets/mainwindow.py index 280f888..3382647 100644 --- a/widgets/mainwindow.py +++ b/widgets/mainwindow.py @@ -13,6 +13,8 @@ from widgets.right_button_menu import RightButtonMenu from widgets.shortcut_dialog import ShortcutDialog from widgets.about_dialog import AboutDialog from widgets.ISAT_to_VOC_dialog import ISATtoVOCDialog +from widgets.ISAT_to_COCO_dialog import ISATtoCOCODialog +from widgets.COCO_to_ISAT_dialog import COCOtoISATDialog from widgets.canvas import AnnotationScene, AnnotationView from configs import STATUSMode, MAPMode, load_config, save_config, CONFIG_FILE, DEFAULT_CONFIG_FILE from annotation import Object, Annotation @@ -84,8 +86,6 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): self.labelGPUResource.setText('segment anything unused.') def init_ui(self): - # 待完成 - self.actionToCOCO.setEnabled(False) # self.setting_dialog = SettingDialog(parent=self, mainwindow=self) @@ -103,6 +103,8 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): self.category_edit_widget = CategoryEditDialog(self, self, self.scene) self.ISAT_to_VOC_dialog = ISATtoVOCDialog(self, mainwindow=self) + self.ISAT_to_COCO_dialog = ISATtoCOCODialog(self, mainwindow=self) + self.COCO_to_ISAT_dialog = COCOtoISATDialog(self, mainwindow=self) self.view = AnnotationView(parent=self) self.view.setScene(self.scene) @@ -152,6 +154,8 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): self.about_dialog.retranslateUi(self.about_dialog) self.shortcut_dialog.retranslateUi(self.shortcut_dialog) self.ISAT_to_VOC_dialog.retranslateUi(self.ISAT_to_VOC_dialog) + self.ISAT_to_COCO_dialog.retranslateUi(self.ISAT_to_COCO_dialog) + self.COCO_to_ISAT_dialog.retranslateUi(self.COCO_to_ISAT_dialog) def translate_to_chinese(self): self.translate('zh') @@ -467,6 +471,14 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): self.ISAT_to_VOC_dialog.reset_gui() self.ISAT_to_VOC_dialog.show() + def ISAT_to_COCO(self): + self.ISAT_to_COCO_dialog.reset_gui() + self.ISAT_to_COCO_dialog.show() + + def COCO_to_ISAT(self): + self.COCO_to_ISAT_dialog.reset_gui() + self.COCO_to_ISAT_dialog.show() + def help(self): self.shortcut_dialog.show() @@ -509,6 +521,8 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): self.actionVisible.triggered.connect(functools.partial(self.set_labels_visible, None)) self.actionToVOC.triggered.connect(self.ISAT_to_VOC) + self.actionToCOCO.triggered.connect(self.ISAT_to_COCO) + self.actionFromCOCO.triggered.connect(self.COCO_to_ISAT) self.actionShortcut.triggered.connect(self.help) self.actionAbout.triggered.connect(self.about)