def predict_annotations_using_extr_points(self, points):
        pass

        @work_exception
        def do_work():
            contours = self.invoke_dextr_pascal_model(self.tag.file_path,
                                                      points)
            return contours, None

        @gui_exception
        def done_work(result):
            self._loading_dialog.hide()
            pred_out, err = result
            if err:
                raise err
            if pred_out:
                for c in pred_out:
                    c_points = []
                    for i in range(0, len(c), 10):
                        c_points.append(c[i])
                    if len(c_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 c_points:
                            polygon.addPoint(
                                QPoint(point[0] - offset.x(),
                                       point[1] - offset.y()))

        self._loading_dialog.show()
        worker = Worker(do_work)
        worker.signals.result.connect(done_work)
        self._thread_pool.start(worker)
    def bind(self):
        @work_exception
        def do_work():
            return dask.compute(
                *[self.load_images(),
                  self.load_models(),
                  self.load_labels()]), None

        @gui_exception
        def done_work(args):
            result, error = args
            if result:
                images, models, labels = result
                if models:
                    for model in models:
                        self.treeview_models.add_node(model)
                if labels:
                    for entry in labels:
                        self.treeview_labels.add_row(entry)
                selected_image = None
                icon = GUIUtilities.get_icon("image.png")
                for img in images:
                    if os.path.isfile(img.file_path):
                        item = CustomListWidgetItem(img.file_path, tag=img)
                        item.setIcon(icon)
                        self.images_list_widget.addItem(item)
                        if img.file_path == self.tag.file_path:
                            selected_image = item
                    self.images_list_widget.setCurrentItem(selected_image)

        worker = Worker(do_work)
        worker.signals.result.connect(done_work)
        self._thread_pool.start(worker)
Esempio n. 3
0
    def download_annot_action_slot(self, vo: DatasetVO):
        menu=QMenu()
        menu.setCursor(QtCore.Qt.PointingHandCursor)
        menu.addAction(self.JSON)
        menu.addAction(self.PASCAL_VOC)
        #menu.addAction(self.TENSORFLOW_OBJECT_DETECTION)
        #menu.addAction(self.YOLO)
        action=menu.exec_(QCursor.pos())
        if action:

            selected_folder=str(QFileDialog.getExistingDirectory(None,"select the folder"))
            if selected_folder:
                action_text = action.text()
                @work_exception
                def do_work():
                    results = self.annot_dao.fetch_all_by_dataset(vo.id)
                    return results, None

                @gui_exception
                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")

                worker = Worker(do_work)
                worker.signals.result.connect(done_work)
                self.thread_pool.start(worker)
    def _process_image_adjust_oper(self, action: QAction):
        curr_action = action.data()
        k = self._number_of_clusters_spin.value()

        @work_exception
        def do_work():
            if curr_action == "reset":
                self._reset_sliders()
                self.image_viewer.reset_viewer()
            elif curr_action == "equalize_histo":
                self.image_viewer.equalize_histogram()
            elif curr_action == "correct_l":
                self.image_viewer.correct_lightness()
            elif curr_action == "clustering":
                self.image_viewer.clusterize(k=k)

            return None, None

        @gui_exception
        def done_work(result):
            out, err = result
            if err:
                return
            self._loading_dialog.hide()
            self.image_viewer.update_viewer()

        self._loading_dialog.show()
        worker = Worker(do_work)
        worker.signals.result.connect(done_work)
        self._thread_pool.start(worker)
Esempio n. 5
0
    def load_image(self):
        @work_exception
        def do_work():
            return dask.compute(
                *[self.load_image_label(),
                  self.load_image_annotations()]), None

        @gui_exception
        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.setRect(roi)
                                item.label = vo.label
                                self.image_viewer.scene().addItem(item)
                            elif vo.kind == "polygon":
                                item = EditablePolygon()
                                item.label = vo.label
                                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")

        self.image_viewer.remove_annotations()
        worker = Worker(do_work)
        worker.signals.result.connect(done_work)
        self._thread_pool.start(worker)
Esempio n. 6
0
    def load_images(self):
        def do_work():
            page = self._curr_page
            items = self._pages[page]

            def create_thumbnail(item):
                file_path = item.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

            delayed_tasks = [
                dask.delayed(create_thumbnail)(item) for item in items
            ]
            # images = dask.compute(*delayed_taks, scheduler="processes", num_workers=5)
            images = dask.compute(*delayed_tasks)
            return images

        def done_work(images):
            for img in images:
                item, h, w, thumbnail = img
                image_card = ImageCard()
                image_card.tag = item
                image_card.source = thumbnail
                image_card.file_path = item.file_path
                image_card.label.setText("({0}px / {1}px)".format(w, h))
                image_card.setFixedHeight(240)
                image_card.doubleClicked.connect(
                    self.gallery_card_double_click)
                image_card.add_buttons(self.actions)
                if len(self.actions) > 0:
                    image_card.actionClicked.connect(
                        lambda name, item: self.cardActionClicked.emit(
                            name, item))
                self.center_layout.add_item(image_card)

        def finished_work():
            self._loading_dialog.close()
            self.enable_paginator(True)

        worker = Worker(do_work)
        worker.signals.result.connect(done_work)
        worker.signals.finished.connect(finished_work)
        self._thread_pool.start(worker)
        self.enable_paginator(False)
        self._loading_dialog.show()
Esempio n. 7
0
    def load(self):
        def do_work():
            ds_dao = DatasetDao()
            return ds_dao.fetch_all()

        def done_work(result):
            for ds in result:
                self.addItem(ds.name, ds.id)

        worker = Worker(do_work)
        worker.signals.result.connect(done_work)
        self._thread_pool.start(worker)
    def predict_annotations_using_pytorch_thub_model(self, repo, model_name):
        @work_exception
        def do_work():
            if model_name == "covid19":
                pred_result = self.invoke_cov19_model(self.tag.file_path, repo,
                                                      model_name)
            else:
                pred_result = self.invoke_tf_hub_model(self.tag.file_path,
                                                       repo, model_name)
            return pred_result, None

        @gui_exception
        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")

        self._loading_dialog.show()
        worker = Worker(do_work)
        worker.signals.result.connect(done_work)
        self._thread_pool.start(worker)
Esempio n. 9
0
    def load_labels(self):
        @work_exception
        def do_work():
            results = self._labels_dao.fetch_all(self.source.dataset)
            return results, None

        @gui_exception
        def done_work(result):
            result, error = result
            if error is None:
                for entry in result:
                    self.treeview_labels.add_row(entry)
        worker=Worker(do_work)
        worker.signals.result.connect(done_work)
        self._thread_pool.start(worker)
Esempio n. 10
0
    def load_models(self):
        @work_exception
        def do_work():
            results = self._hub_dao.fetch_all()
            return results, None

        @gui_exception
        def done_work(result):
            result, error = result
            if result:
                for model in result:
                    self.treeview_models.add_node(model)
        worker=Worker(do_work)
        worker.signals.result.connect(done_work)
        self._thread_pool.start(worker)
Esempio n. 11
0
    def load(self):
        ds_id = self._ds.id

        def do_work():
            entries = self._ds_dao.fetch_entries(ds_id)
            return entries

        def done_work(result):
            self.media_grid.items = result
            self.media_grid.bind()
            self.media_grid.tag = ds_id
            self._loading_dialog.close()

        worker = Worker(do_work)
        worker.signals.result.connect(done_work)
        self._thread_pool.start(worker)
        self._loading_dialog.exec_()
Esempio n. 12
0
    def load(self):
        @work_exception
        def do_work():
            results = self.ds_dao.fetch_all_with_size()
            return results, None

        @gui_exception
        def done_work(result):
            data, error = result
            if error:
                raise error
            self.data_grid.data_source = data
            self.data_grid.bind()

        worker = Worker(do_work)
        worker.signals.result.connect(done_work)
        self.thread_pool.start(worker)
Esempio n. 13
0
    def gallery_files_dropped_slot(self, files: []):
        entries_list = []
        for file_path in files:
            vo = DatasetEntryVO()
            vo.file_path = file_path
            vo.file_size = os.path.getsize(file_path)
            vo.dataset = self._ds.id
            entries_list.append(vo)

        def do_work():
            self._ds_dao.add_entries(entries_list)

        def done_work():
            self.load()

        worker = Worker(do_work)
        worker.signals.result.connect(done_work)
        self._thread_pool.start(worker)
Esempio n. 14
0
    def export_labels_annots(self, dataset_vo: DatasetVO, export_format):

        selected_folder = str(
            QFileDialog.getExistingDirectory(None, "select the folder"))
        if selected_folder:

            @work_exception
            def do_work():
                annotations = self._annot_dao.fetch_labels(dataset_vo.id)
                return annotations, None

            @gui_exception
            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")

            worker = Worker(do_work)
            worker.signals.result.connect(done_work)
            self.thread_pool.start(worker)
Esempio n. 15
0
    def load_image_label(self):
        @work_exception
        def do_work():
            label=self._annot_dao.get_label(self.source.id)
            return label,None

        @gui_exception
        def done_work(result):
            label_name,error=result
            if error:
                raise error
            if label_name:
                self._label.setVisible(True)
                self._label.setText(label_name)
            else:
                self._label.setVisible(False)
                self._label.setText("")
        worker=Worker(do_work)
        worker.signals.result.connect(done_work)
        self._thread_pool.start(worker)
Esempio n. 16
0
    def download_annot_action_slot(self, vo: DatasetVO):
        @work_exception
        def do_work():
            results = self.annot_dao.fetch_all_by_dataset(vo.id)
            return results, None

        @gui_exception
        def done_work(result):
            data, error = result
            if error:
                raise error
            groups = itertools.groupby(data, lambda x: x["image"])
            annot_list = []
            for key, annotations in groups:
                image = ImageSchemeVO()
                image.path = key
                for annot_dict in list(annotations):
                    annot = AnnotSchemeVO()
                    annot.kind = annot_dict["annot_kind"]
                    annot.points = annot_dict["annot_points"]
                    annot.label_name = annot_dict["label_name"]
                    annot.label_color = annot_dict["label_color"]
                    image.regions.append(annot)
                annot_list.append(image)
            scheme = ImageScheme(many=True)
            options = QFileDialog.Options()
            options |= QFileDialog.DontUseNativeDialog
            default_file = os.path.join(os.path.expanduser('~'),
                                        "annotations.json")
            fileName, _ = QFileDialog.getSaveFileName(self,
                                                      "Export annotations",
                                                      default_file,
                                                      "Json Files (*.json)",
                                                      options=options)
            if fileName:
                with open(fileName, 'w') as f:
                    json.dump(scheme.dump(annot_list), f, indent=3)

        worker = Worker(do_work)
        worker.signals.result.connect(done_work)
        self.thread_pool.start(worker)
Esempio n. 17
0
    def load_images(self):
        @work_exception
        def do_work():
            entries = self._ds_dao.fetch_entries(self.source.dataset)
            return entries, None

        @gui_exception
        def done_work(result):
            data, error = result
            selected_item = None
            for vo in data:
                item = CustomListWidgetItem(vo.file_path)
                item.tag = vo
                if vo.file_path == self.source.file_path:
                    selected_item = item
                self.images_list_widget.addItem(item)
                self.images_list_widget.setCurrentItem(selected_item)

        worker = Worker(do_work)
        worker.signals.result.connect(done_work)
        self._thread_pool.start(worker)
Esempio n. 18
0
    def change_image_labels(self, label: LabelVO):
        items = self.images_list_widget.selectedItems()
        selected_images = []
        for item in items:
            vo = item.tag
            selected_images.append(vo)

        @work_exception
        def do_work():
            self._ds_dao.tag_entries(selected_images, label)
            return 1, None

        @gui_exception
        def done_work(result):
            status, err = result
            if err:
                raise err

        worker = Worker(do_work)
        worker.signals.result.connect(done_work)
        self._thread_pool.start(worker)
    def add_repository(self, repo_path):
        @work_exception
        def do_work():
            hub_client = HubClientFactory.create(Framework.PyTorch)
            hub = hub_client.fetch_model(repo_path, force_reload=True)
            id = self._hub_dao.save(hub)
            hub.id = id
            return hub, None

        @gui_exception
        def done_work(result):
            self._loading_dialog.close()
            hub, error = result
            if error:
                raise error
            self.treeview_models.add_node(hub)

        worker = Worker(do_work)
        worker.signals.result.connect(done_work)
        self._thread_pool.start(worker)
        self._loading_dialog.exec_()
Esempio n. 20
0
    def load_image_annotations(self):
        @work_exception
        def do_work():
            results = self._annot_dao.fetch_all(self.source.id)
            return results, None

        @gui_exception
        def done_work(result):
            result, error = result
            if error:
                raise error
            img_bbox: QRectF = self.viewer.pixmap.sceneBoundingRect()
            offset = QPointF(img_bbox.width() / 2, img_bbox.height() / 2)
            for entry in result:
                try:
                    vo: AnnotaVO = entry
                    points = map(float, vo.points.split(","))
                    points = list(more_itertools.chunked(points, 2))
                    if vo.kind == "box":
                        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)
                        rect = EditableBox(roi)
                        rect.label = vo.label
                        self.viewer.scene().addItem(rect)
                    elif vo.kind == "polygon":
                        polygon = EditablePolygon()
                        polygon.label = vo.label
                        self.viewer.scene().addItem(polygon)
                        for p in points:
                            polygon.addPoint(
                                QPoint(p[0] - offset.x(), p[1] - offset.y()))
                except Exception as ex:
                    print(ex)

        worker = Worker(do_work)
        worker.signals.result.connect(done_work)
        self._thread_pool.start(worker)
Esempio n. 21
0
    def add_repository(self):
        @work_exception
        def do_work(repo):
            hub_client = HubClientFactory.create(Framework.PyTorch)
            hub = hub_client.fetch_model(repo, force_reload=True)
            self._hub_dao.save(hub)
            return hub, None

        @gui_exception
        def done_work(result):
            self._loading_dialog.close()
            data, error = result
            if error is None:
                self.treeview_models.add_node(data)

        form = NewRepoForm()
        if form.exec_() == QDialog.Accepted:
            repository = form.result
            worker = Worker(do_work, repository)
            worker.signals.result.connect(done_work)
            self._thread_pool.start(worker)
            self._loading_dialog.exec_()
    def save_annotations(self, done_work_callback):
        scene: QGraphicsScene = self.image_viewer.scene()
        annotations = []
        for item in scene.items():
            image_rect: QRectF = self.image_viewer.pixmap.sceneBoundingRect()
            image_offset = QPointF(image_rect.width() / 2,
                                   image_rect.height() / 2)
            if isinstance(item, EditableItem):
                a = AnnotaVO()
                a.label = item.label.id if item.label else None
                a.entry = self.tag.id
                a.kind = item.shape_type
                a.points = item.coordinates(image_offset)
                annotations.append(a)

        @work_exception
        def do_work():
            self._ann_dao.save(self.tag.id, annotations)
            return None, None

        worker = Worker(do_work)
        worker.signals.result.connect(done_work_callback)
        self._thread_pool.start(worker)
Esempio n. 23
0
    def load_images(self):
        def do_work():
            page = self._curr_page
            items = self._pages[page]

            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

            delayed_tasks = [
                dask.delayed(create_thumbnail)(item) for item in items
            ]
            images = dask.compute(*delayed_tasks)
            return images

        def done_work(images):
            for img in images:
                if img:
                    item, h, w, thumbnail, file_size, is_broken = img
                    image_card = ImageCard()
                    image_card.is_broken = is_broken
                    image_card.tag = item
                    image_card.source = thumbnail
                    image_card.file_path = item.file_path
                    image_size_str = size(
                        file_size,
                        system=alternative) if file_size > 0 else "0 MB"
                    image_card.label.setText(
                        "\n ({0}px / {1}px) \n {2}".format(
                            w, h, image_size_str))
                    image_card.setFixedHeight(240)
                    image_card.doubleClicked.connect(
                        self.gallery_card_double_click)
                    image_card.add_buttons(self.actions)
                    if self.actions:
                        image_card.actionClicked.connect(
                            lambda name, item: self.cardActionClicked.emit(
                                name, item))
                    self.center_layout.add_item(image_card)

        def finished_work():
            self._loading_dialog.close()
            self.enable_paginator(True)

        worker = Worker(do_work)
        worker.signals.result.connect(done_work)
        worker.signals.finished.connect(finished_work)
        self._thread_pool.start(worker)
        self.enable_paginator(False)
        self._loading_dialog.show()
Esempio n. 24
0
    def export_boxes_annots2pascal(self, dataset_vo: DatasetVO):

        output_folder = str(
            QFileDialog.getExistingDirectory(None, "select the folder"))
        if output_folder:
            output_folder = Path(output_folder)

            @dask.delayed
            def export_xml(img_path, img_annotations):
                str_template = '''
                   <annotation>
                       <folder>${folder}</folder>
                       <filename>${filename}</filename>
                       <path>${path}</path>
                       <source>
                           <database>Unknown</database>
                       </source>
                       <size>
                           <width>${width}</width>
                           <height>${height}</height>
                           <depth>${depth}</depth>
                       </size>
                       <segmented>0</segmented>
                       % for i, region in enumerate(annotations):
                           <object>
                               <name>${region["name"]}</name>
                               <pose>Unspecified</pose>
                               <truncated>0</truncated>
                               <difficult>0</difficult>
                               <bndbox>
                                   <xmin>${region["xmin"]}</xmin>
                                   <ymin>${region["ymin"]}</ymin>
                                   <xmax>${region["xmax"]}</xmax>
                                   <ymax>${region["ymax"]}</ymax>
                               </bndbox>
                           </object>
                       % endfor
                   </annotation>
                   '''
                img_path = Path(img_path)
                img_name = img_path.name
                img_stem = img_path.stem
                img: Image = Image.open(str(img_path))
                w, h = img.size
                c = len(img.getbands())

                xml_str = Template(str_template).render(
                    path=img_path,
                    folder=str(img_path.parent),
                    filename=img_name,
                    width=w,
                    height=h,
                    depth=c,
                    annotations=img_annotations)

                output_file = output_folder.joinpath("{}.xml".format(img_stem))
                with open(output_file, 'w') as f:
                    f.write(xml_str)

            @work_exception
            def do_work():
                annotations = self._annot_dao.fetch_boxes(dataset_vo.id)
                if annotations:
                    images = sorted(annotations, key=lambda ann: ann["image"])
                    images = itertools.groupby(images,
                                               key=lambda ann: ann["image"])
                    delayed_tasks = []
                    for img_path, img_annotations in images:
                        boxes = []
                        for annot in img_annotations:
                            points = list(
                                map(int, annot["annot_points"].split(",")))
                            box = dict()
                            box["name"] = annot["label_name"]
                            box["xmin"] = points[0]
                            box["ymin"] = points[1]
                            box["xmax"] = points[2]
                            box["ymax"] = points[3]
                            boxes.append(box)
                        if len(boxes) > 0:
                            delayed_tasks.append(export_xml(img_path, boxes))
                    dask.compute(*delayed_tasks)
                    return True, None
                else:
                    return False, None

            @gui_exception
            def done_work(result):
                success, err = result
                if err:
                    raise err
                if success:
                    GUIUtilities.show_info_message(
                        "Annotations exported successfully", "Done")
                else:
                    GUIUtilities.show_info_message(
                        "Not annotations found for the dataset {}".format(
                            dataset_vo.name), "Done")

            worker = Worker(do_work)
            worker.signals.result.connect(done_work)
            self.thread_pool.start(worker)
Esempio n. 25
0
    def autolabel(self, repo, model_name):
        def do_work():
            try:
                print(repo, model_name)
                from PIL import Image
                from torchvision import transforms
                import torch
                model = torch.hub.load(repo, model_name, pretrained=True)
                model.eval()
                input_image = Image.open(self.source.file_path)
                preprocess = transforms.Compose([
                    transforms.Resize(480),
                    transforms.ToTensor(),
                    transforms.Normalize(mean=[0.485, 0.456, 0.406],
                                         std=[0.229, 0.224, 0.225]),
                ])
                input_tensor = preprocess(input_image)
                input_batch = input_tensor.unsqueeze(
                    0)  # create a mini-batch as expected by the model
                # move the param and model to GPU for speed if available
                if torch.cuda.is_available():
                    input_batch = input_batch.to('cuda')
                    model.to('cuda')
                with torch.no_grad():
                    output = model(input_batch)['out'][0]
                output_predictions = output.argmax(0)
                # create a color pallette, selecting a color for each class
                palette = torch.tensor([2**25 - 1, 2**15 - 1, 2**21 - 1])
                colors = torch.as_tensor([i for i in range(21)
                                          ])[:, None] * palette
                colors = (colors % 255).numpy().astype("uint8")
                # plot the semantic segmentation predictions of 21 classes in each color
                predictions_array: np.ndarray = output_predictions.byte().cpu(
                ).numpy()
                predictions_image = Image.fromarray(predictions_array).resize(
                    input_image.size)
                predictions_image.putpalette(colors)
                labels_mask = np.asarray(predictions_image)
                classes = list(
                    filter(lambda x: x != 0,
                           np.unique(labels_mask).tolist()))
                classes_map = {c: [] for c in classes}
                for c in classes:
                    class_mask = np.zeros(labels_mask.shape, dtype=np.uint8)
                    class_mask[np.where(labels_mask == c)] = 255
                    contour_list = cv2.findContours(class_mask.copy(),
                                                    cv2.RETR_LIST,
                                                    cv2.CHAIN_APPROX_SIMPLE)
                    contour_list = imutils.grab_contours(contour_list)
                    for contour in contour_list:
                        points = np.vstack(contour).squeeze().tolist()
                        classes_map[c].append(points)
                return classes_map, None
            except Exception as ex:
                return None, ex

        def done_work(result):
            self._loading_dialog.close()
            classes_map, err = result
            if err:
                return
            for class_idx, contours in classes_map.items():
                for c in contours:
                    points = []
                    for i in range(0, len(c), 10):
                        points.append(c[i])
                    polygon = EditablePolygon()
                    self.viewer._scene.addItem(polygon)
                    bbox: QRectF = self.viewer.pixmap.boundingRect()
                    offset = QPointF(bbox.width() / 2, bbox.height() / 2)
                    for point in points:
                        polygon.addPoint(
                            QPoint(point[0] - offset.x(),
                                   point[1] - offset.y()))

        worker = Worker(do_work)
        worker.signals.result.connect(done_work)
        self._thread_pool.start(worker)
        self._loading_dialog.exec_()
Esempio n. 26
0
    def export_polygons_annots2png(self, dataset_vo: DatasetVO):
        selected_folder = str(
            QFileDialog.getExistingDirectory(None, "select the folder"))

        if selected_folder:
            selected_folder = Path(selected_folder)

            @work_exception
            def do_work():
                annotations = self._annot_dao.fetch_polygons(dataset_vo.id)
                if annotations:
                    color_palette = set(ann["label_color"]
                                        for ann in annotations)
                    color_palette = [
                        ColorUtilities.hex2RGB(c) for c in color_palette
                    ]
                    color_palette = np.asarray([[0, 0, 0]] + color_palette)
                    color_palette_flatten = color_palette.flatten()

                    labels_map = set(ann["label_name"] for ann in annotations)
                    labels_map = sorted(labels_map)

                    labels_map = {l: i + 1 for i, l in enumerate(labels_map)}
                    colors_map = {
                        l: color_palette.tolist()[i + 1]
                        for i, l in enumerate(labels_map)
                    }

                    images = sorted(annotations, key=lambda ann: ann["image"])
                    images = itertools.groupby(images,
                                               key=lambda ann: ann["image"])
                    for img_path, img_annotations in images:
                        image_name = Path(img_path).stem
                        image = Image.open(img_path).convert("RGB")
                        width, height = image.size
                        mask = Image.new("P", (width, height), 0)
                        mask.putpalette(color_palette_flatten.tolist())
                        for region in img_annotations:
                            label = region["label_name"]
                            points = region["annot_points"]
                            points = map(float, points.split(","))
                            points = list(
                                map(lambda pt: tuple(pt),
                                    more_itertools.chunked(points, 2)))
                            if len(points) > 0:
                                if label in labels_map:
                                    drawable_image = ImageDraw.Draw(mask)
                                    label_id = labels_map[label]
                                    drawable_image.polygon(points,
                                                           fill=label_id)
                                    del drawable_image
                        mask.save(
                            str(
                                selected_folder.joinpath(
                                    "{}.png".format(image_name))),
                            "PNG")  # export image

                    def dumper(obj):
                        try:
                            return obj.toJSON()
                        except:
                            return obj.__dict__

                    colors_map_file = selected_folder.joinpath(
                        "colors_map.json")
                    with open(str(colors_map_file), "w") as f:
                        f.write(
                            json.dumps(colors_map, default=dumper, indent=2))

                    labels_map_file = selected_folder.joinpath(
                        "labels_map.json")
                    with open(str(labels_map_file), "w") as f:
                        f.write(
                            json.dumps(labels_map, default=dumper, indent=2))

                return annotations, None

            @gui_exception
            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")

            worker = Worker(do_work)
            worker.signals.result.connect(done_work)
            self.thread_pool.start(worker)
Esempio n. 27
0
    def import_annot_action_slot(self, dataset_vo: DatasetVO):
        menu = QMenu()
        menu.setCursor(QtCore.Qt.PointingHandCursor)
        menu.addAction(self.PASCAL_VOC)
        action = menu.exec_(QCursor.pos())
        if action:
            action_text = action.text()
            if action_text == self.PASCAL_VOC:
                colors = ColorUtilities.rainbow_gradient(1000)["hex"]
                files = GUIUtilities.select_files(
                    ".xml", "Select the annotations files")
                if len(files) > 0:

                    @work_exception
                    def do_work():
                        annotations = []
                        for xml_file in files:
                            tree = ET.parse(xml_file)
                            root = tree.getroot()
                            objects = root.findall('object')
                            image_path = root.find('path').text
                            image_vo = self._ds_dao.find_by_path(
                                dataset_vo.id, image_path)
                            if image_vo:
                                for roi in objects:
                                    label_name = roi.find('name').text
                                    label_name = label_name.title()
                                    label_vo = self._labels_dao.find_by_name(
                                        dataset_vo.id, label_name)
                                    if label_vo is None:
                                        label_vo = LabelVO()
                                        label_vo.name = label_name
                                        label_vo.dataset = dataset_vo.id
                                        label_vo.color = colors[random.randint(
                                            0, len(colors))]
                                        label_vo = self._labels_dao.save(
                                            label_vo)
                                    box = roi.find("bndbox")
                                    if box:
                                        x1 = int(box.find('xmin').text)
                                        y1 = int(box.find('ymin').text)
                                        x2 = int(box.find('xmax').text)
                                        y2 = int(box.find('ymax').text)
                                        box = AnnotaVO()
                                        box.label = label_vo.id
                                        box.entry = image_vo.id
                                        box.kind = "box"
                                        box.points = ",".join(
                                            map(str, [x1, y1, x2, y2]))
                                        annotations.append(box)
                        if len(annotations) > 0:
                            print(annotations)
                            self._annot_dao.save(dataset_vo.id, annotations)
                        return annotations, None

                    @gui_exception
                    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")

                    worker = Worker(do_work)
                    worker.signals.result.connect(done_work)
                    self.thread_pool.start(worker)