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)
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)
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)
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()
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)
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)
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)
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_()
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)
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)
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)
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)
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)
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)
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_()
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)
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)
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()
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)
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_()
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)
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)