ISAT_with_sam/sam_ann/widgets/mainwindow.py

722 lines
31 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- coding: utf-8 -*-
# @Author : LG
from PyQt5 import QtWidgets, QtCore, QtGui
from sam_ann.ui.MainWindow import Ui_MainWindow
from sam_ann.widgets.setting_dialog import SettingDialog
from sam_ann.widgets.category_choice_dialog import CategoryChoiceDialog
from sam_ann.widgets.category_edit_dialog import CategoryEditDialog
from sam_ann.widgets.category_dock_widget import CategoriesDockWidget
from sam_ann.widgets.annos_dock_widget import AnnosDockWidget
from sam_ann.widgets.files_dock_widget import FilesDockWidget
from sam_ann.widgets.info_dock_widget import InfoDockWidget
from sam_ann.widgets.right_button_menu import RightButtonMenu
from sam_ann.widgets.shortcut_dialog import ShortcutDialog
from sam_ann.widgets.about_dialog import AboutDialog
from sam_ann.widgets.ISAT_to_VOC_dialog import ISATtoVOCDialog
from sam_ann.widgets.ISAT_to_COCO_dialog import ISATtoCOCODialog
from sam_ann.widgets.ISAT_to_LABELME_dialog import ISATtoLabelMeDialog
from sam_ann.widgets.COCO_to_ISAT_dialog import COCOtoISATDialog
from sam_ann.widgets.canvas import AnnotationScene, AnnotationView
from sam_ann.configs import STATUSMode, MAPMode, load_config, save_config, CONFIG_FILE, DEFAULT_CONFIG_FILE, CHECKPOINTS
from sam_ann.annotation import Object, Annotation
from sam_ann.widgets.polygon import Polygon
from sam_ann.configs import BASE_DIR
import os
from PIL import Image
import functools
import imgviz
import numpy as np
from sam_ann.segment_any.segment_any import SegAny
from sam_ann.segment_any.gpu_resource import GPUResource_Thread, osplatform
import sam_ann.icons_rc
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setupUi(self)
self.image_root: str = None
self.label_root:str = None
self.files_list: list = []
self.current_index = None
self.current_file_index: int = None
self.current_label = '__background__'
self.current_group = 1
self.config_file = CONFIG_FILE if os.path.exists(CONFIG_FILE) else DEFAULT_CONFIG_FILE
self.saved = True
self.can_be_annotated = True
self.load_finished = False
self.polygons:list = []
self.image_changed = False
self.png_palette = None # 图像拥有调色盘说明是单通道的标注png文件
self.instance_cmap = imgviz.label_colormap()
self.map_mode = MAPMode.LABEL
# 标注目标
self.current_label:Annotation = None
self.use_segment_anything = False
self.gpu_resource_thread = None
self.pre_segany = ''
self.segany = None
self.init_ui()
self.reload_cfg()
self.init_connect()
self.reset_action()
def init_segment_anything(self, model_name, reload=False):
if model_name == '':
self.use_segment_anything = False
for name, action in self.pths_actions.items():
action.setChecked(model_name == name)
return
model_path = os.path.join(CHECKPOINTS, model_name)
if not os.path.exists(model_path):
QtWidgets.QMessageBox.warning(self, 'Warning',
'The checkpoint of [Segment anything] not existed. If you want use quick annotate, please download from {}'.format(
'https://github.com/facebookresearch/segment-anything#model-checkpoints'))
for name, action in self.pths_actions.items():
action.setChecked(model_name == name)
self.use_segment_anything = False
return
try:
if self.segany is None:
self.segany = SegAny(model_path)
elif model_name != self.pre_segany:
self.segany = SegAny(model_path)
self.pre_segany = model_name
except Exception as e:
print(e)
QtWidgets.QMessageBox.warning(self, 'Warning',
'The model of [Segment anything] is not valid. If you want use quick annotate, please download from {}'.format(
'https://github.com/facebookresearch/segment-anything#model-checkpoints'))
for name, action in self.pths_actions.items():
action.setChecked(model_name == name)
self.use_segment_anything = False
return
self.use_segment_anything = True
self.statusbar.showMessage('Use the checkpoint named {}.'.format(model_name), 3000)
for name, action in self.pths_actions.items():
action.setChecked(model_name==name)
if self.use_segment_anything:
if self.segany.device != 'cpu':
if self.gpu_resource_thread is None:
self.gpu_resource_thread = GPUResource_Thread()
self.gpu_resource_thread.message.connect(self.labelGPUResource.setText)
self.gpu_resource_thread.start()
else:
self.labelGPUResource.setText('cpu')
else:
self.labelGPUResource.setText('segment anything unused.')
if self.current_index is None or ( -1> self.current_index >= len(self.files_list)):
return
file_path = os.path.join(self.image_root, self.files_list[self.current_index])
image_data = np.array(Image.open(file_path))
if image_data.ndim == 3 and image_data.shape[-1] == 3: # 三通道图
self.segany.set_image(image_data)
elif image_data.ndim == 2: # 单通道图
image_data = image_data[:, :, np.newaxis]
image_data = np.repeat(image_data, 3, axis=2) # 转换为三通道
self.segany.set_image(image_data)
elif image_data.ndim == 3 and image_data.shape[-1] > 3: # 多通道
self.segany.set_image(image_data[:,:,:3])
self.statusbar.showMessage("Segment anything only use the 3 dim with shape {} .".format(image_data.shape))
else:
self.statusbar.showMessage("Segment anything don't support the image with shape {} .".format(image_data.shape))
self.image_changed = False
self.show_image(self.current_index)
# if self.current_index is not None:
# self.image_changed = False
# self.show_image(self.current_index)
def init_ui(self):
#q
self.setting_dialog = SettingDialog(parent=self, mainwindow=self)
self.categories_dock_widget = CategoriesDockWidget(mainwindow=self)
self.categories_dock.setWidget(self.categories_dock_widget)
self.annos_dock_widget = AnnosDockWidget(mainwindow=self)
self.annos_dock.setWidget(self.annos_dock_widget)
self.files_dock_widget = FilesDockWidget(mainwindow=self)
self.files_dock.setWidget(self.files_dock_widget)
self.info_dock_widget = InfoDockWidget(mainwindow=self)
self.info_dock.setWidget(self.info_dock_widget)
self.scene = AnnotationScene(mainwindow=self)
self.category_choice_widget = CategoryChoiceDialog(self, mainwindow=self, scene=self.scene)
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.ISAT_to_LABELME_dialog = ISATtoLabelMeDialog(self, mainwindow=self)
self.COCO_to_ISAT_dialog = COCOtoISATDialog(self, mainwindow=self)
self.view = AnnotationView(parent=self)
self.view.setScene(self.scene)
self.setCentralWidget(self.view)
self.right_button_menu = RightButtonMenu(mainwindow=self)
self.right_button_menu.addAction(self.actionEdit)
self.right_button_menu.addAction(self.actionTo_top)
self.right_button_menu.addAction(self.actionTo_bottom)
self.shortcut_dialog = ShortcutDialog(self)
self.about_dialog = AboutDialog(self)
self.labelGPUResource = QtWidgets.QLabel('')
self.labelGPUResource.setAlignment(QtCore.Qt.AlignmentFlag.AlignRight)
self.labelGPUResource.setFixedWidth(180)
self.statusbar.addPermanentWidget(self.labelGPUResource)
self.labelCoord = QtWidgets.QLabel('')
self.labelCoord.setAlignment(QtCore.Qt.AlignmentFlag.AlignRight)
self.labelCoord.setFixedWidth(150)
self.statusbar.addPermanentWidget(self.labelCoord)
self.labelData = QtWidgets.QLabel('')
self.labelData.setAlignment(QtCore.Qt.AlignmentFlag.AlignRight)
self.labelData.setFixedWidth(150)
self.statusbar.addPermanentWidget(self.labelData)
#
model_names = sorted([pth for pth in os.listdir(CHECKPOINTS) if pth.endswith('.pth') or pth.endswith('.pt')])
self.pths_actions = {}
for model_name in model_names:
action = QtWidgets.QAction(self)
action.setObjectName("actionZoom_in")
action.triggered.connect(functools.partial(self.init_segment_anything, model_name))
action.setText("{}".format(model_name))
action.setCheckable(True)
self.pths_actions[model_name] = action
self.menuSAM_model.addAction(action)
# mask alpha
self.toolBar.addSeparator()
self.mask_aplha = QtWidgets.QSlider(QtCore.Qt.Orientation.Horizontal, self)
self.mask_aplha.setFixedWidth(50)
self.mask_aplha.setStatusTip('Mask alpha.')
self.mask_aplha.setToolTip('Mask alpha')
self.mask_aplha.setMaximum(10)
self.mask_aplha.setMinimum(3)
self.mask_aplha.valueChanged.connect(self.change_mask_aplha)
self.toolBar.addWidget(self.mask_aplha)
# vertex size
self.toolBar.addSeparator()
self.vertex_size = QtWidgets.QSlider(QtCore.Qt.Orientation.Horizontal, self)
self.vertex_size.setFixedWidth(50)
self.vertex_size.setStatusTip('Vertex size.')
self.vertex_size.setToolTip('Vertex size')
self.vertex_size.setMaximum(10)
self.vertex_size.setMinimum(2)
self.vertex_size.valueChanged.connect(self.change_vertex_size)
self.toolBar.addWidget(self.vertex_size)
self.trans = QtCore.QTranslator()
def translate(self, language='zh'):
if language == 'zh':
self.trans.load('ui/zh_CN')
else:
self.trans.load('ui/en')
self.actionChinese.setChecked(language=='zh')
self.actionEnglish.setChecked(language=='en')
_app = QtWidgets.QApplication.instance()
_app.installTranslator(self.trans)
self.retranslateUi(self)
self.info_dock_widget.retranslateUi(self.info_dock_widget)
self.annos_dock_widget.retranslateUi(self.annos_dock_widget)
self.files_dock_widget.retranslateUi(self.files_dock_widget)
self.category_choice_widget.retranslateUi(self.category_choice_widget)
self.category_edit_widget.retranslateUi(self.category_edit_widget)
self.setting_dialog.retranslateUi(self.setting_dialog)
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.ISAT_to_LABELME_dialog.retranslateUi(self.ISAT_to_LABELME_dialog)
self.COCO_to_ISAT_dialog.retranslateUi(self.COCO_to_ISAT_dialog)
def translate_to_chinese(self):
self.translate('zh')
self.cfg['language'] = 'zh'
def translate_to_english(self):
self.translate('en')
self.cfg['language'] = 'en'
def reload_cfg(self):
self.cfg = load_config(self.config_file)
label_dict_list = self.cfg.get('label', [])
d = {}
for label_dict in label_dict_list:
category = label_dict.get('name', 'unknow')
color = label_dict.get('color', '#000000')
d[category] = color
self.category_color_dict = d
if self.current_index is not None:
self.show_image(self.current_index)
language = self.cfg.get('language', 'en')
self.cfg['language'] = language
self.translate(language)
contour_mode = self.cfg.get('contour_mode', 'max_only')
self.cfg['contour_mode'] = contour_mode
self.change_contour_mode(contour_mode)
mask_alpha = self.cfg.get('mask_alpha', 0.5)
self.cfg['mask_alpha'] = mask_alpha
self.mask_aplha.setValue(mask_alpha*10)
vertex_size = self.cfg.get('vertex_size', 2)
self.cfg['vertex_size'] = int(vertex_size)
model_name = self.cfg.get('model_name', '')
self.init_segment_anything(model_name)
self.categories_dock_widget.update_widget()
def set_saved_state(self, is_saved:bool):
self.saved = is_saved
if self.files_list is not None and self.current_index is not None:
if is_saved:
self.setWindowTitle(self.current_label.label_path)
else:
self.setWindowTitle('*{}'.format(self.current_label.label_path))
def open_dir(self):
dir = QtWidgets.QFileDialog.getExistingDirectory(self)
if dir:
self.files_list.clear()
self.files_dock_widget.listWidget.clear()
files = []
suffixs = tuple(['{}'.format(fmt.data().decode('ascii').lower()) for fmt in QtGui.QImageReader.supportedImageFormats()])
for f in os.listdir(dir):
if f.lower().endswith(suffixs):
# f = os.path.join(dir, f)
files.append(f)
files = sorted(files)
self.files_list = files
self.files_dock_widget.update_widget()
self.current_index = 0
self.image_root = dir
self.actionOpen_dir.setStatusTip("Image root: {}".format(self.image_root))
if self.label_root is None:
self.label_root = dir
self.actionSave_dir.setStatusTip("Label root: {}".format(self.label_root))
self.image_changed = True
self.show_image(self.current_index)
def save_dir(self):
dir = QtWidgets.QFileDialog.getExistingDirectory(self)
if dir:
self.label_root = dir
self.actionSave_dir.setStatusTip("Label root: {}".format(self.label_root))
# 刷新图片
if self.current_index is not None:
self.show_image(self.current_index)
def save(self):
if self.current_label is None:
return
self.current_label.objects.clear()
for polygon in self.polygons:
object = polygon.to_object()
self.current_label.objects.append(object)
self.current_label.note = self.info_dock_widget.lineEdit_note.text()
self.current_label.save_annotation()
# 保存标注文件的同时保存一份isat配置文件
self.save_cfg(os.path.join(self.label_root, 'isat.yaml'))
self.set_saved_state(True)
def show_image(self, index:int):
self.reset_action()
self.current_label = None
self.load_finished = False
self.saved = True
if not -1 < index < len(self.files_list):
self.scene.clear()
self.scene.setSceneRect(QtCore.QRectF())
return
if not self.image_changed:
self.scene.cancel_draw()
self.actionSegment_anything.setEnabled(self.use_segment_anything)
self.actionPolygon.setEnabled(True)
self.actionSave.setEnabled(True)
self.actionBit_map.setEnabled(True)
self.actionBackspace.setEnabled(True)
self.actionFinish.setEnabled(True)
self.actionCancel.setEnabled(True)
self.actionVisible.setEnabled(True)
return
try:
self.scene.cancel_draw()
self.polygons.clear()
self.annos_dock_widget.listWidget.clear()
file_path = os.path.join(self.image_root, self.files_list[index])
image_data = Image.open(file_path)
self.png_palette = image_data.getpalette()
if self.png_palette is not None and file_path.endswith('.png'):
self.statusbar.showMessage('This is a label file.')
self.can_be_annotated = False
else:
self.can_be_annotated = True
if self.can_be_annotated:
self.actionSegment_anything.setEnabled(self.use_segment_anything)
self.actionPolygon.setEnabled(True)
self.actionSave.setEnabled(True)
self.actionBit_map.setEnabled(True)
self.actionBackspace.setEnabled(True)
self.actionFinish.setEnabled(True)
self.actionCancel.setEnabled(True)
self.actionVisible.setEnabled(True)
else:
self.actionSegment_anything.setEnabled(False)
self.actionPolygon.setEnabled(False)
self.actionSave.setEnabled(False)
self.actionBit_map.setEnabled(False)
self.actionBackspace.setEnabled(False)
self.actionFinish.setEnabled(False)
self.actionCancel.setEnabled(False)
self.actionVisible.setEnabled(False)
self.scene.load_image(file_path)
self.view.zoomfit()
# load label
if self.can_be_annotated:
self.current_group = 1
_, name = os.path.split(file_path)
label_path = os.path.join(self.label_root, '.'.join(name.split('.')[:-1]) + '.json')
self.current_label = Annotation(file_path, label_path)
# 载入数据
self.current_label.load_annotation()
for object in self.current_label.objects:
try:
group = int(object.group)
self.current_group = group+1 if group >= self.current_group else self.current_group
except Exception as e:
pass
polygon = Polygon()
self.scene.addItem(polygon)
polygon.load_object(object)
self.polygons.append(polygon)
if self.current_label is not None:
self.setWindowTitle('{}'.format(self.current_label.label_path))
else:
self.setWindowTitle('{}'.format(file_path))
self.annos_dock_widget.update_listwidget()
self.info_dock_widget.update_widget()
self.files_dock_widget.set_select(index)
self.current_index = index
self.files_dock_widget.label_current.setText('{}'.format(self.current_index+1))
self.load_finished = True
except Exception as e:
print(e)
finally:
if self.current_index > 0:
self.actionPrev.setEnabled(True)
else:
self.actionPrev.setEnabled(False)
if self.current_index < len(self.files_list) - 1:
self.actionNext.setEnabled(True)
else:
self.actionNext.setEnabled(False)
def prev_image(self):
if self.scene.mode != STATUSMode.VIEW:
return
if self.current_index is None:
return
if not self.saved:
result = QtWidgets.QMessageBox.question(self, 'Warning', 'Proceed without saved?', QtWidgets.QMessageBox.StandardButton.Yes|QtWidgets.QMessageBox.StandardButton.No, QtWidgets.QMessageBox.StandardButton.No)
if result == QtWidgets.QMessageBox.StandardButton.No:
return
self.current_index = self.current_index - 1
if self.current_index < 0:
self.current_index = 0
QtWidgets.QMessageBox.warning(self, 'Warning', 'This is the first picture.')
else:
self.image_changed = True
self.show_image(self.current_index)
def next_image(self):
if self.scene.mode != STATUSMode.VIEW:
return
if self.current_index is None:
return
if not self.saved:
result = QtWidgets.QMessageBox.question(self, 'Warning', 'Proceed without saved?', QtWidgets.QMessageBox.StandardButton.Yes|QtWidgets.QMessageBox.StandardButton.No, QtWidgets.QMessageBox.StandardButton.No)
if result == QtWidgets.QMessageBox.StandardButton.No:
return
self.current_index = self.current_index + 1
if self.current_index > len(self.files_list)-1:
self.current_index = len(self.files_list)-1
QtWidgets.QMessageBox.warning(self, 'Warning', 'This is the last picture.')
else:
self.image_changed = True
self.show_image(self.current_index, True)
def jump_to(self):
index = self.files_dock_widget.lineEdit_jump.text()
if index:
if not index.isdigit():
if index in self.files_list:
index = self.files_list.index(index)+1
else:
QtWidgets.QMessageBox.warning(self, 'Warning', 'Don`t exist image named: {}'.format(index))
self.files_dock_widget.lineEdit_jump.clear()
return
index = int(index)-1
if 0 <= index < len(self.files_list):
self.image_changed = True
self.show_image(index)
self.files_dock_widget.lineEdit_jump.clear()
else:
QtWidgets.QMessageBox.warning(self, 'Warning', 'Index must be in [1, {}].'.format(len(self.files_list)))
self.files_dock_widget.lineEdit_jump.clear()
self.files_dock_widget.lineEdit_jump.clearFocus()
return
def cancel_draw(self):
self.scene.cancel_draw()
def setting(self):
self.setting_dialog.load_cfg()
self.setting_dialog.show()
def add_new_object(self, category, group, segmentation, area, layer, bbox):
if self.current_label is None:
return
object = Object(category=category, group=group, segmentation=segmentation, area=area, layer=layer, bbox=bbox)
self.current_label.objects.append(object)
def delete_object(self, index:int):
if 0 <= index < len(self.current_label.objects):
del self.current_label.objects[index]
def change_bit_map(self):
self.set_labels_visible(True)
if self.scene.mode == STATUSMode.CREATE:
self.scene.cancel_draw()
if self.map_mode == MAPMode.LABEL:
# to semantic
for polygon in self.polygons:
polygon.setEnabled(False)
for vertex in polygon.vertexs:
vertex.setVisible(False)
polygon.change_color(QtGui.QColor(self.category_color_dict.get(polygon.category, '#000000')))
polygon.color.setAlpha(255)
polygon.setBrush(polygon.color)
self.annos_dock_widget.listWidget.setEnabled(False)
self.annos_dock_widget.checkBox_visible.setEnabled(False)
self.actionSegment_anything.setEnabled(False)
self.actionPolygon.setEnabled(False)
self.actionVisible.setEnabled(False)
self.map_mode = MAPMode.SEMANTIC
semantic_icon = QtGui.QIcon()
semantic_icon.addPixmap(QtGui.QPixmap(":/icon/icons/semantic.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.actionBit_map.setIcon(semantic_icon)
elif self.map_mode == MAPMode.SEMANTIC:
# to instance
for polygon in self.polygons:
polygon.setEnabled(False)
for vertex in polygon.vertexs:
vertex.setVisible(False)
if polygon.group != '':
index = int(polygon.group)
index = index % self.instance_cmap.shape[0]
rgb = self.instance_cmap[index]
else:
rgb = self.instance_cmap[0]
polygon.change_color(QtGui.QColor(rgb[0], rgb[1], rgb[2], 255))
polygon.color.setAlpha(255)
polygon.setBrush(polygon.color)
self.annos_dock_widget.listWidget.setEnabled(False)
self.annos_dock_widget.checkBox_visible.setEnabled(False)
self.actionSegment_anything.setEnabled(False)
self.actionPolygon.setEnabled(False)
self.actionVisible.setEnabled(False)
self.map_mode = MAPMode.INSTANCE
instance_icon = QtGui.QIcon()
instance_icon.addPixmap(QtGui.QPixmap(":/icon/icons/instance.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.actionBit_map.setIcon(instance_icon)
elif self.map_mode == MAPMode.INSTANCE:
# to label
for polygon in self.polygons:
polygon.setEnabled(True)
for vertex in polygon.vertexs:
# vertex.setEnabled(True)
vertex.setVisible(polygon.isVisible())
polygon.change_color(QtGui.QColor(self.category_color_dict.get(polygon.category, '#000000')))
polygon.color.setAlpha(polygon.nohover_alpha)
polygon.setBrush(polygon.color)
self.annos_dock_widget.listWidget.setEnabled(True)
self.annos_dock_widget.checkBox_visible.setEnabled(True)
self.actionSegment_anything.setEnabled(self.use_segment_anything)
self.actionPolygon.setEnabled(True)
self.actionVisible.setEnabled(True)
self.map_mode = MAPMode.LABEL
label_icon = QtGui.QIcon()
label_icon.addPixmap(QtGui.QPixmap(":/icon/icons/照片_pic.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.actionBit_map.setIcon(label_icon)
else:
pass
def set_labels_visible(self, visible=None):
if visible is None:
visible = not self.annos_dock_widget.checkBox_visible.isChecked()
self.annos_dock_widget.checkBox_visible.setChecked(visible)
self.annos_dock_widget.set_all_polygon_visible(visible)
def change_contour_mode(self, contour_mode='max_only'):
if contour_mode == 'max_only':
self.scene.change_contour_mode_to_save_max_only()
elif contour_mode == 'external':
self.scene.change_contour_mode_to_save_external()
self.statusbar.showMessage('Save all external contours will bring some noise.', 3000)
elif contour_mode == 'all':
self.scene.change_contour_mode_to_save_all()
self.statusbar.showMessage('Category of inner contour will be set _background__.', 3000)
else:
self.scene.change_contour_mode_to_save_max_only()
self.statusbar.showMessage('The contour mode [{}] not support.'.format(contour_mode), 3000)
self.actionContour_Max_only.setChecked(contour_mode == 'max_only')
self.actionContour_External.setChecked(contour_mode == 'external')
self.actionContour_All.setChecked(contour_mode == 'all')
self.cfg['contour_mode'] = contour_mode
def change_mask_aplha(self):
value = self.mask_aplha.value() / 10
self.scene.mask_alpha = value
self.scene.update_mask()
self.cfg['mask_alpha'] = value
def change_vertex_size(self):
value = self.vertex_size.value()
self.cfg['vertex_size'] = value
if self.current_index is not None:
# TODO: no clear
self.image_changed = False
self.show_image(self.current_index)
def ISAT_to_VOC(self):
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 ISAT_to_LABELME(self):
self.ISAT_to_LABELME_dialog.reset_gui()
self.ISAT_to_LABELME_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()
def about(self):
self.about_dialog.show()
def save_cfg(self, config_file):
save_config(self.cfg, config_file)
def exit(self):
self.save_cfg(self.config_file)
self.close()
def closeEvent(self, a0: QtGui.QCloseEvent):
self.exit()
def init_connect(self):
self.actionOpen_dir.triggered.connect(self.open_dir)
self.actionSave_dir.triggered.connect(self.save_dir)
self.actionPrev.triggered.connect(self.prev_image)
self.actionNext.triggered.connect(self.next_image)
self.actionSetting.triggered.connect(self.setting)
self.actionExit.triggered.connect(self.exit)
self.actionSegment_anything.triggered.connect(self.scene.start_segment_anything)
self.actionPolygon.triggered.connect(self.scene.start_draw_polygon)
self.actionCancel.triggered.connect(self.scene.cancel_draw)
self.actionBackspace.triggered.connect(self.scene.backspace)
self.actionFinish.triggered.connect(self.scene.finish_draw)
self.actionEdit.triggered.connect(self.scene.edit_polygon)
self.actionDelete.triggered.connect(self.scene.delete_selected_graph)
self.actionSave.triggered.connect(self.save)
self.actionTo_top.triggered.connect(self.scene.move_polygon_to_top)
self.actionTo_bottom.triggered.connect(self.scene.move_polygon_to_bottom)
self.actionZoom_in.triggered.connect(self.view.zoom_in)
self.actionZoom_out.triggered.connect(self.view.zoom_out)
self.actionFit_wiondow.triggered.connect(self.view.zoomfit)
self.actionBit_map.triggered.connect(self.change_bit_map)
self.actionVisible.triggered.connect(functools.partial(self.set_labels_visible, None))
self.actionContour_Max_only.triggered.connect(functools.partial(self.change_contour_mode, 'max_only'))
self.actionContour_External.triggered.connect(functools.partial(self.change_contour_mode, 'external'))
self.actionContour_All.triggered.connect(functools.partial(self.change_contour_mode, 'all'))
self.actionToVOC.triggered.connect(self.ISAT_to_VOC)
self.actionToCOCO.triggered.connect(self.ISAT_to_COCO)
self.actionTo_LabelMe.triggered.connect(self.ISAT_to_LABELME)
self.actionFromCOCO.triggered.connect(self.COCO_to_ISAT)
self.actionShortcut.triggered.connect(self.help)
self.actionAbout.triggered.connect(self.about)
self.actionChinese.triggered.connect(self.translate_to_chinese)
self.actionEnglish.triggered.connect(self.translate_to_english)
self.annos_dock_widget.listWidget.doubleClicked.connect(self.scene.edit_polygon)
def reset_action(self):
self.actionPrev.setEnabled(False)
self.actionNext.setEnabled(False)
self.actionSegment_anything.setEnabled(False)
self.actionPolygon.setEnabled(False)
self.actionEdit.setEnabled(False)
self.actionDelete.setEnabled(False)
self.actionSave.setEnabled(False)
self.actionTo_top.setEnabled(False)
self.actionTo_bottom.setEnabled(False)
self.actionBit_map.setChecked(False)
self.actionBit_map.setEnabled(False)