def accept(self) -> None: if self.result.color and self.result.name: super(NewLabelForm, self).accept() else: GUIUtilities.show_info_message( "The color and name fields are required", "info") return
def done_work(result): self._loading_dialog.hide() pred_out, err = result if err: raise err if pred_out: pred_type, pred_res = pred_out if pred_type == "mask": for class_idx, contours in pred_res.items(): if len(contours) > 0: for c in contours: points = [] for i in range(0, len(c), 10): points.append(c[i]) if len(points) > 5: polygon = EditablePolygon() polygon.tag = self.tag.dataset self.image_viewer._scene.addItem(polygon) bbox: QRectF = self.image_viewer.pixmap.boundingRect( ) offset = QPointF(bbox.width() / 2, bbox.height() / 2) for point in points: if isinstance( point, list) and len(point) == 2: polygon.addPoint( QPoint(point[0] - offset.x(), point[1] - offset.y())) else: class_id, class_name = pred_res GUIUtilities.show_info_message( "predicted label : `{}`".format(class_name), "prediction result")
def done_work(result): annots, err = result if err: raise err if annots: output_file = Path(selected_folder) \ .joinpath("annotations.{}".format(export_format)) if export_format == "csv": df = pd.DataFrame(annots) df.to_csv(str(output_file), index=False) else: def dumper(obj): try: return obj.toJSON() except: return obj.__dict__ with open(output_file, "w") as f: f.write( json.dumps(annots, default=dumper, indent=2)) GUIUtilities.show_info_message( "Annotations exported successfully", "Done") else: GUIUtilities.show_info_message( "Not annotations found for the dataset {}".format( dataset_vo.name), "Done")
def contextMenuEvent(self, evt: QContextMenuEvent) -> None: index: QModelIndex = self.indexAt(evt.pos()) actions = [] if index.isValid(): node: CustomNode = index.internalPointer() index: QModelIndex = self.indexAt(evt.pos()) menu = QMenu() menu.triggered.connect(self.context_menu_actions_handler) if node.level == 1: actions = [ QAction(gui.get_icon('new_folder.png'), self.CTX_MENU_ADD_REPOSITORY_ACTION) ] elif node.level == 2: actions = [ QAction(gui.get_icon('delete.png'), self.CTX_MENU_DELETE_REPO_ACTION), QAction(gui.get_icon('refresh.png'), self.CTX_MENU_UPDATE_REPO_ACTION) ] elif node.level == 3: actions = [ QAction(gui.get_icon('robotic-hand.png'), self.CTX_MENU_AUTO_LABEL_ACTION) ] if actions: for act in actions: act.setData(index) menu.addAction(act) menu.exec_(self.mapToGlobal(evt.pos()))
def __init__(self, parent=None): super(TopBar, self).__init__(parent) self.setLayout(QHBoxLayout()) self.layout().setAlignment(QtCore.Qt.AlignRight) self.layout().setContentsMargins(0, 0, 0, 0) self.setFrameStyle(QFrame.Box) self.setObjectName("top_bar") self.setFixedHeight(40) # self.setCursor(QtCore.Qt.SizeAllCursor) preferred_size = QSize(30, 30) self.btn_minimize = QPushButton( icon=GUIUtilities.get_icon("minimize.png")) self.btn_maximize = QPushButton( icon=GUIUtilities.get_icon("maximize.png")) self.btn_close = QPushButton(icon=GUIUtilities.get_icon("close.png")) self.btn_minimize.clicked.connect( lambda evt: self.window().showMinimized()) self.btn_maximize.clicked.connect(self.btn_maximize_click) self.btn_close.clicked.connect(lambda evt: self.window().close()) self.layout().addWidget(self.btn_minimize) self.layout().addWidget(self.btn_maximize) self.layout().addWidget(self.btn_close) self.dragPos = None for i in reversed(range(self.layout().count())): widget = self.layout().itemAt(i).widget() if isinstance(widget, QPushButton): widget.setFixedSize(preferred_size) widget.setCursor(QtCore.Qt.PointingHandCursor)
def thumbnail(self, widget: QWidget): GUIUtilities.clear_layout(self.thumbnail_layout) widget.setCursor(QtCore.Qt.PointingHandCursor) app: QApplication = QApplication.instance() curr_theme = "dark" if app: curr_theme = app.property("theme") widget.setStyleSheet(self.unselected_style[curr_theme]) self.thumbnail_layout.addWidget(widget)
def wrapper(*args, **kwargs): try: if args or kwargs: return function(*args, **kwargs) else: return function() except Exception: exc_type, exc_value, exc_traceback = sys.exc_info() GUIUtilities.show_error_message("{}".format( str(traceback.format_exception_only(exc_type, exc_value)[0])))
def done_work(result): data, error = result if error: raise error images =itertools.groupby(data,lambda x: x["image"]) if action_text == self.JSON: self.annotations2json(images, selected_folder) elif action_text == self.PASCAL_VOC: self.annotations2pascal(images,selected_folder) GUIUtilities.show_info_message("Annotations exported successfully", "Done")
def done_work(result): annotations, err = result if err: raise err if annotations: GUIUtilities.show_info_message( "Annotations exported successfully", "Done") else: GUIUtilities.show_info_message( "Not annotations found for the dataset {}".format( dataset_vo.name), "Done")
def setup_toolbar(self): uncheck_all_icon = GUIUtilities.get_icon("uncheck_all.png") self.btn_uncheck_all = ImageButton(icon=uncheck_all_icon, size=QSize(20, 20)) check_all_icon = GUIUtilities.get_icon("check_all.png") self.btn_check_all = ImageButton(icon=check_all_icon, size=QSize(20, 20)) self.btn_check_all.setFixedWidth(40) self.btn_uncheck_all.setFixedWidth(40) self.btn_check_all.clicked.connect(self.btn_check_all_on_click_slot) self.btn_uncheck_all.clicked.connect( self.btn_uncheck_all_on_click_slot)
def done_work(result): data, error = result if error: raise error if len(data) > 0: GUIUtilities.show_info_message( "Annotations imported successfully", "Import annotations status") else: GUIUtilities.show_info_message( "No annotations found", "Import annotations status")
def contextMenuEvent(self, evt: QContextMenuEvent) -> None: menu = QMenu() menu.triggered.connect(self.context_menu_actions_handler) index: QModelIndex = self.indexAt(evt.pos()) if index.isValid(): icon: QIcon = GUIUtilities.get_icon('delete_label.png') action = menu.addAction(icon, self.CTX_MENU_DELETE_LABEL) action.setData(index) else: icon: QIcon = GUIUtilities.get_icon('new_label.png') menu.addAction(icon, self.CTX_MENU_ADD_LABEL) menu.exec_(self.mapToGlobal(evt.pos()))
def build_toolbox(self): icon_size = QSize(28, 28) self._toolbox = [ ImageButton(icon=GUIUtilities.get_icon("polygon.png"), size=icon_size, tag="polygon"), ImageButton(icon=GUIUtilities.get_icon("square.png"), size=icon_size, tag="box"), ImageButton(icon=GUIUtilities.get_icon("circle.png"), size=icon_size, tag="ellipse"), ImageButton(icon=GUIUtilities.get_icon("highlighter.png"), size=icon_size, tag="free"), ImageButton(icon=GUIUtilities.get_icon("robotic-hand.png"), size=icon_size, tag="points"), ImageButton(icon=GUIUtilities.get_icon("cursor.png"), size=icon_size, tag="pointer"), ImageButton(icon=GUIUtilities.get_icon("save-icon.png"), size=icon_size, tag="save"), ImageButton(icon=GUIUtilities.get_icon("clean.png"), size=icon_size, tag="clean") ] for button in self._toolbox: self.actions_layout.addWidget(button) self.actions_layout.addWidget(SeparatorWidget()) button.clicked.connect(self._action_toolbox_clicked_slot)
def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.setupUi(self) self.tab_widget_manager.tabCloseRequested.connect(lambda index: self.tab_widget_manager.removeTab(index)) self.lateral_menu = LateralMenu() self.setWindowTitle("CV-Studio") self.resize(1600, 900) self.lateral_menu.add_item(GUIUtilities.get_icon("data.png"), "Datasets", name="datasets") self.lateral_menu.add_item(GUIUtilities.get_icon("logout.png"), "Exit", loc=LateralMenuItemLoc.BOTTOM, name="exit") self.lateral_menu.item_click_signal.connect(self.item_click_signal_slot) self.tab_widget_manager.clear() self.loading_dialog = QLoadingDialog() self.frame_lateral_bar.setLayout(QVBoxLayout()) self.frame_lateral_bar.layout().addWidget(self.lateral_menu)
def done_work(args): result, error = args if result: label, annotations = result if label: self._class_label.setVisible(True) self._class_label.setText(label) else: self._class_label.setVisible(False) self._class_label.setText("") if annotations: img_bbox: QRectF = self.image_viewer.pixmap.sceneBoundingRect( ) offset = QPointF(img_bbox.width() / 2, img_bbox.height() / 2) for entry in annotations: try: vo: AnnotaVO = entry points = map(float, vo.points.split(",")) points = list(more_itertools.chunked(points, 2)) if vo.kind == "box" or vo.kind == "ellipse": x = points[0][0] - offset.x() y = points[0][1] - offset.y() w = math.fabs(points[0][0] - points[1][0]) h = math.fabs(points[0][1] - points[1][1]) roi: QRectF = QRectF(x, y, w, h) if vo.kind == "box": item = EditableBox(roi) else: item = EditableEllipse() item.tag = self.tag.dataset item.setRect(roi) item.label = vo.label self.image_viewer.scene().addItem(item) elif vo.kind == "polygon": item = EditablePolygon() item.label = vo.label item.tag = self.tag.dataset self.image_viewer.scene().addItem(item) for p in points: item.addPoint( QPoint(p[0] - offset.x(), p[1] - offset.y())) except Exception as ex: GUIUtilities.show_error_message( "Error loading the annotations: {}".format(ex), "Error")
def setup_paginator(self): self.grid_actions_layout.addWidget(self.btn_check_all) self.grid_actions_layout.addWidget(self.btn_uncheck_all) self.btn_next_page.clicked.connect(self.btn_next_page_on_click) self.btn_prev_page.clicked.connect(self.btn_prev_page_on_click) self.btn_last_page.clicked.connect(self.btn_last_page_on_click) self.btn_first_page.clicked.connect(self.btn_first_page_on_click) self.btn_first_page.setIcon(GUIUtilities.get_icon("first.png")) self.btn_prev_page.setIcon(GUIUtilities.get_icon("left.png")) self.btn_next_page.setIcon(GUIUtilities.get_icon("right.png")) self.btn_last_page.setIcon(GUIUtilities.get_icon("last.png")) self.btn_first_page.setStyleSheet('QPushButton{border: 0px solid;}') self.btn_prev_page.setStyleSheet('QPushButton{border: 0px solid;}') self.btn_last_page.setStyleSheet('QPushButton{border: 0px solid;}') self.btn_next_page.setStyleSheet('QPushButton{border: 0px solid;}') self.grid_actions_layout.setAlignment(QtCore.Qt.AlignCenter)
def build_new_button(self): new_item_widget: GridCard = GridCard(with_actions=False, with_title=False) btn_new_item = ImageButton(GUIUtilities.get_icon("new_folder.png")) btn_new_item.clicked.connect(lambda: self.new_item_action.emit()) new_item_widget.body = btn_new_item return new_item_widget
def __init__(self, parent=None): super(BaseModelSelectionPage, self).__init__(parent) self.setTitle("Base Model Selection") self._layout = QVBoxLayout(self) _model_section_widget = QWidget() _section_layout = QFormLayout(_model_section_widget) self.ds_picker = DatasetPicker() self.arch_picker = ModelPicker() self._num_of_epochs_picker = QSpinBox() self._num_of_workers_picker = QSpinBox() self._batch_size_picker = QSpinBox() self._learning_rate_picker = QDoubleSpinBox() self._learning_momentum_picker = QDoubleSpinBox() self._learning_weight_decay_picker = QDoubleSpinBox() self._learning_weight_decay_picker = QDoubleSpinBox() _section_layout.addRow(self.tr("Dataset: "), self.ds_picker) _section_layout.addRow(self.tr("Architecture: "), self.arch_picker) _section_layout.addRow(self.tr("Number of epochs: "), self._num_of_epochs_picker) _section_layout.addRow(self.tr("Number of workers: "), self._num_of_workers_picker) _section_layout.addRow(self.tr("Batch Size: "), self._batch_size_picker) _section_layout.addRow(self.tr("Learning rate: "), self._learning_rate_picker) self._layout.addWidget( GUIUtilities.wrap_with_groupbox(_model_section_widget, "Model Details"))
def __init__(self, parent=None): super(NewLabelForm, self).__init__(parent) self.setupUi(self) self.setWindowTitle("Create New Label".title()) self.setWindowIcon(GUIUtilities.get_icon("polygon.png")) self.btn_pick_color.clicked.connect(self.btn_pick_color_click_slot) self._result = None
def __init__(self, vo: DatasetVO = None, parent=None): super(DatasetForm, self).__init__(parent) self.setupUi(self) self.setWindowTitle("Create new dataset".title()) self.setWindowIcon(GUIUtilities.get_icon("polygon.png")) self._value = vo self.initialize_form()
def add_node(self, vo: HubVO): parent_node = CustomNode( [vo.path, ""], level=2, status=1, success_icon=GUIUtilities.get_icon("github.png")) self._root_node.addChild(parent_node) for m in vo.models: child_node = CustomNode( [m.name, ""], level=3, tooltip=m.description, status=1, success_icon=GUIUtilities.get_icon("cube.png")) parent_node.addChild(child_node) self._update_model()
def contextMenuEvent(self, evt: QContextMenuEvent) -> None: index: QModelIndex = self.indexAt(evt.pos()) if index.isValid(): node: CustomNode = index.internalPointer() menu = QMenu() menu.triggered.connect(self.context_menu_actions_handler) if node.level == 1: icon: QIcon = GUIUtilities.get_icon('delete-dataset.png') action: QAction = menu.addAction( icon, self.CTX_MENU_NEW_DATASET_ACTION) action.setData(node) elif node.level == 3: icon: QIcon = GUIUtilities.get_icon('delete-dataset.png') action: QAction = menu.addAction( icon, self.CTX_MENU_AUTO_LABEL_ACTION) action.setData(node) menu.exec_(self.mapToGlobal(evt.pos()))
def update(self) -> None: GUIUtilities.clear_layout(self) if self.widgets and len(self.widgets) > 0: row = col = 0 n = max(len(self.widgets), self.cols) for idx in range(n): self.setColumnStretch(col, 1) self.setRowStretch(row, 1) if idx < len(self.widgets): widget = self.widgets[idx] self.addWidget(widget, row, col) else: self.addWidget(QWidget(), row, col) col += 1 if col % self.cols == 0: row += 1 col = 0
def accept(self) -> None: if not self.nameLineEdit.text(): GUIUtilities.show_info_message("The name field is required", "info") return if self._value is None: usr_folder = FileUtilities.get_usr_folder() new_folder = FileUtilities.create_new_folder(usr_folder) vo = DatasetVO() ds_folder = os.path.basename(new_folder) vo.folder = ds_folder self._value = vo else: vo = self._value vo.name = self.nameLineEdit.text() vo.description = self.descriptionEditText.toPlainText() # dataset_vo.data_type=self.typeComboBox.currentText() return QDialog.accept(self)
def __init__(self, ds, parent=None): super(MediaTabWidget, self).__init__(parent) self.media_grid = Gallery() self.media_grid.filesDropped.connect(self.gallery_files_dropped_slot) self.media_grid.doubleClicked.connect(self.gallery_card_double_click_slot) delete_action = GalleryAction(gui.get_icon("delete.png"), name="delete", tooltip="delete image") edit_action = GalleryAction(gui.get_icon("annotations.png"), name="edit", tooltip="edit annotations") # view_action=GalleryAction(gui.get_icon("search.png"),name="view") self.media_grid.actions = [delete_action, edit_action] self.media_grid.cardActionClicked.connect(self.card_action_clicked_slot) self.setLayout(QVBoxLayout()) self.layout().setContentsMargins(0, 0, 0, 0) self.layout().addWidget(self.media_grid) self._thread_pool = QThreadPool() self._loading_dialog = QLoadingDialog() self._ds_dao = DatasetDao() self._ds: DatasetVO = ds self.load()
def source(self, value): self._video_source = value qimage = GUIUtilities.array_to_qimage(self._video_source) pixmap = QPixmap.fromImage(qimage) pixmap = pixmap.scaledToHeight(120, mode=QtCore.Qt.SmoothTransformation) # pixmap=pixmap.scaled(QSize(150,150),aspectRatioMode=QtCore.Qt.KeepAspectRatio,transformMode=QtCore.Qt.SmoothTransformation) # image_widget.setScaledContents(True) self._video_widget.setPixmap(pixmap)
def __init__(self, parent=None): super(ModelWizard, self).__init__(parent) self.setWindowIcon(GUIUtilities.get_icon("pytorch.png")) self.setWindowTitle("New Model") self.resize(800, 600) self.setWizardStyle(QWizard.ClassicStyle) self._model_params_page = BaseModelSelectionPage() self.addPage(self._model_params_page) self.button(QWizard.FinishButton).clicked.connect( self.finish_button_click)
def create_thumbnail(item): file_path = item.file_path if os.path.isfile(file_path): image = cv2.imread(file_path) h, w, _ = np.shape(image) if w > h: thumbnail_array = imutils.resize(image, width=150) else: thumbnail_array = imutils.resize(image, height=150) thumbnail_array = cv2.cvtColor(thumbnail_array, cv2.COLOR_BGR2RGB) thumbnail = GUIUtilities.array_to_qimage(thumbnail_array) thumbnail = QPixmap.fromImage(thumbnail) del thumbnail_array del image return item, h, w, thumbnail, os.path.getsize( file_path), False thumbnail = GUIUtilities.get_image("placeholder.png") thumbnail = thumbnail.scaledToHeight(100) h, w = thumbnail.height(), thumbnail.width() return item, h, w, thumbnail, 0, True
def done_work(result): data,error=result selected_item = None for vo in data: item = CustomListWidgetItem(vo.file_path) item.setIcon(GUIUtilities.get_icon("image.png")) item.tag = vo if vo.file_path == self.source.file_path: selected_item = item self.images_list_widget.addItem(item) self.images_list_widget.setCursor(QtCore.Qt.PointingHandCursor) self.images_list_widget.setCurrentItem(selected_item)
def create_actions_bar(self): self.btn_enable_polygon_selection = ImageButton( icon=GUIUtilities.get_icon("polygon.png"), size=QSize(32, 32)) self.btn_enable_rectangle_selection = ImageButton( icon=GUIUtilities.get_icon("square.png"), size=QSize(32, 32)) self.btn_enable_free_selection = ImageButton( icon=GUIUtilities.get_icon("highlighter.png"), size=QSize(32, 32)) self.btn_enable_none_selection = ImageButton( icon=GUIUtilities.get_icon("cursor.png"), size=QSize(32, 32)) self.btn_save_annotations = ImageButton( icon=GUIUtilities.get_icon("save-icon.png"), size=QSize(32, 32)) self.btn_clear_annotations = ImageButton( icon=GUIUtilities.get_icon("clean.png"), size=QSize(32, 32)) self.actions_layout.addWidget(self.btn_enable_rectangle_selection) self.actions_layout.addWidget(self.btn_enable_polygon_selection) self.actions_layout.addWidget(self.btn_enable_free_selection) self.actions_layout.addWidget(self.btn_enable_none_selection) self.actions_layout.addWidget(self.btn_clear_annotations) self.actions_layout.addWidget(self.btn_save_annotations) self.btn_save_annotations.clicked.connect( self.btn_save_annotations_clicked_slot) self.btn_enable_polygon_selection.clicked.connect( self.btn_enable_polygon_selection_clicked_slot) self.btn_enable_rectangle_selection.clicked.connect( self.btn_enable_rectangle_selection_clicked_slot) self.btn_enable_free_selection.clicked.connect( self.btn_enable_free_selection_clicked_slot) self.btn_enable_none_selection.clicked.connect( self.btn_enable_none_selection_clicked_slot) self.btn_clear_annotations.clicked.connect( self.btn_clear_annotations_clicked_slot)