Пример #1
0
 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)
Пример #2
0
    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)
Пример #3
0
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()
Пример #4
0
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
Пример #5
0
    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)
Пример #6
0
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()
Пример #7
0
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
Пример #8
0
 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
                })
Пример #10
0
 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
Пример #12
0
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()
Пример #13
0
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))
Пример #16
0
        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()
Пример #18
0
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()