toVOC toCOCO
This commit is contained in:
parent
f6f985b72c
commit
c03420ce63
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.6 (segment_anything_env)" project-jdk-type="Python SDK" />
|
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.8 (ISAT_with_segment_anything)" project-jdk-type="Python SDK" />
|
||||||
</project>
|
</project>
|
22
example/images/isat.yaml
Normal file
22
example/images/isat.yaml
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
label:
|
||||||
|
- color: '#000000'
|
||||||
|
name: __background__
|
||||||
|
- color: '#ef2929'
|
||||||
|
name: person
|
||||||
|
- color: '#fcaf3e'
|
||||||
|
name: knife
|
||||||
|
- color: '#fce94f'
|
||||||
|
name: fork
|
||||||
|
- color: '#8ae234'
|
||||||
|
name: cup
|
||||||
|
- color: '#729fcf'
|
||||||
|
name: giraffe
|
||||||
|
- color: '#ad7fa8'
|
||||||
|
name: plate
|
||||||
|
- color: '#e9b96e'
|
||||||
|
name: table
|
||||||
|
- color: '#a40000'
|
||||||
|
name: cake
|
||||||
|
- color: '#5c3566'
|
||||||
|
name: fence
|
||||||
|
language: zh
|
199
tools/fromCOCO.py
Normal file
199
tools/fromCOCO.py
Normal file
@ -0,0 +1,199 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# @Author : LG
|
||||||
|
|
||||||
|
|
||||||
|
from PyQt5.QtCore import QThread, pyqtSignal
|
||||||
|
from json import load, dump
|
||||||
|
import os
|
||||||
|
from pycocotools import mask as coco_mask
|
||||||
|
import cv2
|
||||||
|
import imgviz
|
||||||
|
import yaml
|
||||||
|
|
||||||
|
class FROMCOCO(QThread):
|
||||||
|
message = pyqtSignal(int, int, str)
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super(FROMCOCO, self).__init__()
|
||||||
|
self.coco_json_path:str = None
|
||||||
|
self.to_root:str = None
|
||||||
|
self.keep_crowd = False
|
||||||
|
|
||||||
|
self.cache = False
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
assert self.coco_json_path.endswith('.json')
|
||||||
|
annos = {}
|
||||||
|
if os.path.exists(self.coco_json_path):
|
||||||
|
self.message.emit(None, None, 'Loading COCO json: {}'.format(self.coco_json_path))
|
||||||
|
|
||||||
|
with open(self.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', [])}
|
||||||
|
self.message.emit(None, None, ' Contain {} images.'.format(len(images)))
|
||||||
|
|
||||||
|
annotations = dataset.get('annotations', [])
|
||||||
|
self.message.emit(None, None, ' Contain {} annotations.'.format(len(annotations)))
|
||||||
|
|
||||||
|
categories = {categorie.get('id', None): {'name': categorie.get('name', '')} for categorie in
|
||||||
|
dataset.get('categories', [])}
|
||||||
|
self.message.emit(None, None, ' Contain {} categories.'.format(len(categories)))
|
||||||
|
|
||||||
|
self.message.emit(None, None, 'Loading annotations...')
|
||||||
|
for index, annotation in enumerate(annotations):
|
||||||
|
if self.cache:
|
||||||
|
return
|
||||||
|
self.message.emit(index+1, len(annotations), None)
|
||||||
|
|
||||||
|
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 self.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
|
||||||
|
|
||||||
|
self.message.emit(None, None, 'Start convert to ISAT json...')
|
||||||
|
for index, (image_id, values) in enumerate(annos.items()):
|
||||||
|
if self.cache:
|
||||||
|
return
|
||||||
|
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', '')
|
||||||
|
if 'background' in object['category']:
|
||||||
|
object['group'] = 0
|
||||||
|
else:
|
||||||
|
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(self.to_root, json_name)
|
||||||
|
|
||||||
|
self.message.emit(index + 1, len(annos), '{:>8d}/{:<8d} | Converting to {}'.format(index + 1, len(annos), json_name))
|
||||||
|
|
||||||
|
with open(save_json, 'w') as f:
|
||||||
|
try:
|
||||||
|
dump(isat_anno, f)
|
||||||
|
self.message.emit(None, None, ' ' * 18 + '| Saved finished.')
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
self.message.emit(index + 1, len(annos), ' ' * 18 + '| Save error: {}'.format(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)
|
||||||
|
|
||||||
|
s = yaml.dump({'label': list(categories.values())})
|
||||||
|
with open(os.path.join(self.to_root, 'categorys.yaml'), 'w') as f:
|
||||||
|
f.write(s)
|
||||||
|
self.message.emit(None, None, 'Generate categorys.yaml.')
|
||||||
|
else:
|
||||||
|
self.message.emit(None, None, '{} not exist.'.format(self.coco_json_path))
|
||||||
|
self.message.emit(None, None, '*** Finished! ***')
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
self.wait()
|
193
tools/toCOCO.py
193
tools/toCOCO.py
@ -1,17 +1,22 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# @Author : LG
|
# @Author : LG
|
||||||
|
|
||||||
|
from PyQt5.QtCore import QThread, pyqtSignal
|
||||||
from json import load, dump
|
from json import load, dump
|
||||||
import os
|
import os
|
||||||
from pycocotools import mask as coco_mask
|
|
||||||
import cv2
|
|
||||||
import imgviz
|
|
||||||
import yaml
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
class COCOConverter:
|
class TOCOCO(QThread):
|
||||||
def convert_to_coco(self, isat_json_root:str, to_path:str):
|
message = pyqtSignal(int, int, str)
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super(TOCOCO, self).__init__()
|
||||||
|
self.isat_json_root:str = None
|
||||||
|
self.to_path:str = None
|
||||||
|
self.cache = False
|
||||||
|
|
||||||
|
def run(self):
|
||||||
coco_anno = {}
|
coco_anno = {}
|
||||||
# info
|
# info
|
||||||
coco_anno['info'] = {}
|
coco_anno['info'] = {}
|
||||||
@ -36,11 +41,15 @@ class COCOConverter:
|
|||||||
|
|
||||||
categories_dict = {}
|
categories_dict = {}
|
||||||
|
|
||||||
jsons = [f for f in os.listdir(isat_json_root) if f.endswith('.json')]
|
jsons = [f for f in os.listdir(self.isat_json_root) if f.endswith('.json')]
|
||||||
|
num_jsons = len(jsons)
|
||||||
|
self.message.emit(None, None, 'Loading ISAT jsons...')
|
||||||
for file_index, json in enumerate(jsons):
|
for file_index, json in enumerate(jsons):
|
||||||
print('Load ISAT: {}'.format(json))
|
if self.cache:
|
||||||
|
return
|
||||||
|
self.message.emit(file_index+1, num_jsons, '{:>8d}/{:<8d} | Loading ISAT json: {}'.format(file_index+1, num_jsons, json))
|
||||||
try:
|
try:
|
||||||
with open(os.path.join(isat_json_root, json), 'r') as f:
|
with open(os.path.join(self.isat_json_root, json), 'r') as f:
|
||||||
dataset = load(f)
|
dataset = load(f)
|
||||||
info = dataset.get('info', {})
|
info = dataset.get('info', {})
|
||||||
description = info.get('description', '')
|
description = info.get('description', '')
|
||||||
@ -129,169 +138,23 @@ class COCOConverter:
|
|||||||
bbox_tmp[2] - bbox_tmp[0], bbox_tmp[3] - bbox_tmp[1]]
|
bbox_tmp[2] - bbox_tmp[0], bbox_tmp[3] - bbox_tmp[1]]
|
||||||
|
|
||||||
coco_anno['annotations'].append(coco_anno_info)
|
coco_anno['annotations'].append(coco_anno_info)
|
||||||
|
self.message.emit(None, None, ' ' * 18 + '| Loading finished.')
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print('Load ISAT: {}, error: {}'.format(json, e))
|
self.message.emit(None, None, ' ' * 18 + '| Error: {}'.format(e))
|
||||||
|
|
||||||
categories_dict = sorted(categories_dict.items(), key=lambda x:x[1])
|
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]
|
coco_anno['categories'] = [{'name': name, 'id': id, 'supercategory': None} for name, id in categories_dict]
|
||||||
|
|
||||||
with open(to_path, 'w') as f:
|
self.message.emit(None, None, 'Saving COCO json {}'.format(self.to_path))
|
||||||
|
with open(self.to_path, 'w') as f:
|
||||||
try:
|
try:
|
||||||
dump(coco_anno, f)
|
dump(coco_anno, f)
|
||||||
print('Save coco json to {}'.format(to_path))
|
self.message.emit(None, None, 'Saved finished!')
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print('Save {} error :{}'.format(to_path, e))
|
self.message.emit(None, None, 'Error: {}'.format(e))
|
||||||
|
|
||||||
|
self.message.emit(None, None, '*** Finished! ***')
|
||||||
|
|
||||||
def convert_from_coco(self, coco_json_path:str, to_root:str, keep_crowd:bool=False):
|
def __del__(self):
|
||||||
assert coco_json_path.endswith('.json')
|
self.wait()
|
||||||
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', '')
|
|
||||||
if 'background' in object['category']:
|
|
||||||
object['group'] = 0
|
|
||||||
else:
|
|
||||||
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)
|
|
124
tools/toVOC.py
124
tools/toVOC.py
@ -1,63 +1,103 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# @Author : LG
|
# @Author : LG
|
||||||
|
|
||||||
|
from PyQt5.QtCore import QThread, pyqtSignal
|
||||||
from json import load
|
from json import load
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from PIL import Image, ImageDraw, ImageColor
|
from PIL import Image, ImageColor
|
||||||
import mahotas
|
import mahotas
|
||||||
import imgviz
|
import imgviz
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
class VOCConverter:
|
class TOVOC(QThread):
|
||||||
def __init__(self, cfg, is_segmentation):
|
message = pyqtSignal(int, int, str)
|
||||||
self.is_segmentation = is_segmentation
|
|
||||||
|
|
||||||
labels = cfg.get('label', [])
|
def __init__(self,):
|
||||||
self.category_dict = {}
|
super(TOVOC, self).__init__()
|
||||||
if self.is_segmentation:
|
self.cfg = None
|
||||||
self.cmap = imgviz.label_colormap()
|
self.from_root = None
|
||||||
|
self.to_root = None
|
||||||
|
self.is_instance = False
|
||||||
|
self.keep_crowd = False
|
||||||
|
self.cache = False
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
labels = self.cfg.get('label', [])
|
||||||
|
category_dict = {}
|
||||||
|
if self.is_instance:
|
||||||
|
cmap = imgviz.label_colormap()
|
||||||
else:
|
else:
|
||||||
self.cmap = np.zeros((len(labels), 3), dtype=np.uint8)
|
self.message.emit(None, None, 'Loading category index and color...')
|
||||||
|
self.message.emit(None, None, ' '+'-'*53)
|
||||||
|
self.message.emit(None, None, ' | {:^5s} | {:^8s} | {:^30s} |'.format('index', 'color', 'category'))
|
||||||
|
cmap = np.zeros((len(labels), 3), dtype=np.uint8)
|
||||||
for index, label_dict in enumerate(labels):
|
for index, label_dict in enumerate(labels):
|
||||||
category = label_dict.get('name', 'unknow')
|
category = label_dict.get('name', 'unknow')
|
||||||
color = label_dict.get('color', '#000000')
|
color = label_dict.get('color', '#000000')
|
||||||
self.category_dict[category] = {'index': index, 'color': color}
|
category_dict[category] = {'index': index, 'color': color}
|
||||||
self.cmap[index] = (ImageColor.getrgb(color))
|
cmap[index] = (ImageColor.getrgb(color))
|
||||||
|
self.message.emit(None, None, ' | {:>5d} | {:>8s} | {:<30s} |'.format(index, color, category))
|
||||||
|
self.message.emit(None, None, ' '+'-' * 53)
|
||||||
|
self.message.emit(None, None, 'Load category index and color finished!')
|
||||||
|
|
||||||
def convert(self, from_path:str, to_path:str):
|
jsons = [f for f in os.listdir(self.from_root) if f.endswith('.json')]
|
||||||
assert from_path.endswith('.json')
|
num_jsons = len(jsons)
|
||||||
|
|
||||||
with open(from_path, 'r') as f:
|
self.message.emit(None, None, 'Start convert.')
|
||||||
dataset = load(f)
|
|
||||||
info = dataset.get('info', {})
|
|
||||||
objects = dataset.get('objects', [])
|
|
||||||
|
|
||||||
img_name = info.get('name', '')
|
for index, json in enumerate(jsons):
|
||||||
width = info.get('width', 0)
|
|
||||||
height = info.get('height', 0)
|
|
||||||
depth = info.get('depth', 0)
|
|
||||||
note = info.get('note', '')
|
|
||||||
img = np.zeros(shape=(height, width), dtype=np.uint8)
|
|
||||||
|
|
||||||
objects = sorted(objects, key=lambda obj:obj.get('layer', 1))
|
if self.cache:
|
||||||
|
return
|
||||||
|
from_path = os.path.join(self.from_root, json)
|
||||||
|
self.message.emit(index+1, num_jsons, '{:>8d}/{:<8d} | Loading json:{}'.format(index+1, num_jsons, json))
|
||||||
|
with open(from_path, 'r') as f:
|
||||||
|
dataset = load(f)
|
||||||
|
info = dataset.get('info', {})
|
||||||
|
objects = dataset.get('objects', [])
|
||||||
|
|
||||||
for obj in objects:
|
img_name = info.get('name', '')
|
||||||
category = obj.get('category', 'unknow')
|
width = info.get('width', 0)
|
||||||
group = obj.get('group', '')
|
height = info.get('height', 0)
|
||||||
segmentation = obj.get('segmentation', [])
|
depth = info.get('depth', 0)
|
||||||
iscrowd = obj.get('iscrowd', 0)
|
note = info.get('note', '')
|
||||||
note = obj.get('note', '')
|
img = np.zeros(shape=(height, width), dtype=np.uint8)
|
||||||
area = obj.get('area', 0)
|
|
||||||
layer = obj.get('layer', 1)
|
|
||||||
bbox = obj.get('bbox', [])
|
|
||||||
segmentation = [(p[1], p[0]) for p in segmentation]
|
|
||||||
|
|
||||||
if self.is_segmentation and group != '':
|
objects = sorted(objects, key=lambda obj:obj.get('layer', 1))
|
||||||
mahotas.polygon.fill_polygon(segmentation, img, color=int(group))
|
|
||||||
else:
|
|
||||||
mahotas.polygon.fill_polygon(segmentation, img, color=self.category_dict.get(category, {}).get('index', 0))
|
|
||||||
img = Image.fromarray(img.astype(np.uint8), mode='P')
|
|
||||||
img.putpalette(self.cmap.flatten())
|
|
||||||
img.save(to_path)
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
for obj in objects:
|
||||||
|
category = obj.get('category', 'unknow')
|
||||||
|
group = obj.get('group', '')
|
||||||
|
segmentation = obj.get('segmentation', [])
|
||||||
|
iscrowd = obj.get('iscrowd', 0)
|
||||||
|
if iscrowd:
|
||||||
|
if not self.keep_crowd:
|
||||||
|
continue
|
||||||
|
note = obj.get('note', '')
|
||||||
|
area = obj.get('area', 0)
|
||||||
|
layer = obj.get('layer', 1)
|
||||||
|
bbox = obj.get('bbox', [])
|
||||||
|
segmentation = [(int(p[1]), int(p[0])) for p in segmentation]
|
||||||
|
|
||||||
|
if self.is_instance and group != '':
|
||||||
|
mahotas.polygon.fill_polygon(segmentation, img, color=int(group))
|
||||||
|
else:
|
||||||
|
mahotas.polygon.fill_polygon(segmentation, img, color=category_dict.get(category, {}).get('index', 0))
|
||||||
|
|
||||||
|
to_name = json[:-5]+'.png'
|
||||||
|
to_path = os.path.join(self.to_root, to_name)
|
||||||
|
try:
|
||||||
|
img = Image.fromarray(img.astype(np.uint8), mode='P')
|
||||||
|
|
||||||
|
img.putpalette(cmap.flatten())
|
||||||
|
img.save(to_path)
|
||||||
|
self.message.emit(None, None, ' ' * 18 + '| Saved png :{}'.format(to_name))
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
self.message.emit(None, None, ' ' * 18 + '| Save png :{} | error: {}'.format(to_name, e))
|
||||||
|
|
||||||
|
self.message.emit(None, None, '*** Finished! ***')
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
self.wait()
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Form implementation generated from reading ui file 'COCO_to_ISAT_dialog.ui'
|
# Form implementation generated from reading ui file '/home/super/PycharmProjects/ISAT_with_segment_anything/ui/COCO_to_ISAT_dialog.ui'
|
||||||
#
|
#
|
||||||
# Created by: PyQt5 UI code generator 5.15.7
|
# Created by: PyQt5 UI code generator 5.15.7
|
||||||
#
|
#
|
||||||
@ -15,7 +15,7 @@ class Ui_Dialog(object):
|
|||||||
def setupUi(self, Dialog):
|
def setupUi(self, Dialog):
|
||||||
Dialog.setObjectName("Dialog")
|
Dialog.setObjectName("Dialog")
|
||||||
Dialog.setWindowModality(QtCore.Qt.NonModal)
|
Dialog.setWindowModality(QtCore.Qt.NonModal)
|
||||||
Dialog.resize(600, 166)
|
Dialog.resize(600, 257)
|
||||||
font = QtGui.QFont()
|
font = QtGui.QFont()
|
||||||
font.setFamily("Times New Roman")
|
font.setFamily("Times New Roman")
|
||||||
font.setPointSize(12)
|
font.setPointSize(12)
|
||||||
@ -62,13 +62,18 @@ class Ui_Dialog(object):
|
|||||||
self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.widget_4)
|
self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.widget_4)
|
||||||
self.horizontalLayout_3.setContentsMargins(0, 0, 0, 0)
|
self.horizontalLayout_3.setContentsMargins(0, 0, 0, 0)
|
||||||
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
|
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.verticalLayout.addWidget(self.widget_4)
|
||||||
|
self.textBrowser = QtWidgets.QTextBrowser(Dialog)
|
||||||
|
font = QtGui.QFont()
|
||||||
|
font.setFamily("宋体")
|
||||||
|
self.textBrowser.setFont(font)
|
||||||
|
self.textBrowser.setLineWrapMode(QtWidgets.QTextEdit.NoWrap)
|
||||||
|
self.textBrowser.setObjectName("textBrowser")
|
||||||
|
self.verticalLayout.addWidget(self.textBrowser)
|
||||||
|
self.progressBar = QtWidgets.QProgressBar(Dialog)
|
||||||
|
self.progressBar.setProperty("value", 24)
|
||||||
|
self.progressBar.setObjectName("progressBar")
|
||||||
|
self.verticalLayout.addWidget(self.progressBar)
|
||||||
self.widget_2 = QtWidgets.QWidget(Dialog)
|
self.widget_2 = QtWidgets.QWidget(Dialog)
|
||||||
self.widget_2.setObjectName("widget_2")
|
self.widget_2.setObjectName("widget_2")
|
||||||
self.horizontalLayout = QtWidgets.QHBoxLayout(self.widget_2)
|
self.horizontalLayout = QtWidgets.QHBoxLayout(self.widget_2)
|
||||||
@ -78,8 +83,8 @@ class Ui_Dialog(object):
|
|||||||
self.label.setStyleSheet("color: rgb(255, 0, 0);")
|
self.label.setStyleSheet("color: rgb(255, 0, 0);")
|
||||||
self.label.setObjectName("label")
|
self.label.setObjectName("label")
|
||||||
self.horizontalLayout.addWidget(self.label)
|
self.horizontalLayout.addWidget(self.label)
|
||||||
spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||||
self.horizontalLayout.addItem(spacerItem2)
|
self.horizontalLayout.addItem(spacerItem1)
|
||||||
self.pushButton_cache = QtWidgets.QPushButton(self.widget_2)
|
self.pushButton_cache = QtWidgets.QPushButton(self.widget_2)
|
||||||
icon = QtGui.QIcon()
|
icon = QtGui.QIcon()
|
||||||
icon.addPixmap(QtGui.QPixmap(":/icons/icons/关闭_close-one.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
icon.addPixmap(QtGui.QPixmap(":/icons/icons/关闭_close-one.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>600</width>
|
<width>600</width>
|
||||||
<height>166</height>
|
<height>257</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="font">
|
<property name="font">
|
||||||
@ -140,29 +140,28 @@
|
|||||||
<property name="bottomMargin">
|
<property name="bottomMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer_3">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label_info">
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QTextBrowser" name="textBrowser">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>宋体</family>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="lineWrapMode">
|
||||||
|
<enum>QTextEdit::NoWrap</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QProgressBar" name="progressBar">
|
||||||
|
<property name="value">
|
||||||
|
<number>24</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QWidget" name="widget_2" native="true">
|
<widget class="QWidget" name="widget_2" native="true">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Form implementation generated from reading ui file 'ISAT_to_COCO_dialog.ui'
|
# Form implementation generated from reading ui file '/home/super/PycharmProjects/ISAT_with_segment_anything/ui/ISAT_to_COCO_dialog.ui'
|
||||||
#
|
#
|
||||||
# Created by: PyQt5 UI code generator 5.15.7
|
# Created by: PyQt5 UI code generator 5.15.7
|
||||||
#
|
#
|
||||||
@ -15,7 +15,7 @@ class Ui_Dialog(object):
|
|||||||
def setupUi(self, Dialog):
|
def setupUi(self, Dialog):
|
||||||
Dialog.setObjectName("Dialog")
|
Dialog.setObjectName("Dialog")
|
||||||
Dialog.setWindowModality(QtCore.Qt.NonModal)
|
Dialog.setWindowModality(QtCore.Qt.NonModal)
|
||||||
Dialog.resize(600, 137)
|
Dialog.resize(600, 226)
|
||||||
font = QtGui.QFont()
|
font = QtGui.QFont()
|
||||||
font.setFamily("Times New Roman")
|
font.setFamily("Times New Roman")
|
||||||
font.setPointSize(12)
|
font.setPointSize(12)
|
||||||
@ -46,18 +46,23 @@ class Ui_Dialog(object):
|
|||||||
self.lineEdit_label_root.setObjectName("lineEdit_label_root")
|
self.lineEdit_label_root.setObjectName("lineEdit_label_root")
|
||||||
self.gridLayout.addWidget(self.lineEdit_label_root, 2, 0, 1, 1)
|
self.gridLayout.addWidget(self.lineEdit_label_root, 2, 0, 1, 1)
|
||||||
self.verticalLayout.addWidget(self.widget)
|
self.verticalLayout.addWidget(self.widget)
|
||||||
|
self.textBrowser = QtWidgets.QTextBrowser(Dialog)
|
||||||
|
font = QtGui.QFont()
|
||||||
|
font.setFamily("宋体")
|
||||||
|
self.textBrowser.setFont(font)
|
||||||
|
self.textBrowser.setLineWrapMode(QtWidgets.QTextEdit.NoWrap)
|
||||||
|
self.textBrowser.setObjectName("textBrowser")
|
||||||
|
self.verticalLayout.addWidget(self.textBrowser)
|
||||||
self.widget_3 = QtWidgets.QWidget(Dialog)
|
self.widget_3 = QtWidgets.QWidget(Dialog)
|
||||||
self.widget_3.setObjectName("widget_3")
|
self.widget_3.setObjectName("widget_3")
|
||||||
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.widget_3)
|
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.widget_3)
|
||||||
self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
|
self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
|
||||||
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
|
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.verticalLayout.addWidget(self.widget_3)
|
||||||
|
self.progressBar = QtWidgets.QProgressBar(Dialog)
|
||||||
|
self.progressBar.setProperty("value", 24)
|
||||||
|
self.progressBar.setObjectName("progressBar")
|
||||||
|
self.verticalLayout.addWidget(self.progressBar)
|
||||||
self.widget_2 = QtWidgets.QWidget(Dialog)
|
self.widget_2 = QtWidgets.QWidget(Dialog)
|
||||||
self.widget_2.setObjectName("widget_2")
|
self.widget_2.setObjectName("widget_2")
|
||||||
self.horizontalLayout = QtWidgets.QHBoxLayout(self.widget_2)
|
self.horizontalLayout = QtWidgets.QHBoxLayout(self.widget_2)
|
||||||
@ -67,8 +72,8 @@ class Ui_Dialog(object):
|
|||||||
self.label.setStyleSheet("color: rgb(255, 0, 0);")
|
self.label.setStyleSheet("color: rgb(255, 0, 0);")
|
||||||
self.label.setObjectName("label")
|
self.label.setObjectName("label")
|
||||||
self.horizontalLayout.addWidget(self.label)
|
self.horizontalLayout.addWidget(self.label)
|
||||||
spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||||
self.horizontalLayout.addItem(spacerItem1)
|
self.horizontalLayout.addItem(spacerItem)
|
||||||
self.pushButton_cache = QtWidgets.QPushButton(self.widget_2)
|
self.pushButton_cache = QtWidgets.QPushButton(self.widget_2)
|
||||||
icon = QtGui.QIcon()
|
icon = QtGui.QIcon()
|
||||||
icon.addPixmap(QtGui.QPixmap(":/icons/icons/关闭_close-one.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
icon.addPixmap(QtGui.QPixmap(":/icons/icons/关闭_close-one.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||||
@ -93,6 +98,11 @@ class Ui_Dialog(object):
|
|||||||
self.pushButton_label_root.setText(_translate("Dialog", "Jsons root"))
|
self.pushButton_label_root.setText(_translate("Dialog", "Jsons root"))
|
||||||
self.lineEdit_save_path.setPlaceholderText(_translate("Dialog", "COCO json save path"))
|
self.lineEdit_save_path.setPlaceholderText(_translate("Dialog", "COCO json save path"))
|
||||||
self.lineEdit_label_root.setPlaceholderText(_translate("Dialog", "ISAT jsons root"))
|
self.lineEdit_label_root.setPlaceholderText(_translate("Dialog", "ISAT jsons root"))
|
||||||
|
self.textBrowser.setHtml(_translate("Dialog", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
|
||||||
|
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
|
||||||
|
"p, li { white-space: pre-wrap; }\n"
|
||||||
|
"</style></head><body style=\" font-family:\'宋体\'; font-size:12pt; font-weight:400; font-style:normal;\">\n"
|
||||||
|
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:\'Times New Roman\';\"><br /></p></body></html>"))
|
||||||
self.label.setText(_translate("Dialog", "Convert ISAT jsons to COCO json.The layer attr will be lost."))
|
self.label.setText(_translate("Dialog", "Convert ISAT jsons to COCO json.The layer attr will be lost."))
|
||||||
self.pushButton_cache.setText(_translate("Dialog", "cache"))
|
self.pushButton_cache.setText(_translate("Dialog", "cache"))
|
||||||
self.pushButton_apply.setText(_translate("Dialog", "convert"))
|
self.pushButton_apply.setText(_translate("Dialog", "convert"))
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>600</width>
|
<width>600</width>
|
||||||
<height>137</height>
|
<height>226</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="font">
|
<property name="font">
|
||||||
@ -87,6 +87,25 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QTextBrowser" name="textBrowser">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>宋体</family>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="lineWrapMode">
|
||||||
|
<enum>QTextEdit::NoWrap</enum>
|
||||||
|
</property>
|
||||||
|
<property name="html">
|
||||||
|
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||||
|
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||||
|
p, li { white-space: pre-wrap; }
|
||||||
|
</style></head><body style=" font-family:'宋体'; font-size:12pt; font-weight:400; font-style:normal;">
|
||||||
|
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Times New Roman';"><br /></p></body></html></string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QWidget" name="widget_3" native="true">
|
<widget class="QWidget" name="widget_3" native="true">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
@ -102,29 +121,16 @@
|
|||||||
<property name="bottomMargin">
|
<property name="bottomMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer_2">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label_info">
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QProgressBar" name="progressBar">
|
||||||
|
<property name="value">
|
||||||
|
<number>24</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QWidget" name="widget_2" native="true">
|
<widget class="QWidget" name="widget_2" native="true">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Form implementation generated from reading ui file 'ISAT_to_VOC_dialog.ui'
|
# Form implementation generated from reading ui file '/home/super/PycharmProjects/ISAT_with_segment_anything/ui/ISAT_to_VOC_dialog.ui'
|
||||||
#
|
#
|
||||||
# Created by: PyQt5 UI code generator 5.15.7
|
# Created by: PyQt5 UI code generator 5.15.7
|
||||||
#
|
#
|
||||||
@ -15,7 +15,7 @@ class Ui_Dialog(object):
|
|||||||
def setupUi(self, Dialog):
|
def setupUi(self, Dialog):
|
||||||
Dialog.setObjectName("Dialog")
|
Dialog.setObjectName("Dialog")
|
||||||
Dialog.setWindowModality(QtCore.Qt.NonModal)
|
Dialog.setWindowModality(QtCore.Qt.NonModal)
|
||||||
Dialog.resize(600, 173)
|
Dialog.resize(600, 251)
|
||||||
font = QtGui.QFont()
|
font = QtGui.QFont()
|
||||||
font.setFamily("Times New Roman")
|
font.setFamily("Times New Roman")
|
||||||
font.setPointSize(12)
|
font.setPointSize(12)
|
||||||
@ -29,20 +29,9 @@ class Ui_Dialog(object):
|
|||||||
self.gridLayout = QtWidgets.QGridLayout(self.widget)
|
self.gridLayout = QtWidgets.QGridLayout(self.widget)
|
||||||
self.gridLayout.setContentsMargins(0, 0, 0, 0)
|
self.gridLayout.setContentsMargins(0, 0, 0, 0)
|
||||||
self.gridLayout.setObjectName("gridLayout")
|
self.gridLayout.setObjectName("gridLayout")
|
||||||
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.pushButton_save_root = QtWidgets.QPushButton(self.widget)
|
self.pushButton_save_root = QtWidgets.QPushButton(self.widget)
|
||||||
self.pushButton_save_root.setObjectName("pushButton_save_root")
|
self.pushButton_save_root.setObjectName("pushButton_save_root")
|
||||||
self.gridLayout.addWidget(self.pushButton_save_root, 3, 1, 1, 1)
|
self.gridLayout.addWidget(self.pushButton_save_root, 3, 1, 1, 1)
|
||||||
self.checkBox_is_instance = QtWidgets.QCheckBox(self.widget)
|
|
||||||
self.checkBox_is_instance.setToolTip("")
|
|
||||||
self.checkBox_is_instance.setAccessibleName("")
|
|
||||||
self.checkBox_is_instance.setAccessibleDescription("")
|
|
||||||
self.checkBox_is_instance.setObjectName("checkBox_is_instance")
|
|
||||||
self.gridLayout.addWidget(self.checkBox_is_instance, 4, 1, 1, 1)
|
|
||||||
self.lineEdit_label_root = QtWidgets.QLineEdit(self.widget)
|
self.lineEdit_label_root = QtWidgets.QLineEdit(self.widget)
|
||||||
self.lineEdit_label_root.setEnabled(True)
|
self.lineEdit_label_root.setEnabled(True)
|
||||||
self.lineEdit_label_root.setReadOnly(True)
|
self.lineEdit_label_root.setReadOnly(True)
|
||||||
@ -51,28 +40,41 @@ class Ui_Dialog(object):
|
|||||||
self.pushButton_label_root = QtWidgets.QPushButton(self.widget)
|
self.pushButton_label_root = QtWidgets.QPushButton(self.widget)
|
||||||
self.pushButton_label_root.setObjectName("pushButton_label_root")
|
self.pushButton_label_root.setObjectName("pushButton_label_root")
|
||||||
self.gridLayout.addWidget(self.pushButton_label_root, 2, 1, 1, 1)
|
self.gridLayout.addWidget(self.pushButton_label_root, 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.verticalLayout.addWidget(self.widget)
|
self.verticalLayout.addWidget(self.widget)
|
||||||
self.widget_process = QtWidgets.QWidget(Dialog)
|
self.widget_3 = QtWidgets.QWidget(Dialog)
|
||||||
self.widget_process.setObjectName("widget_process")
|
self.widget_3.setObjectName("widget_3")
|
||||||
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.widget_process)
|
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.widget_3)
|
||||||
self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
|
self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
|
||||||
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
|
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
|
||||||
self.progressBar = QtWidgets.QProgressBar(self.widget_process)
|
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||||
|
self.horizontalLayout_2.addItem(spacerItem)
|
||||||
|
self.checkBox_is_instance = QtWidgets.QCheckBox(self.widget_3)
|
||||||
|
self.checkBox_is_instance.setToolTip("")
|
||||||
|
self.checkBox_is_instance.setAccessibleName("")
|
||||||
|
self.checkBox_is_instance.setAccessibleDescription("")
|
||||||
|
self.checkBox_is_instance.setObjectName("checkBox_is_instance")
|
||||||
|
self.horizontalLayout_2.addWidget(self.checkBox_is_instance)
|
||||||
|
self.checkBox_keep_crowd = QtWidgets.QCheckBox(self.widget_3)
|
||||||
|
self.checkBox_keep_crowd.setObjectName("checkBox_keep_crowd")
|
||||||
|
self.horizontalLayout_2.addWidget(self.checkBox_keep_crowd)
|
||||||
|
self.verticalLayout.addWidget(self.widget_3)
|
||||||
|
self.textBrowser = QtWidgets.QTextBrowser(Dialog)
|
||||||
|
font = QtGui.QFont()
|
||||||
|
font.setFamily("宋体")
|
||||||
|
font.setPointSize(12)
|
||||||
|
self.textBrowser.setFont(font)
|
||||||
|
self.textBrowser.setLineWrapMode(QtWidgets.QTextEdit.NoWrap)
|
||||||
|
self.textBrowser.setObjectName("textBrowser")
|
||||||
|
self.verticalLayout.addWidget(self.textBrowser)
|
||||||
|
self.progressBar = QtWidgets.QProgressBar(Dialog)
|
||||||
self.progressBar.setProperty("value", 0)
|
self.progressBar.setProperty("value", 0)
|
||||||
self.progressBar.setObjectName("progressBar")
|
self.progressBar.setObjectName("progressBar")
|
||||||
self.horizontalLayout_2.addWidget(self.progressBar)
|
self.verticalLayout.addWidget(self.progressBar)
|
||||||
self.current_num = QtWidgets.QLabel(self.widget_process)
|
|
||||||
self.current_num.setText("")
|
|
||||||
self.current_num.setObjectName("current_num")
|
|
||||||
self.horizontalLayout_2.addWidget(self.current_num)
|
|
||||||
self.label_3 = QtWidgets.QLabel(self.widget_process)
|
|
||||||
self.label_3.setObjectName("label_3")
|
|
||||||
self.horizontalLayout_2.addWidget(self.label_3)
|
|
||||||
self.all_num = QtWidgets.QLabel(self.widget_process)
|
|
||||||
self.all_num.setText("")
|
|
||||||
self.all_num.setObjectName("all_num")
|
|
||||||
self.horizontalLayout_2.addWidget(self.all_num)
|
|
||||||
self.verticalLayout.addWidget(self.widget_process)
|
|
||||||
self.widget_2 = QtWidgets.QWidget(Dialog)
|
self.widget_2 = QtWidgets.QWidget(Dialog)
|
||||||
self.widget_2.setObjectName("widget_2")
|
self.widget_2.setObjectName("widget_2")
|
||||||
self.horizontalLayout = QtWidgets.QHBoxLayout(self.widget_2)
|
self.horizontalLayout = QtWidgets.QHBoxLayout(self.widget_2)
|
||||||
@ -82,8 +84,8 @@ class Ui_Dialog(object):
|
|||||||
self.label.setStyleSheet("color: rgb(255, 0, 0);")
|
self.label.setStyleSheet("color: rgb(255, 0, 0);")
|
||||||
self.label.setObjectName("label")
|
self.label.setObjectName("label")
|
||||||
self.horizontalLayout.addWidget(self.label)
|
self.horizontalLayout.addWidget(self.label)
|
||||||
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||||
self.horizontalLayout.addItem(spacerItem)
|
self.horizontalLayout.addItem(spacerItem1)
|
||||||
self.pushButton_cache = QtWidgets.QPushButton(self.widget_2)
|
self.pushButton_cache = QtWidgets.QPushButton(self.widget_2)
|
||||||
icon = QtGui.QIcon()
|
icon = QtGui.QIcon()
|
||||||
icon.addPixmap(QtGui.QPixmap(":/icons/icons/关闭_close-one.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
icon.addPixmap(QtGui.QPixmap(":/icons/icons/关闭_close-one.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||||
@ -104,13 +106,17 @@ class Ui_Dialog(object):
|
|||||||
def retranslateUi(self, Dialog):
|
def retranslateUi(self, Dialog):
|
||||||
_translate = QtCore.QCoreApplication.translate
|
_translate = QtCore.QCoreApplication.translate
|
||||||
Dialog.setWindowTitle(_translate("Dialog", "ISAT to VOC png"))
|
Dialog.setWindowTitle(_translate("Dialog", "ISAT to VOC png"))
|
||||||
self.lineEdit_save_root.setPlaceholderText(_translate("Dialog", "png save root"))
|
|
||||||
self.pushButton_save_root.setText(_translate("Dialog", "Save root"))
|
self.pushButton_save_root.setText(_translate("Dialog", "Save root"))
|
||||||
self.checkBox_is_instance.setText(_translate("Dialog", "Is Instance"))
|
|
||||||
self.lineEdit_label_root.setPlaceholderText(_translate("Dialog", "ISAT annotations root"))
|
self.lineEdit_label_root.setPlaceholderText(_translate("Dialog", "ISAT annotations root"))
|
||||||
self.pushButton_label_root.setText(_translate("Dialog", "Label root"))
|
self.pushButton_label_root.setText(_translate("Dialog", "Label root"))
|
||||||
self.label_3.setAccessibleName(_translate("Dialog", "aaa"))
|
self.lineEdit_save_root.setPlaceholderText(_translate("Dialog", "png save root"))
|
||||||
self.label_3.setText(_translate("Dialog", "/"))
|
self.checkBox_is_instance.setText(_translate("Dialog", "Is instance"))
|
||||||
|
self.checkBox_keep_crowd.setText(_translate("Dialog", "Keep crowd"))
|
||||||
|
self.textBrowser.setHtml(_translate("Dialog", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
|
||||||
|
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
|
||||||
|
"p, li { white-space: pre-wrap; }\n"
|
||||||
|
"</style></head><body style=\" font-family:\'宋体\'; font-size:12pt; font-weight:400; font-style:normal;\">\n"
|
||||||
|
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><br /></p></body></html>"))
|
||||||
self.label.setText(_translate("Dialog", "Convert ISAT annotations to VOC png."))
|
self.label.setText(_translate("Dialog", "Convert ISAT annotations to VOC png."))
|
||||||
self.pushButton_cache.setText(_translate("Dialog", "cache"))
|
self.pushButton_cache.setText(_translate("Dialog", "cache"))
|
||||||
self.pushButton_apply.setText(_translate("Dialog", "convert"))
|
self.pushButton_apply.setText(_translate("Dialog", "convert"))
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>600</width>
|
<width>600</width>
|
||||||
<height>173</height>
|
<height>251</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="font">
|
<property name="font">
|
||||||
@ -44,19 +44,6 @@
|
|||||||
<property name="bottomMargin">
|
<property name="bottomMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item row="3" column="0">
|
|
||||||
<widget class="QLineEdit" name="lineEdit_save_root">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="readOnly">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="placeholderText">
|
|
||||||
<string>png save root</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="1">
|
<item row="3" column="1">
|
||||||
<widget class="QPushButton" name="pushButton_save_root">
|
<widget class="QPushButton" name="pushButton_save_root">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@ -64,22 +51,6 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="1">
|
|
||||||
<widget class="QCheckBox" name="checkBox_is_instance">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="accessibleName">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="accessibleDescription">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Is Instance</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
<item row="2" column="0">
|
||||||
<widget class="QLineEdit" name="lineEdit_label_root">
|
<widget class="QLineEdit" name="lineEdit_label_root">
|
||||||
<property name="enabled">
|
<property name="enabled">
|
||||||
@ -100,11 +71,24 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLineEdit" name="lineEdit_save_root">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="placeholderText">
|
||||||
|
<string>png save root</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QWidget" name="widget_process" native="true">
|
<widget class="QWidget" name="widget_3" native="true">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
@ -119,39 +103,71 @@
|
|||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QProgressBar" name="progressBar">
|
<spacer name="horizontalSpacer_2">
|
||||||
<property name="value">
|
<property name="orientation">
|
||||||
<number>0</number>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="current_num">
|
<widget class="QCheckBox" name="checkBox_is_instance">
|
||||||
<property name="text">
|
<property name="toolTip">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label_3">
|
|
||||||
<property name="accessibleName">
|
<property name="accessibleName">
|
||||||
<string>aaa</string>
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="accessibleDescription">
|
||||||
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>/</string>
|
<string>Is instance</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="all_num">
|
<widget class="QCheckBox" name="checkBox_keep_crowd">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string>Keep crowd</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QTextBrowser" name="textBrowser">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>宋体</family>
|
||||||
|
<pointsize>12</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="lineWrapMode">
|
||||||
|
<enum>QTextEdit::NoWrap</enum>
|
||||||
|
</property>
|
||||||
|
<property name="html">
|
||||||
|
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||||
|
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||||
|
p, li { white-space: pre-wrap; }
|
||||||
|
</style></head><body style=" font-family:'宋体'; font-size:12pt; font-weight:400; font-style:normal;">
|
||||||
|
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html></string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QProgressBar" name="progressBar">
|
||||||
|
<property name="value">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QWidget" name="widget_2" native="true">
|
<widget class="QWidget" name="widget_2" native="true">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
@ -25,12 +25,24 @@ class Ui_Dialog(object):
|
|||||||
self.widget.setObjectName("widget")
|
self.widget.setObjectName("widget")
|
||||||
self.verticalLayout = QtWidgets.QVBoxLayout(self.widget)
|
self.verticalLayout = QtWidgets.QVBoxLayout(self.widget)
|
||||||
self.verticalLayout.setObjectName("verticalLayout")
|
self.verticalLayout.setObjectName("verticalLayout")
|
||||||
self.label = QtWidgets.QLabel(self.widget)
|
self.widget_2 = QtWidgets.QWidget(self.widget)
|
||||||
|
self.widget_2.setObjectName("widget_2")
|
||||||
|
self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.widget_2)
|
||||||
|
self.horizontalLayout_3.setContentsMargins(0, 0, 0, 0)
|
||||||
|
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
|
||||||
|
self.label = QtWidgets.QLabel(self.widget_2)
|
||||||
|
self.label.setMaximumSize(QtCore.QSize(80, 16777215))
|
||||||
font = QtGui.QFont()
|
font = QtGui.QFont()
|
||||||
font.setPointSize(20)
|
font.setPointSize(20)
|
||||||
self.label.setFont(font)
|
self.label.setFont(font)
|
||||||
self.label.setObjectName("label")
|
self.label.setObjectName("label")
|
||||||
self.verticalLayout.addWidget(self.label)
|
self.horizontalLayout_3.addWidget(self.label)
|
||||||
|
self.label_config_file = QtWidgets.QLabel(self.widget_2)
|
||||||
|
self.label_config_file.setText("")
|
||||||
|
self.label_config_file.setAlignment(QtCore.Qt.AlignBottom|QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft)
|
||||||
|
self.label_config_file.setObjectName("label_config_file")
|
||||||
|
self.horizontalLayout_3.addWidget(self.label_config_file)
|
||||||
|
self.verticalLayout.addWidget(self.widget_2)
|
||||||
self.category_list_widget = QtWidgets.QListWidget(self.widget)
|
self.category_list_widget = QtWidgets.QListWidget(self.widget)
|
||||||
self.category_list_widget.setObjectName("category_list_widget")
|
self.category_list_widget.setObjectName("category_list_widget")
|
||||||
self.verticalLayout.addWidget(self.category_list_widget)
|
self.verticalLayout.addWidget(self.category_list_widget)
|
||||||
|
@ -24,15 +24,49 @@
|
|||||||
<widget class="QWidget" name="widget" native="true">
|
<widget class="QWidget" name="widget" native="true">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label">
|
<widget class="QWidget" name="widget_2" native="true">
|
||||||
<property name="font">
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
<font>
|
<property name="leftMargin">
|
||||||
<pointsize>20</pointsize>
|
<number>0</number>
|
||||||
</font>
|
</property>
|
||||||
</property>
|
<property name="topMargin">
|
||||||
<property name="text">
|
<number>0</number>
|
||||||
<string>Label</string>
|
</property>
|
||||||
</property>
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>80</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>20</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Label</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_config_file">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
@ -71,7 +105,7 @@
|
|||||||
<string>Add new label</string>
|
<string>Add new label</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../icons.qrc">
|
<iconset>
|
||||||
<normaloff>:/icons/icons/书签_bookmark-one.svg</normaloff>:/icons/icons/书签_bookmark-one.svg</iconset>
|
<normaloff>:/icons/icons/书签_bookmark-one.svg</normaloff>:/icons/icons/书签_bookmark-one.svg</iconset>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
@ -86,7 +120,7 @@
|
|||||||
<string>Import</string>
|
<string>Import</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../icons.qrc">
|
<iconset>
|
||||||
<normaloff>:/icons/icons/传入3_afferent-three.svg</normaloff>:/icons/icons/传入3_afferent-three.svg</iconset>
|
<normaloff>:/icons/icons/传入3_afferent-three.svg</normaloff>:/icons/icons/传入3_afferent-three.svg</iconset>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
@ -97,7 +131,7 @@
|
|||||||
<string>Export</string>
|
<string>Export</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../icons.qrc">
|
<iconset>
|
||||||
<normaloff>:/icons/icons/传出3_efferent-three.svg</normaloff>:/icons/icons/传出3_efferent-three.svg</iconset>
|
<normaloff>:/icons/icons/传出3_efferent-three.svg</normaloff>:/icons/icons/传出3_efferent-three.svg</iconset>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
@ -121,7 +155,7 @@
|
|||||||
<string>Cache</string>
|
<string>Cache</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../icons.qrc">
|
<iconset>
|
||||||
<normaloff>:/icons/icons/关闭_close-one.svg</normaloff>:/icons/icons/关闭_close-one.svg</iconset>
|
<normaloff>:/icons/icons/关闭_close-one.svg</normaloff>:/icons/icons/关闭_close-one.svg</iconset>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
@ -132,7 +166,7 @@
|
|||||||
<string>Apply</string>
|
<string>Apply</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../icons.qrc">
|
<iconset>
|
||||||
<normaloff>:/icons/icons/校验_check-one.svg</normaloff>:/icons/icons/校验_check-one.svg</iconset>
|
<normaloff>:/icons/icons/校验_check-one.svg</normaloff>:/icons/icons/校验_check-one.svg</iconset>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# @Author : LG
|
# @Author : LG
|
||||||
|
|
||||||
from PyQt5 import QtWidgets, QtCore, QtGui
|
from PyQt5 import QtWidgets, QtCore
|
||||||
from ui.COCO_to_ISAT_dialog import Ui_Dialog
|
from ui.COCO_to_ISAT_dialog import Ui_Dialog
|
||||||
from tools.toCOCO import COCOConverter
|
from tools.fromCOCO import FROMCOCO
|
||||||
|
|
||||||
|
|
||||||
class COCOtoISATDialog(QtWidgets.QDialog, Ui_Dialog):
|
class COCOtoISATDialog(QtWidgets.QDialog, Ui_Dialog):
|
||||||
@ -13,15 +13,20 @@ class COCOtoISATDialog(QtWidgets.QDialog, Ui_Dialog):
|
|||||||
self.mainwindow = mainwindow
|
self.mainwindow = mainwindow
|
||||||
self.label_path = None
|
self.label_path = None
|
||||||
self.save_root = None
|
self.save_root = None
|
||||||
self.pause = False
|
|
||||||
|
|
||||||
self.setWindowModality(QtCore.Qt.WindowModality.WindowModal)
|
self.setWindowModality(QtCore.Qt.WindowModality.WindowModal)
|
||||||
|
|
||||||
|
self.converter = FROMCOCO()
|
||||||
|
self.converter.message.connect(self.print_message)
|
||||||
|
|
||||||
self.init_connect()
|
self.init_connect()
|
||||||
|
|
||||||
def reset_gui(self):
|
def reset_gui(self):
|
||||||
self.lineEdit_label_path.clear()
|
self.lineEdit_label_path.clear()
|
||||||
self.lineEdit_save_root.clear()
|
self.lineEdit_save_root.clear()
|
||||||
|
self.checkBox_keepcrowd.setChecked(False)
|
||||||
|
self.progressBar.reset()
|
||||||
|
self.textBrowser.clear()
|
||||||
|
|
||||||
def _label_path(self):
|
def _label_path(self):
|
||||||
path, suffix = QtWidgets.QFileDialog.getOpenFileName(self, caption='COCO json save file',
|
path, suffix = QtWidgets.QFileDialog.getOpenFileName(self, caption='COCO json save file',
|
||||||
@ -43,24 +48,38 @@ class COCOtoISATDialog(QtWidgets.QDialog, Ui_Dialog):
|
|||||||
self.lineEdit_save_root.clear()
|
self.lineEdit_save_root.clear()
|
||||||
|
|
||||||
def cache(self):
|
def cache(self):
|
||||||
self.pause = True
|
self.converter.cache = True
|
||||||
self.close()
|
self.close()
|
||||||
|
|
||||||
def apply(self):
|
def apply(self):
|
||||||
self.pause = False
|
|
||||||
if self.label_path is None or self.save_root is None:
|
if self.label_path is None or self.save_root is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
converter = COCOConverter()
|
|
||||||
|
|
||||||
self.pushButton_label_path.setEnabled(False)
|
self.pushButton_label_path.setEnabled(False)
|
||||||
self.pushButton_save_root.setEnabled(False)
|
self.pushButton_save_root.setEnabled(False)
|
||||||
self.label_info.setText('Convering...')
|
self.checkBox_keepcrowd.setEnabled(False)
|
||||||
converter.convert_from_coco(self.label_path, self.save_root, keep_crowd=self.checkBox_keepcrowd.isChecked())
|
self.pushButton_apply.setEnabled((False))
|
||||||
self.label_info.setText('Finish!!!')
|
|
||||||
|
self.progressBar.reset()
|
||||||
|
self.textBrowser.clear()
|
||||||
|
self.converter.cache = False
|
||||||
|
self.converter.coco_json_path = self.label_path
|
||||||
|
self.converter.to_root = self.save_root
|
||||||
|
self.converter.keep_crowd = self.checkBox_keepcrowd.isChecked()
|
||||||
|
self.converter.run()
|
||||||
|
|
||||||
self.pushButton_label_path.setEnabled(True)
|
self.pushButton_label_path.setEnabled(True)
|
||||||
self.pushButton_save_root.setEnabled(True)
|
self.pushButton_save_root.setEnabled(True)
|
||||||
|
self.checkBox_keepcrowd.setEnabled(True)
|
||||||
|
self.pushButton_apply.setEnabled((True))
|
||||||
|
|
||||||
|
def print_message(self, index, all, message):
|
||||||
|
if all:
|
||||||
|
self.progressBar.setMaximum(all)
|
||||||
|
if index:
|
||||||
|
self.progressBar.setValue(index)
|
||||||
|
if message:
|
||||||
|
self.textBrowser.append(message)
|
||||||
|
|
||||||
def init_connect(self):
|
def init_connect(self):
|
||||||
self.pushButton_label_path.clicked.connect(self._label_path)
|
self.pushButton_label_path.clicked.connect(self._label_path)
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
from PyQt5 import QtWidgets, QtCore, QtGui
|
from PyQt5 import QtWidgets, QtCore, QtGui
|
||||||
from ui.ISAT_to_COCO_dialog import Ui_Dialog
|
from ui.ISAT_to_COCO_dialog import Ui_Dialog
|
||||||
from tools.toCOCO import COCOConverter
|
from tools.toCOCO import TOCOCO
|
||||||
|
|
||||||
|
|
||||||
class ISATtoCOCODialog(QtWidgets.QDialog, Ui_Dialog):
|
class ISATtoCOCODialog(QtWidgets.QDialog, Ui_Dialog):
|
||||||
@ -13,15 +13,18 @@ class ISATtoCOCODialog(QtWidgets.QDialog, Ui_Dialog):
|
|||||||
self.mainwindow = mainwindow
|
self.mainwindow = mainwindow
|
||||||
self.label_root = None
|
self.label_root = None
|
||||||
self.save_path = None
|
self.save_path = None
|
||||||
self.pause = False
|
|
||||||
|
self.converter = TOCOCO()
|
||||||
|
self.converter.message.connect(self.print_message)
|
||||||
|
|
||||||
self.setWindowModality(QtCore.Qt.WindowModality.WindowModal)
|
self.setWindowModality(QtCore.Qt.WindowModality.WindowModal)
|
||||||
|
|
||||||
self.init_connect()
|
self.init_connect()
|
||||||
|
|
||||||
def reset_gui(self):
|
def reset_gui(self):
|
||||||
self.lineEdit_label_root.clear()
|
self.lineEdit_label_root.clear()
|
||||||
self.lineEdit_save_path.clear()
|
self.lineEdit_save_path.clear()
|
||||||
|
self.textBrowser.clear()
|
||||||
|
self.progressBar.reset()
|
||||||
|
|
||||||
def _label_root(self):
|
def _label_root(self):
|
||||||
dir = QtWidgets.QFileDialog.getExistingDirectory(self, caption='ISAT jsons root')
|
dir = QtWidgets.QFileDialog.getExistingDirectory(self, caption='ISAT jsons root')
|
||||||
@ -42,25 +45,35 @@ class ISATtoCOCODialog(QtWidgets.QDialog, Ui_Dialog):
|
|||||||
self.lineEdit_save_path.clear()
|
self.lineEdit_save_path.clear()
|
||||||
|
|
||||||
def cache(self):
|
def cache(self):
|
||||||
self.pause = True
|
self.converter.cache = True
|
||||||
self.close()
|
self.close()
|
||||||
|
|
||||||
def apply(self):
|
def apply(self):
|
||||||
self.pause = False
|
|
||||||
if self.label_root is None or self.save_path is None:
|
if self.label_root is None or self.save_path is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
converter = COCOConverter()
|
|
||||||
|
|
||||||
self.pushButton_label_root.setEnabled(False)
|
self.pushButton_label_root.setEnabled(False)
|
||||||
self.pushButton_save_path.setEnabled(False)
|
self.pushButton_save_path.setEnabled(False)
|
||||||
self.label_info.setText('Convering...')
|
self.pushButton_apply.setEnabled(False)
|
||||||
|
|
||||||
converter.convert_to_coco(self.label_root, self.save_path)
|
self.progressBar.reset()
|
||||||
self.label_info.setText('Finish!!!')
|
self.textBrowser.clear()
|
||||||
|
self.converter.cache = False
|
||||||
|
self.converter.isat_json_root = self.label_root
|
||||||
|
self.converter.to_path = self.save_path
|
||||||
|
self.converter.start()
|
||||||
|
|
||||||
self.pushButton_label_root.setEnabled(True)
|
self.pushButton_label_root.setEnabled(True)
|
||||||
self.pushButton_save_path.setEnabled(True)
|
self.pushButton_save_path.setEnabled(True)
|
||||||
|
self.pushButton_apply.setEnabled(True)
|
||||||
|
|
||||||
|
def print_message(self, index, all, message):
|
||||||
|
if index:
|
||||||
|
self.progressBar.setValue(index)
|
||||||
|
if all:
|
||||||
|
self.progressBar.setMaximum(all)
|
||||||
|
if message:
|
||||||
|
self.textBrowser.append(message)
|
||||||
|
|
||||||
def init_connect(self):
|
def init_connect(self):
|
||||||
self.pushButton_label_root.clicked.connect(self._label_root)
|
self.pushButton_label_root.clicked.connect(self._label_root)
|
||||||
|
@ -3,7 +3,8 @@
|
|||||||
|
|
||||||
from PyQt5 import QtWidgets, QtCore, QtGui
|
from PyQt5 import QtWidgets, QtCore, QtGui
|
||||||
from ui.ISAT_to_VOC_dialog import Ui_Dialog
|
from ui.ISAT_to_VOC_dialog import Ui_Dialog
|
||||||
from tools.toVOC import VOCConverter
|
from tools.toVOC import TOVOC
|
||||||
|
from configs import load_config
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
|
||||||
@ -14,16 +15,21 @@ class ISATtoVOCDialog(QtWidgets.QDialog, Ui_Dialog):
|
|||||||
self.mainwindow = mainwindow
|
self.mainwindow = mainwindow
|
||||||
self.label_root = None
|
self.label_root = None
|
||||||
self.save_root = None
|
self.save_root = None
|
||||||
self.pause = False
|
|
||||||
|
self.converter = TOVOC()
|
||||||
|
self.converter.message.connect(self.print_message)
|
||||||
|
|
||||||
self.setWindowModality(QtCore.Qt.WindowModality.WindowModal)
|
self.setWindowModality(QtCore.Qt.WindowModality.WindowModal)
|
||||||
|
|
||||||
self.init_connect()
|
self.init_connect()
|
||||||
|
|
||||||
def reset_gui(self):
|
def reset_gui(self):
|
||||||
self.widget_process.setVisible(False)
|
|
||||||
self.lineEdit_label_root.clear()
|
self.lineEdit_label_root.clear()
|
||||||
self.lineEdit_save_root.clear()
|
self.lineEdit_save_root.clear()
|
||||||
|
self.checkBox_is_instance.setChecked(False)
|
||||||
|
self.checkBox_keep_crowd.setChecked(False)
|
||||||
|
self.textBrowser.clear()
|
||||||
|
self.progressBar.reset()
|
||||||
|
|
||||||
def _label_root(self):
|
def _label_root(self):
|
||||||
dir = QtWidgets.QFileDialog.getExistingDirectory(self)
|
dir = QtWidgets.QFileDialog.getExistingDirectory(self)
|
||||||
@ -42,11 +48,10 @@ class ISATtoVOCDialog(QtWidgets.QDialog, Ui_Dialog):
|
|||||||
self.lineEdit_save_root.clear()
|
self.lineEdit_save_root.clear()
|
||||||
|
|
||||||
def cache(self):
|
def cache(self):
|
||||||
self.pause = True
|
self.converter.cache = True
|
||||||
self.close()
|
self.close()
|
||||||
|
|
||||||
def apply(self):
|
def apply(self):
|
||||||
self.pause = False
|
|
||||||
if self.label_root is None or self.save_root is None:
|
if self.label_root is None or self.save_root is None:
|
||||||
return
|
return
|
||||||
# 语义分割,保存类别文件
|
# 语义分割,保存类别文件
|
||||||
@ -55,29 +60,38 @@ class ISATtoVOCDialog(QtWidgets.QDialog, Ui_Dialog):
|
|||||||
for index, label in enumerate(self.mainwindow.cfg.get('label', [])):
|
for index, label in enumerate(self.mainwindow.cfg.get('label', [])):
|
||||||
f.write('{} {}\n'.format(label.get('name'), index))
|
f.write('{} {}\n'.format(label.get('name'), index))
|
||||||
|
|
||||||
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)
|
self.pushButton_label_root.setEnabled(False)
|
||||||
self.pushButton_save_root.setEnabled(False)
|
self.pushButton_save_root.setEnabled(False)
|
||||||
self.checkBox_is_instance.setEnabled(False)
|
self.checkBox_is_instance.setEnabled(False)
|
||||||
|
self.checkBox_keep_crowd.setEnabled(False)
|
||||||
|
self.pushButton_apply.setEnabled(False)
|
||||||
|
|
||||||
self.widget_process.setVisible(True)
|
self.progressBar.reset()
|
||||||
self.progressBar.setMaximum(len(jsons))
|
self.textBrowser.clear()
|
||||||
self.all_num.setText('{}'.format(len(jsons)))
|
self.converter.cache = False
|
||||||
|
if os.path.exists(os.path.join(self.label_root, 'isat.yaml')):
|
||||||
for index, json in enumerate(jsons):
|
self.converter.cfg = load_config(os.path.join(self.label_root, 'isat.yaml'))
|
||||||
if self.pause:
|
else:
|
||||||
break
|
self.converter.cfg = self.mainwindow.cfg
|
||||||
label_path = os.path.join(self.label_root, json)
|
self.converter.from_root = self.label_root
|
||||||
save_path = os.path.join(self.save_root, json[:-5]+'.png')
|
self.converter.to_root = self.save_root
|
||||||
converter.convert(label_path, save_path)
|
self.converter.is_instance = self.checkBox_is_instance.isChecked()
|
||||||
self.progressBar.setValue(index+1)
|
self.converter.keep_crowd = self.checkBox_keep_crowd.isChecked()
|
||||||
self.current_num.setText('{}'.format(index+1))
|
self.converter.start()
|
||||||
|
|
||||||
self.pushButton_label_root.setEnabled(True)
|
self.pushButton_label_root.setEnabled(True)
|
||||||
self.pushButton_save_root.setEnabled(True)
|
self.pushButton_save_root.setEnabled(True)
|
||||||
self.checkBox_is_instance.setEnabled(True)
|
self.checkBox_is_instance.setEnabled(True)
|
||||||
|
self.checkBox_keep_crowd.setEnabled(True)
|
||||||
|
self.pushButton_apply.setEnabled(True)
|
||||||
|
|
||||||
|
def print_message(self, index, all, message):
|
||||||
|
if all:
|
||||||
|
self.progressBar.setMaximum(all)
|
||||||
|
if index:
|
||||||
|
self.progressBar.setValue(index)
|
||||||
|
if message:
|
||||||
|
self.textBrowser.append(message)
|
||||||
|
|
||||||
def init_connect(self):
|
def init_connect(self):
|
||||||
self.pushButton_label_root.clicked.connect(self._label_root)
|
self.pushButton_label_root.clicked.connect(self._label_root)
|
||||||
|
@ -237,6 +237,8 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
|
|||||||
|
|
||||||
self.current_label.note = self.info_dock_widget.lineEdit_note.text()
|
self.current_label.note = self.info_dock_widget.lineEdit_note.text()
|
||||||
self.current_label.save_annotation()
|
self.current_label.save_annotation()
|
||||||
|
# 保存标注文件的同时保存一份isat配置文件
|
||||||
|
self.save_cfg(os.path.join(self.label_root, 'isat.yaml'))
|
||||||
self.set_saved_state(True)
|
self.set_saved_state(True)
|
||||||
|
|
||||||
def show_image(self, index:int):
|
def show_image(self, index:int):
|
||||||
|
@ -60,6 +60,7 @@ class SettingDialog(QtWidgets.QDialog, Ui_Dialog):
|
|||||||
self.category_list_widget.takeItem(row)
|
self.category_list_widget.takeItem(row)
|
||||||
|
|
||||||
def load_cfg(self):
|
def load_cfg(self):
|
||||||
|
self.label_config_file.setText(self.mainwindow.config_file)
|
||||||
cfg = load_config(self.mainwindow.config_file)
|
cfg = load_config(self.mainwindow.config_file)
|
||||||
self.category_list_widget.clear()
|
self.category_list_widget.clear()
|
||||||
labels = cfg.get('label', [])
|
labels = cfg.get('label', [])
|
||||||
|
Loading…
x
Reference in New Issue
Block a user