def inference(self, img, ann): labels = infer_on_image(image=img, model=self.model, idx_to_class=self.out_class_mapping, confidence_thresh=self.confidence_thresh, confidence_tag_meta=self.confidence_tag_meta, num_classes=len(self.class_title_to_idx)) return sly.Annotation(ann.img_size, labels=labels)
def inference(self, img, ann): h, w = img.shape[:2] # Resize to requested model input size input_image = sly.image.resize(img, self.input_size) input_image_var = np.expand_dims(input_image.astype(np.float32), 0) raw_pixelwise_probas_array = self.session.run(self.logits, feed_dict={self.inputs: input_image_var}) # Resize back to the original pixelwise_probas_array = cv2.resize(np.squeeze(raw_pixelwise_probas_array[0]), (w, h), cv2.INTER_LINEAR) labels = raw_to_labels.segmentation_array_to_sly_bitmaps(self.out_class_mapping, np.argmax(pixelwise_probas_array, axis=2)) pixelwise_scores_labels = raw_to_labels.segmentation_scores_to_per_class_labels(self.out_class_mapping, pixelwise_probas_array) return sly.Annotation(ann.img_size, labels=labels, pixelwise_scores_labels=pixelwise_scores_labels)
def inference(model, half, device, imgsz, stride, image: np.ndarray, meta: sly.ProjectMeta, conf_thres=0.25, iou_thres=0.45, augment=False, agnostic_nms=False, debug_visualization=False) -> sly.Annotation: names = model.module.names if hasattr(model, 'module') else model.names img0 = image # RGB # Padded resize img = letterbox(img0, new_shape=imgsz, stride=stride)[0] img = img.transpose(2, 0, 1) # to 3x416x416 img = np.ascontiguousarray(img) img = torch.from_numpy(img).to(device) img = img.half() if half else img.float() # uint8 to fp16/32 img /= 255.0 # 0 - 255 to 0.0 - 1.0 if img.ndimension() == 3: img = img.unsqueeze(0) inf_out = model(img, augment=augment)[0] # Apply NMS labels = [] output = non_max_suppression(inf_out, conf_thres=conf_thres, iou_thres=iou_thres, agnostic=agnostic_nms) for i, det in enumerate(output): if det is not None and len(det): det[:, :4] = scale_coords(img.shape[2:], det[:, :4], img0.shape).round() for *xyxy, conf, cls in reversed(det): top, left, bottom, right = int(xyxy[1]), int(xyxy[0]), int(xyxy[3]), int(xyxy[2]) rect = sly.Rectangle(top, left, bottom, right) obj_class = meta.get_obj_class(names[int(cls)]) tag = sly.Tag(meta.get_tag_meta(CONFIDENCE), round(float(conf), 4)) label = sly.Label(rect, obj_class, sly.TagCollection([tag])) labels.append(label) height, width = img0.shape[:2] ann = sly.Annotation(img_size=(height, width), labels=labels) if debug_visualization is True: # visualize for debug purposes vis = np.copy(img0) ann.draw_contour(vis, thickness=2) sly.image.write("vis.jpg", vis) return ann.to_json()
def visualize_dets(img_, output_, save_path_, names_, meta_): labels = [] for i, det in enumerate(output_): if det is not None and len(det): for *xyxy, conf, cls in reversed(det): left, top, right, bottom = int(xyxy[0]), int(xyxy[1]), int( xyxy[2]), int(xyxy[3]) rect = sly.Rectangle(top, left, bottom, right) obj_class = meta_.get_obj_class(names_[int(cls)]) tag = sly.Tag(meta_.get_tag_meta("confidence"), round(float(conf), 4)) label = sly.Label(rect, obj_class, sly.TagCollection([tag])) labels.append(label) width, height = img_.size ann = sly.Annotation(img_size=(height, width), labels=labels) vis = np.copy(img_) ann.draw_contour(vis, thickness=2) sly.image.write(save_path_, vis) return vis
def inference(self, img, ann): # Resize the image to the dimenstions the model has been trained on. # Even though the model preserves input dimensionality and in principle can be used with the full-size original # input directly, it is better to resize to preserve the scale of image features consistent with what the model # has seen during training. img_resized = sly.image.resize(img, self.input_size) # Height x Width x Channels -> Channels x Height x Width (pytorch convention), conversion to float, # change intensity range from 0...255 to 0...1 img_chw = to_tensor(img_resized) # Add a dummy batch dimension. img_bchw = img_chw[None, ...] # Copy the data to the GPU to feed the model for inference. with torch.no_grad(): model_input_cuda = Variable(img_bchw).cuda() # Run inference. class_scores_cuda = self._model(model_input_cuda) # Copy inference results back to CPU RAM, drop the batch dimension. class_scores = np.squeeze(class_scores_cuda.data.cpu().numpy(), axis=0) # Reorder dimensions back to the common Height x Width x Channels format. class_scores_hwc = np.transpose(class_scores, [1, 2, 0]) # Resize back to the original size. Use nearest neighbor interpolation to avoid interpolation artifacts in the # scores space. class_scores_original_size = sly.image.resize_inter_nearest(class_scores_hwc, out_size=img.shape[:2]) # Find the most likely class ID for every pixel. class_ids = np.argmax(class_scores_original_size, axis=2) # Convert the raw segmentation array to supervisely labels, one per output class. labels = raw_to_labels.segmentation_array_to_sly_bitmaps(idx_to_class=self.out_class_mapping, pred=class_ids) # Wrap the resulting labels into an image annotation and return. return sly.Annotation(img_size=img.shape[:2], labels=labels)
def convert(): img_dir = join(sly.TaskPaths.DATA_DIR, IMAGE_DIR_NAME) ann_dir = join(sly.TaskPaths.DATA_DIR, ANNOTATION_DIR_NAME) tasks_settings = json.load(open(sly.TaskPaths.SETTINGS_PATH, 'r')) classes_mapping = DEFAULT_CLASSES_MAPPING if CLASSES_MAPPING_KEY in tasks_settings[OPTIONS]: classes_mapping = tasks_settings[OPTIONS][CLASSES_MAPPING_KEY] else: sly.logger.warn('Classes mapping not found. Set to default: {}'.format(str(DEFAULT_CLASSES_MAPPING))) pr = sly.Project(os.path.join(sly.TaskPaths.RESULTS_DIR, tasks_settings['res_names']['project']), sly.OpenMode.CREATE) obj_class_collection = create_obj_class_collection(classes_mapping) pr_meta = sly.ProjectMeta(obj_classes=obj_class_collection) pr.set_meta(pr_meta) ds = pr.create_dataset(DATASET_NAME) images_pathes = sly.fs.list_files(img_dir) masks_pathes = sly.fs.list_files(ann_dir) masks_map = {sly.fs.get_file_name(mask_p): mask_p for mask_p in masks_pathes} progress = sly.Progress('Dataset: {!r}'.format(DATASET_NAME), len(images_pathes)) for img_fp in images_pathes: full_img_fp = join(img_dir, img_fp) image = read_image_pillow(full_img_fp) image_name = sly.fs.get_file_name(full_img_fp) ann = sly.Annotation(image.shape[:2]) if image_name not in masks_map: sly.logger.warning('Mask for image {} doesn\'t exist.'.format(image_name)) else: full_mask_fp = join(ann_dir, masks_map[image_name]) labels = read_mask_labels(full_mask_fp, classes_mapping, obj_class_collection) ann = ann.add_labels(labels) ds.add_item_np(image_name, image, img_ext=sly.fs.get_file_ext(full_img_fp), ann=ann) progress.iter_done_report()
def synthesize(api: sly.Api, task_id, state, meta: sly.ProjectMeta, image_infos, labels, bg_images, cache_dir, preview=True): progress_cb = refresh_progress_preview if preview is False: progress_cb = refresh_progress augs = yaml.safe_load(state["augs"]) sly.logger.info("Init augs from yaml file") aug.init_fg_augs(augs) visibility_threshold = augs['objects'].get('visibility', 0.8) classes = state["selectedClasses"] bg_info = random.choice(bg_images) sly.logger.info("Download background") bg = api.image.download_np(bg_info.id) sly.logger.debug(f"BG shape: {bg.shape}") res_image = bg.copy() res_labels = [] # sequence of objects that will be generated res_classes = [] to_generate = [] for class_name in classes: original_class: sly.ObjClass = meta.get_obj_class(class_name) res_classes.append(original_class.clone(geometry_type=sly.Bitmap)) count_range = augs["objects"]["count"] count = random.randint(*count_range) for i in range(count): to_generate.append(class_name) random.shuffle(to_generate) res_meta = sly.ProjectMeta(obj_classes=sly.ObjClassCollection(res_classes)) progress = sly.Progress("Processing foregrounds", len(to_generate)) progress_cb(api, task_id, progress) progress_every = max(10, int(len(to_generate) / 20)) cover_img = np.zeros(res_image.shape[:2], np.int32) # size is (h, w) objects_area = defaultdict(lambda: defaultdict(float)) cached_images = {} # generate objects for idx, class_name in enumerate(to_generate, start=1): if class_name not in labels: progress.iter_done_report() continue image_id = random.choice(list(labels[class_name].keys())) label: sly.Label = random.choice(labels[class_name][image_id]) if image_id in cached_images: source_image = cached_images[image_id] else: image_info = image_infos[image_id] source_image = _get_image_using_cache(api, cache_dir, image_id, image_info) cached_images[image_id] = source_image label_img, label_mask = get_label_foreground(source_image, label) #sly.image.write(os.path.join(cache_dir, f"{index}_label_img.png"), label_img) #sly.image.write(os.path.join(cache_dir, f"{index}_label_mask.png"), label_mask) label_img, label_mask = aug.apply_to_foreground(label_img, label_mask) #sly.image.write(os.path.join(cache_dir, f"{index}_aug_label_img.png"), label_img) #sly.image.write(os.path.join(cache_dir, f"{index}_aug_label_mask.png"), label_mask) label_img, label_mask = aug.resize_foreground_to_fit_into_image( res_image, label_img, label_mask) #label_area = g.area find_place = False for attempt in range(3): origin = aug.find_origin(res_image.shape, label_mask.shape) g = sly.Bitmap(label_mask[:, :, 0].astype(bool), origin=sly.PointLocation(row=origin[1], col=origin[0])) difference = count_visibility(cover_img, g, idx, origin[0], origin[1]) allow_placement = True for object_idx, diff in difference.items(): new_area = objects_area[object_idx]['current'] - diff visibility_portion = new_area / objects_area[object_idx][ 'original'] if visibility_portion < visibility_threshold: #sly.logger.warn(f"Object '{idx}', attempt {attempt + 1}: " # f"visible portion ({visibility_portion}) < threshold ({visibility_threshold})") allow_placement = False break if allow_placement is True: find_place = True break else: continue if find_place is False: sly.logger.warn( f"Object '{idx}' is skipped: can not be placed to satisfy visibility threshold" ) continue try: aug.place_fg_to_bg(label_img, label_mask, res_image, origin[0], origin[1]) g.draw(cover_img, color=idx) for object_idx, diff in difference.items(): objects_area[object_idx]['current'] -= diff current_obj_area = g.area objects_area[idx]['current'] = current_obj_area objects_area[idx]['original'] = current_obj_area res_labels.append(sly.Label(g, res_meta.get_obj_class(class_name))) except Exception as e: #sly.logger.warn(repr(e)) sly.logger.warn( f"FG placement error:: label shape: {label_img.shape}; mask shape: {label_mask.shape}", extra={"error": repr(e)}) progress.iter_done_report() if idx % progress_every == 0: # progress.need_report(): progress_cb(api, task_id, progress) progress_cb(api, task_id, progress) res_ann = sly.Annotation(img_size=bg.shape[:2], labels=res_labels) # debug visualization # sly.image.write(os.path.join(cache_dir, "__res_img.png"), res_image) #res_ann.draw(res_image) #sly.image.write(os.path.join(cache_dir, "__res_ann.png"), res_image) res_meta, res_ann = rasterize.convert_to_nonoverlapping(res_meta, res_ann) return res_image, res_ann, res_meta
def inference(self, img, ann): labels = infer_rectangles(img, self.detection_graph, self.session, self.out_class_mapping, self.confidence_thresh, self.confidence_tag_meta) return sly.Annotation(ann.img_size, labels=labels)
ann_info = api.video.annotation.download(video_info.id) ann = sly.VideoAnnotation.from_json(ann_info, meta, key_id_map) progress = sly.Progress("Video: {!r}".format(video_info.name), len(ann.frames)) image_names = [] frame_images = [] dst_anns = [] for frame in ann.frames: image_names.append('{}_frame_{:05d}.png'.format( name, frame.index)) frame_images.append( api.video.frame.download_np(video_info.id, frame.index)) labels = [ sly.Label(figure.geometry, figure.parent_object.obj_class) for figure in frame.figures ] dst_anns.append(sly.Annotation(ann.img_size, labels=labels)) if len(image_names) > 10: upload_and_reset(dst_dataset.id, image_names, frame_images, dst_anns, progress) upload_and_reset(dst_dataset.id, image_names, frame_images, dst_anns, progress) sly.logger.info('PROJECT_CREATED', extra={ 'event_type': sly.EventType.PROJECT_CREATED, 'project_id': dst_project.id })
def _raw_detections_to_ann(self, detections_raw, img_size): labels = common.yolo_preds_to_sly_rects( detections_raw, self.out_class_mapping, self.confidence_tag_meta) return sly.Annotation(img_size, labels=labels)
def extract_foreground(): api = sly.Api.from_env() task_id = int(os.getenv("TASK_ID")) try: if DEBUG: sly.fs.mkdir(const.DEBUG_VIS_DIR) sly.fs.clean_dir(const.DEBUG_VIS_DIR) state = api.task.get_data(task_id, field=const.STATE) project = api.task.get_data(task_id, field="{}.projects[{}]".format( const.DATA, state[const.PROJECT_INDEX])) project_id = project["id"] workspace_id = api.project.get_info_by_id(project_id).workspace_id team_id = api.workspace.get_info_by_id(workspace_id).team_id processed_items = [] api.task.set_data(task_id, payload=processed_items, field="{}.{}".format(const.DATA, const.TABLE)) # sample images all_images = [] for dataset in api.dataset.get_list(project_id): images = api.image.get_list(dataset.id) image_dataset = [dataset] * len(images) all_images.extend(zip(images, image_dataset)) # read sample count if state[const.SAMPLE_FLAG]: cnt_images = state[const.SAMPLE_COUNT] assert cnt_images <= len(all_images) random.shuffle(all_images) all_images = all_images[:cnt_images] fg_class, st_class = set_project_meta(api, project_id, state) sly.fs.mkdir(const.CACHE_DIR) for idx, (image_info, dataset_info) in enumerate(all_images): table_row = {} image_id = image_info.id table_row['id'] = image_id sly.logger.debug("---> image_id = {}".format(image_id)) if DEBUG: debug_img_dir = os.path.join(const.DEBUG_VIS_DIR, str(image_id)) sly.fs.mkdir(debug_img_dir) image_url = api.image.url(team_id, workspace_id, project_id, dataset_info.id, image_id) table_row['name'] = '<a href="{0}" rel="noopener noreferrer" target="_blank">{1}</a>' \ .format(image_url, image_info.name) image_path = os.path.join(const.CACHE_DIR, "{}.png".format(image_id)) if not sly.fs.file_exists(image_path): api.image.download_path( image_id, image_path, ) image = sly.image.read(image_path, remove_alpha_channel=False) if image.shape[2] != 4: sly.logger.warning( "Image (id = {}) is skipped: it does not have alpha channel" .format(image_id)) continue if DEBUG: sly.image.write(os.path.join(debug_img_dir, '000_image.png'), image, remove_alpha_channel=False) alpha = image[:, :, 3] if DEBUG: sly.image.write(os.path.join(debug_img_dir, '001_alpha.png'), alpha) # extract foreground pixels mask = (alpha >= state[const.ALPHA_THRESHOLD]).astype( np.uint8) * 255 if DEBUG: sly.image.write(os.path.join(debug_img_dir, '002_mask.png'), mask) # create mask for all connected components mask_instances, num_cc = skimage.measure.label(mask, background=0, return_num=True) if DEBUG: vis = skimage.color.label2rgb(mask_instances, bg_label=0) sly.image.write(os.path.join(debug_img_dir, '003_mask_cc.png'), vis * 255) table_row['total objects'] = num_cc # remove small objects area_pixels = int(mask_instances.shape[0] * mask_instances.shape[1] / 100 * state[const.AREA_THRESHOLD]) mask_cleaned = skimage.morphology.remove_small_objects( mask_instances, area_pixels) mask_cleaned, num_cc = skimage.measure.label(mask_cleaned, background=0, return_num=True) if DEBUG: vis = skimage.color.label2rgb(mask_cleaned, bg_label=0) sly.image.write( os.path.join(debug_img_dir, '004_mask_cleaned.png'), vis * 255) cc_area = count_instances_area(mask_cleaned, num_cc) cc_area = cc_area[:state[const.MAX_NUMBER_OF_OBJECTS]] table_row['final objects'] = len(cc_area) labels = [] sly.logger.debug( "image_id = {}, number of extracted objects: {}".format( image_id, len(cc_area))) for cc_color, area in cc_area: object_mask = (mask_cleaned == cc_color) geometry = sly.Bitmap(data=object_mask) label = sly.Label(geometry, fg_class) labels.append(label) #find gray zone gray_zone = np.logical_and(alpha != 0, alpha != 255) if np.sum(gray_zone) != 0: #gray_zone is not empty gray_geometry = sly.Bitmap(data=gray_zone) gray_label = sly.Label(gray_geometry, st_class) labels.append(gray_label) table_row['gray area (%)'] = round( np.sum(gray_zone) * 100 / (gray_zone.shape[0] * gray_zone.shape[1]), 2) ann = sly.Annotation(mask.shape[:2], labels=labels) if DEBUG: render = np.zeros(ann.img_size + (3, ), dtype=np.uint8) ann.draw(render) sly.image.write(os.path.join(debug_img_dir, '005_ann.png'), render) api.annotation.upload_ann(image_id, ann) processed_items.append(table_row) #time.sleep(2) if (idx % const.NOTIFY_EVERY == 0 and idx != 0) or idx == len(all_images) - 1: api.task.set_data(task_id, payload=processed_items, field="{}.{}".format(const.DATA, const.TABLE), append=True) processed_items = [] update_progress(api, task_id, (idx + 1) * 100 / len(all_images)) need_stop = api.task.get_data(task_id, field="{}.{}".format( const.STATE, const.STOP_CLICKED)) if need_stop is True: reset_buttons_and_progress(api, task_id) sly.logger.info("SCRIPT IS STOPPED") exit(0) except Exception as e: sly.logger.critical('Unexpected exception', exc_info=True, extra={ 'event_type': sly.EventType.TASK_CRASHED, 'exc_str': str(e), }) sly.logger.debug('Script finished: ERROR') else: sly.logger.debug('Script finished: OK') finally: reset_buttons_and_progress(api, task_id) pass
def merge(api: sly.Api, task_id, context, state, app_logger): dst_project = api.project.create(workspace_id, dst_project_name, change_name_if_conflict=True) api.project.update_meta(dst_project.id, meta.to_json()) api.project.update_custom_data( dst_project.id, {"input_project": { "id": src_project.id, "name": src_project.name }}) progress = sly.Progress("Merging images", api.project.get_images_count(src_project.id)) for src_dataset in api.dataset.get_list(src_project.id): dst_dataset = api.dataset.create(dst_project.id, src_dataset.name) images = api.image.get_list(src_dataset.id) image_ids = [image_info.id for image_info in images] #image_names = [image_info.name for image_info in images] ann_infos = api.annotation.download_batch(src_dataset.id, image_ids) anns = [ sly.Annotation.from_json(ann_info.annotation, meta) for ann_info in ann_infos ] parts_ids = defaultdict(list) parts_top_left = defaultdict(list) parts_anns = defaultdict(list) max_height = defaultdict(int) max_width = defaultdict(int) for image_info, ann in zip(images, anns): real_name = image_info.name.split("___")[0] ext = sly.fs.get_file_ext(image_info.name) settings = image_info.name.split("___")[1] settings = settings.replace(ext, "") window_index = int(settings.split("_")[0]) window_top = int(settings.split("_")[1]) window_left = int(settings.split("_")[2]) original_name = "{}{}".format(real_name, ext) max_height[original_name] = max(max_height[original_name], window_top + ann.img_size[0]) max_width[original_name] = max(max_width[original_name], window_left + ann.img_size[1]) parts_ids[original_name].append(image_info.id) parts_top_left[original_name].append((window_top, window_left)) parts_anns[original_name].append(ann) for original_name in parts_ids.keys(): images = api.image.download_nps(src_dataset.id, parts_ids[original_name]) height = max_height[original_name] width = max_width[original_name] channels = images[0].shape[2] final_image = np.zeros((height, width, channels), dtype=np.uint8) final_ann = sly.Annotation(final_image.shape[:2]) for image_part, ann, (top, left) in zip(images, parts_anns[original_name], parts_top_left[original_name]): def _translate_label(label): shift_y = top shift_x = left return [label.translate(shift_y, shift_x)] ann = ann.transform_labels(_translate_label, new_size=final_image.shape[:2]) final_image[top:top + image_part.shape[0], left:left + image_part.shape[1], :] = image_part final_ann = final_ann.add_labels(ann.labels) final_ann = final_ann.clone( img_tags=final_ann.img_tags.merge_without_duplicates( ann.img_tags)) merged_image_info = api.image.upload_np(dst_dataset.id, original_name, final_image) api.annotation.upload_ann(merged_image_info.id, final_ann) progress.iters_done_report(len(images)) api.task.set_output_project(task_id, dst_project.id, dst_project.name) app.stop()
def convert(): img_dir = join(sly.TaskPaths.DATA_DIR, IMAGE_DIR_NAME) ann_dir = join(sly.TaskPaths.DATA_DIR, ANNOTATION_DIR_NAME) tasks_settings = load_json_file(sly.TaskPaths.TASK_CONFIG_PATH) classes_mapping = DEFAULT_CLASSES_MAPPING if CLASSES_MAPPING_KEY in tasks_settings[OPTIONS]: classes_mapping = tasks_settings[OPTIONS][CLASSES_MAPPING_KEY] else: sly.logger.warn('Classes mapping not found. Set to default: {}'.format( str(DEFAULT_CLASSES_MAPPING))) pr = sly.Project( os.path.join(sly.TaskPaths.RESULTS_DIR, tasks_settings['res_names']['project']), sly.OpenMode.CREATE) obj_class_collection = create_obj_class_collection(classes_mapping) pr_meta = sly.ProjectMeta(obj_classes=obj_class_collection) pr.set_meta(pr_meta) ds = pr.create_dataset(DATASET_NAME) images_pathes = sly.fs.list_files(img_dir) masks_pathes = sly.fs.list_files(ann_dir) masks_map = { sly.fs.get_file_name(mask_p): mask_p for mask_p in masks_pathes } progress = sly.Progress('Dataset: {!r}'.format(DATASET_NAME), len(images_pathes)) for img_fp in images_pathes: full_img_fp = join(img_dir, img_fp) try: image = read_image_pillow(full_img_fp) image_name = os.path.basename(full_img_fp) sample_name = sly.fs.get_file_name(full_img_fp) ann = sly.Annotation(image.shape[:2]) mask_name = masks_map.pop(sample_name, None) if mask_name is None: sly.logger.warning( 'Mask for image {} doesn\'t exist.'.format(sample_name)) else: full_mask_fp = join(ann_dir, mask_name) labels = read_mask_labels(full_mask_fp, classes_mapping, obj_class_collection) ann = ann.add_labels(labels) ds.add_item_np(image_name, image, ann=ann) except Exception as e: exc_str = str(e) sly.logger.warn( 'Input sample skipped due to error: {}'.format(exc_str), exc_info=True, extra={ 'exc_str': exc_str, 'image': full_img_fp }) progress.iter_done_report() if len(masks_map) > 0: masks_list = list(masks_map.values()) sly.logger.warning( 'Images for masks doesn\'t exist. Masks: {}'.format(masks_list))
def transform(api: sly.Api, task_id, context, state, app_logger): storage_dir = my_app.data_dir project = api.project.create(WORKSPACE_ID, PROJECT_NAME, change_name_if_conflict=True) dataset = api.dataset.create(project.id, DATASET_NAME, change_name_if_conflict=True) local_file = os.path.join(storage_dir, sly.fs.get_file_name_with_ext(INPUT_FILE)) api.file.download(TEAM_ID, INPUT_FILE, local_file) tag_names = set() movies_info = [] with open(local_file, encoding="ISO-8859-1") as f: reader = csv.DictReader(f) for row in reader: movies_info.append(row) tag_names.update(parse_genres(row["Genre"])) tags_arr = [ sly.TagMeta(name=tag_name, value_type=sly.TagValueType.NONE) for tag_name in tag_names ] project_meta = sly.ProjectMeta(tag_metas=sly.TagMetaCollection( items=tags_arr)) api.project.update_meta(project.id, project_meta.to_json()) movies_info_len = len(movies_info) movies_info_len_digits = len(str(movies_info_len)) batch_size = 50 progress = sly.Progress('Uploading images', movies_info_len, app_logger) for batch_idx, batch in enumerate( sly._utils.batched(movies_info, batch_size)): image_paths = [] image_names = [] image_metas = [] csv_rows = [] for idx, csv_row in enumerate(batch): image_url = csv_row["Poster"] cur_img_ext = os.path.splitext(image_url)[1] cur_img_idx = str(batch_idx * batch_size + idx + 1).rjust( movies_info_len_digits, '0') image_name = f"{cur_img_idx}{cur_img_ext}" local_path = os.path.join(storage_dir, image_name) try: download_file(image_url, local_path, app_logger, batch_idx * batch_size + idx, movies_info_len) except: app_logger.warn( f"Couldn't download image:(row={batch_idx*batch_size+idx}, url={image_url}" ) continue csv_rows.append(csv_row) image_paths.append(local_path) image_names.append(image_name) image_metas.append({ "Title": csv_row["Title"], "imdbId": csv_row["imdbId"], "IMDB Score": csv_row["IMDB Score"], "Imdb Link": csv_row["Imdb Link"].replace('title/tt', 'title/tt0') }) images = api.image.upload_paths(dataset.id, image_names, image_paths, metas=image_metas) cur_anns = [] for image, csv_row in zip(images, csv_rows): tags_arr = [] image_tags = parse_genres(csv_row["Genre"]) if len(image_tags) == 0: continue for image_tag in image_tags: tag_meta = project_meta.get_tag_meta(image_tag) tags_arr.append(sly.Tag(tag_meta)) tags_arr = sly.TagCollection(items=tags_arr) ann = sly.Annotation(img_size=(image.height, image.width), img_tags=tags_arr) cur_anns.append((image.id, ann)) if len(cur_anns) > 0: img_ids = [img_id for img_id, ann in cur_anns] anns = [ann for img_id, ann in cur_anns] api.annotation.upload_anns(img_ids, anns) progress.iters_done_report(len(batch)) api.task.set_output_project(task_id, project.id, project.name) my_app.stop()
def process_coco_dir(input_dir, project, project_meta, api, config_yaml_info, app_logger): for dataset_type, dataset_path in config_yaml_info["datasets"]: tag_meta = project_meta.get_tag_meta(dataset_type) dataset_name = os.path.basename(dataset_path) images_list = sorted( sly.fs.list_files(dataset_path, valid_extensions=sly.image.SUPPORTED_IMG_EXTS)) if len(images_list) == 0: raise Exception( "Dataset: {!r} is empty. Check {!r} directory in project folder" .format(dataset_name, dataset_path)) dataset = api.dataset.create(project.id, dataset_name, change_name_if_conflict=True) progress = sly.Progress("Processing {} dataset".format(dataset_name), len(images_list), sly.logger) for batch in sly._utils.batched(images_list): cur_img_names = [] cur_img_paths = [] cur_anns = [] for image_file_name in batch: image_name = os.path.basename(image_file_name) cur_img_names.append(image_name) cur_img_paths.append(image_file_name) ann_file_name = os.path.join( input_dir, "labels", dataset_name, "{}.txt".format(os.path.splitext(image_name)[0])) curr_img = sly.image.read(image_file_name) height, width = curr_img.shape[:2] labels_arr = [] if os.path.isfile(ann_file_name): with open(ann_file_name, "r") as f: for idx, line in enumerate(f): try: label = parse_line(line, width, height, project_meta, config_yaml_info) labels_arr.append(label) except Exception as e: app_logger.warn( e, { "filename": ann_file_name, "line": line, "line_num": idx }) tags_arr = sly.TagCollection(items=[sly.Tag(tag_meta)]) ann = sly.Annotation(img_size=(height, width), labels=labels_arr, img_tags=tags_arr) cur_anns.append(ann) img_infos = api.image.upload_paths(dataset.id, cur_img_names, cur_img_paths) img_ids = [x.id for x in img_infos] api.annotation.upload_anns(img_ids, cur_anns) progress.iters_done_report(len(batch))
max_height[original_name] = max(max_height[original_name], window_top + ann.img_size[0]) max_width[original_name] = max(max_width[original_name], window_left + ann.img_size[1]) parts_ids[original_name].append(image_info.id) parts_top_left[original_name].append((window_top, window_left)) parts_anns[original_name].append(ann) for original_name in parts_ids.keys(): images = api.image.download_nps(src_dataset.id, parts_ids[original_name]) height = max_height[original_name] width = max_width[original_name] channels = images[0].shape[2] final_image = np.zeros((height, width, channels), dtype=np.uint8) final_ann = sly.Annotation(final_image.shape[:2]) for image_part, ann, (top, left) in zip(images, parts_anns[original_name], parts_top_left[original_name]): def _translate_label(label): shift_y = top shift_x = left return [label.translate(shift_y, shift_x)] ann = ann.transform_labels(_translate_label, new_size=final_image.shape[:2]) final_image[top:top + image_part.shape[0], left:left + image_part.shape[1], :] = image_part final_ann = final_ann.add_labels(ann.labels) final_ann = final_ann.clone(img_tags=final_ann.img_tags.
def turn_into_images_project(api: sly.Api, task_id, context, state, app_logger): res_project_name = f"{g.project.name}(images)" dst_project = api.project.create(g.WORKSPACE_ID, res_project_name, type=sly.ProjectType.IMAGES, change_name_if_conflict=True) api.project.update_meta(dst_project.id, g.meta.to_json()) key_id_map = KeyIdMap() for dataset_name in g.SELECTED_DATASETS: dataset = api.dataset.get_info_by_name(g.PROJECT_ID, dataset_name) dst_dataset = api.dataset.create(dst_project.id, dataset.name) videos = api.video.get_list(dataset.id) for batch in sly.batched(videos): for video_info in batch: general_time = time() ann_info = api.video.annotation.download(video_info.id) ann = sly.VideoAnnotation.from_json(ann_info, g.meta, key_id_map) if g.OPTIONS == "annotated" and len(ann.tags) == 0 and len( ann.frames) == 0: g.my_app.logger.warn( f"Video {video_info.name} annotation is empty in Dataset {dataset_name}" ) continue need_download_video = f.need_download_video( video_info.frames_count, len(ann.frames)) video_path = None if need_download_video or g.OPTIONS == "all": local_time = time() video_path = os.path.join(g.video_dir, video_info.name) progress_cb = f.get_progress_cb( "Downloading video", int(video_info.file_meta['size']), is_size=True) api.video.download_path(video_info.id, video_path, progress_cb=progress_cb) g.logger.info( f'video {video_info.name} downloaded in {time() - local_time} seconds' ) frames_to_convert = [] video_props = [] video_frame_tags = defaultdict(list) f.convert_tags(ann.tags, video_props, video_frame_tags, frames_to_convert) object_frame_tags = defaultdict(lambda: defaultdict(list)) object_props = defaultdict(list) for vobject in ann.objects: f.convert_tags(vobject.tags, object_props[vobject.key()], object_frame_tags[vobject.key()], frames_to_convert) vobject_id = key_id_map.get_object_id(vobject.key()) f.add_object_id_tag(vobject_id, object_props[vobject.key()]) if g.OPTIONS == "annotated": frames_to_convert.extend(list(ann.frames.keys())) frames_to_convert = list(dict.fromkeys(frames_to_convert)) frames_to_convert.sort() else: frames_to_convert = list(range(0, video_info.frames_count)) progress = sly.Progress( "Processing video frames: {!r}".format(video_info.name), len(frames_to_convert)) # total_images_size = 0 for batch_index, batch_frames in enumerate( sly.batched(frames_to_convert, batch_size=g.BATCH_SIZE)): metas = [] anns = [] if need_download_video or g.OPTIONS == "all": local_time = time() images_names, images = f.get_frames_from_video( video_info.name, video_path, batch_frames) g.logger.debug( f'extracted {len(batch_frames)} by {time() - local_time} seconds' ) """ too slow calculations, for extreme debug images_size = f.calculate_batch_size(images) / (1024 * 1024) # in MegaBytes g.logger.debug(f'batch size: {images_size} MB') g.logger.debug(f'mean item size: {images_size / len(images)} MB') total_images_size += images_size """ else: images_names, images = f.get_frames_from_api( api, video_info.id, video_info.name, batch_frames) for frame_index in batch_frames: metas.append({ "video_id": video_info.id, "video_name": video_info.name, "frame_index": frame_index, "video_dataset_id": video_info.dataset_id, "video_dataset_name": dataset.name, "video_project_id": g.project.id, "video_project_name": g.project.name }) labels = [] frame_annotation = ann.frames.get(frame_index) if frame_annotation is not None: for figure in frame_annotation.figures: tags_to_assign = object_props[ figure.parent_object.key()].copy() tags_to_assign.extend(object_frame_tags[ figure.parent_object.key()].get( frame_index, []).copy()) cur_label = sly.Label( figure.geometry, figure.parent_object.obj_class, sly.TagCollection(tags_to_assign)) labels.append(cur_label) img_tags = video_props.copy() + video_frame_tags.get( frame_index, []).copy() anns.append( sly.Annotation( ann.img_size, labels=labels, img_tags=sly.TagCollection(img_tags))) if g.LOG_LEVEL == 'debug': f.distort_frames(images) g.logger.debug(f'{len(images)} frames distorted') f.upload_frames( api, dst_dataset.id, images_names, images, anns, metas, f'{batch_index}/{int(len(frames_to_convert) / g.BATCH_SIZE)}' ) progress.iters_done_report(len(images_names)) # g.logger.debug(f'total images size for video: {total_images_size} MB') g.logger.info( f'video {video_info.name} converted in {time() - general_time} seconds' ) g.my_app.stop()
def convert(): settings = json.load(open(sly.TaskPaths.TASK_CONFIG_PATH)) tag_metas = sly.TagMetaCollection() out_project = sly.Project( os.path.join(sly.TaskPaths.RESULTS_DIR, settings['res_names']['project']), sly.OpenMode.CREATE) requested_tags = settings.get("options", {}).get("tags", []) if len(requested_tags) != len(set(requested_tags)): raise ValueError( 'Duplicate values detected in the list of requested tags: {}'. format(requested_tags)) skipped_count = 0 samples_count = 0 for ds_name, folder_path in get_datasets_names_and_paths(): dataset = None # Process all files in current folder filenames_in_folder = sly.fs.list_files(folder_path) dataset_progress = sly.Progress('Dataset {!r}'.format(ds_name), len(filenames_in_folder)) for dicom_filename in filenames_in_folder: try: # Read DICOM file dicom_obj = pydicom.dcmread(dicom_filename) # Extract tags tags_and_metas = get_tags_from_dicom_object( dicom_obj, requested_tags) # Extract images (DICOM file may contain few images) base_name = os.path.basename(dicom_filename) images = extract_images_from_dicom(dicom_obj, dicom_filename) for image_index, image in enumerate(images): sample_name = base_name if len(images) > 1: sample_name = base_name + '__{:04d}'.format( image_index) samples_count += 1 ann = sly.Annotation(img_size=image.shape[:2]) # Save tags for tag, tag_meta in tags_and_metas: ann = ann.add_tag(tag) if tag_meta not in tag_metas: tag_metas = tag_metas.add(tag_meta) # Save annotations if dataset is None: dataset = out_project.create_dataset(ds_name) dataset.add_item_np(sample_name + '.png', image, ann=ann) except Exception as e: exc_str = str(e) sly.logger.warn( 'Input sample skipped due to error: {}'.format(exc_str), exc_info=True, extra={ 'exc_str': exc_str, 'dataset_name': ds_name, 'image_name': dicom_filename, }) skipped_count += 1 dataset_progress.iter_done_report() sly.logger.info('Processed.', extra={ 'samples': samples_count, 'skipped': skipped_count }) if out_project.total_items == 0: raise RuntimeError( 'Result project is empty! All input DICOM files have unreadable format!' ) out_meta = sly.ProjectMeta(tag_metas=tag_metas) out_project.set_meta(out_meta)
def generate(api: sly.Api, task_id, context, state, app_logger): global PRODUCT_TAGS products_count = len(PRODUCTS.keys()) train_count = state["trainCount"] val_count = state["valCount"] total_count = products_count * (train_count + val_count) augs_settings = yaml.safe_load(state["augs"]) augs.init_fg_augs(augs_settings) PRODUCT_TAGS = PRODUCT_TAGS.add_items([TRAIN_TAG, VAL_TAG]) res_meta = sly.ProjectMeta( obj_classes=sly.ObjClassCollection([RESULT_CLASS]), tag_metas=PRODUCT_TAGS ) res_project = api.project.create(WORKSPACE_ID, state["outputProjectName"], change_name_if_conflict=True) api.project.update_meta(res_project.id, res_meta.to_json()) progress = sly.Progress("Generating", total_count) for product_id in PRODUCTS.keys(): dataset = api.dataset.create(res_project.id, str(product_id)) tag_meta = PRODUCT_TAGS.get(product_id) if tag_meta is None: raise ValueError(f"TagMeta {product_id} not found") # cache images for one product images = {} for image_id in PRODUCTS[product_id].keys(): images[image_id] = sly.image.read(IMAGE_PATH[image_id]) name_index = 0 for batch in sly.batched([TRAIN_TAG] * train_count + [VAL_TAG] * val_count, batch_size=10): final_images = [] final_anns = [] final_names = [] for tag in batch: image_id = random.choice(list(PRODUCTS[product_id].keys())) img = images[image_id] ann = random.choice(list(PRODUCTS[product_id][image_id])) label_image = None label_mask = None label_preview = None retry_count = 5 for retry_idx in range(5): try: label_image, label_mask, label_preview = \ try_generate_example( augs_settings, augs, preview=True, product_id=product_id, img=img, ann=ann ) break except Exception as e: if retry_idx == retry_count - 1: raise e continue res_ann = sly.Annotation(label_image.shape[:2], labels=[label_preview], img_tags=sly.TagCollection([tag, sly.Tag(tag_meta)])) final_images.append(label_image) final_anns.append(res_ann) final_names.append("{:05d}.jpg".format(name_index)) name_index += 1 new_images = api.image.upload_nps(dataset.id, final_names, final_images) new_image_ids = [image_info.id for image_info in new_images] api.annotation.upload_anns(new_image_ids, final_anns) progress.iters_done_report(len(batch)) refresh_progress(api, task_id, progress) refresh_progress(api, task_id, progress) res_project = api.project.get_info_by_id(res_project.id) fields = [ {"field": "data.started", "payload": False}, {"field": "data.resProjectId", "payload": res_project.id}, {"field": "data.resProjectName", "payload": res_project.name}, {"field": "data.resProjectPreviewUrl", "payload": api.image.preview_url(res_project.reference_image_url, 100, 100)}, ] api.task.set_fields(task_id, fields) api.task.set_output_project(task_id, res_project.id, res_project.name) app.stop()