예제 #1
0
 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")
예제 #3
0
            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")
예제 #4
0
 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()))
예제 #5
0
 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)
예제 #6
0
 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)
예제 #7
0
 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])))
예제 #8
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")
예제 #9
0
 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")
예제 #10
0
 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)
예제 #11
0
 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")
예제 #12
0
 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()))
예제 #13
0
 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)
예제 #14
0
 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)
예제 #15
0
        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")
예제 #16
0
 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)
예제 #17
0
 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
예제 #18
0
 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"))
예제 #19
0
 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
예제 #20
0
 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()
예제 #21
0
    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()
예제 #22
0
 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()))
예제 #23
0
 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
예제 #24
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)
예제 #25
0
 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()
예제 #26
0
 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)
예제 #27
0
 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)
예제 #28
0
 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
예제 #29
0
 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)
예제 #30
0
    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)