Ejemplo n.º 1
0
def get_ann(img_path, inst_path):
    global classes_dict
    ann = sly.Annotation.from_img_path(img_path)
    instance_img = sly.image.read(inst_path)
    img_gray = cv2.cvtColor(instance_img, cv2.COLOR_BGR2GRAY)
    _, mask_foreground = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY)
    mask_background = (img_gray == 0)
    class_name = 'background'
    color = [1, 1, 1]
    bitmap = sly.Bitmap(data=mask_background)
    if not classes_dict.has_key(class_name):
        obj_class = sly.ObjClass(name=class_name,
                                 geometry_type=sly.Bitmap,
                                 color=color)
        classes_dict = classes_dict.add(obj_class)
    ann = ann.add_label(sly.Label(bitmap, classes_dict.get(class_name)))
    mask_foreground = mask_foreground.astype(np.bool)
    if np.any(mask_foreground):
        class_name = 'object'
        color = [255, 255, 255]
        bitmap = sly.Bitmap(data=mask_foreground)
        if not classes_dict.has_key(class_name):
            obj_class = sly.ObjClass(name=class_name,
                                     geometry_type=sly.Bitmap,
                                     color=color)
            classes_dict = classes_dict.add(obj_class)
        ann = ann.add_label(sly.Label(bitmap, classes_dict.get(class_name)))
        return ann
def get_masks(img):
    alpha = img[:, :, 3]
    mask_fg = alpha >= threshold
    mask_fuzzy = np.logical_and(alpha > 0, alpha < 255)

    fg = sly.Label(sly.Bitmap(mask_fg), foreground)
    fzz = None
    if np.any(mask_fuzzy) and need_fuzzy:
        fzz = sly.Label(sly.Bitmap(mask_fuzzy), fuzzy)

    return fg, fzz
Ejemplo n.º 3
0
    def _generate_annotation(self, src_img_path, inst_path):
        ann = sly.Annotation.from_img_path(src_img_path)

        if os.path.isfile(inst_path):
            instance_img = self._read_img_unchanged(inst_path)
            col2coord = get_col2coord(instance_img)
            curr_col2cls = {
                col: self.cls_names[int(
                    col //
                    256)]  # some dirty hack to determine class correctly
                for col, coord in col2coord.items()
            }

            for color, class_name in curr_col2cls.items():
                mask = instance_img == color  # exact match for 1d uint16
                bitmap = sly.Bitmap(data=mask)
                obj_class = sly.ObjClass(name=class_name,
                                         geometry_type=sly.Bitmap,
                                         color=self.cls2col.get(
                                             class_name,
                                             sly.color.random_rgb()))

                if not self.obj_classes.has_key(class_name):
                    self.obj_classes = self.obj_classes.add(obj_class)

                ann = ann.add_label(sly.Label(bitmap, obj_class))
                instance_img[mask] = 0  # to check missing colors, see below

            if np.sum(instance_img) > 0:
                sly.logger.warn(
                    'Not all objects or classes are captured from source segmentation.',
                    extra={})
        return ann
Ejemplo n.º 4
0
def convert_to_nonoverlapping(meta: sly.ProjectMeta, ann: sly.Annotation) -> (sly.ProjectMeta, sly.Annotation):
    common_img = np.zeros(ann.img_size, np.int32)  # size is (h, w)
    for idx, lbl in enumerate(ann.labels, start=1):
        if need_convert(lbl.obj_class.geometry_type):
            if allow_render_for_any_shape(lbl) is True:
                lbl.draw(common_img, color=idx)
            else:
                sly.logger.warn(
                    "Object of class {!r} (shape: {!r}) has non spatial shape {!r}. It will not be rendered."
                        .format(lbl.obj_class.name,
                                lbl.obj_class.geometry_type.geometry_name(),
                                lbl.geometry.geometry_name()))

    new_classes = sly.ObjClassCollection()
    new_labels = []
    for idx, lbl in enumerate(ann.labels, start=1):
        if not need_convert(lbl.obj_class.geometry_type):
            new_labels.append(lbl.clone())
        else:
            if allow_render_for_any_shape(lbl) is False:
                continue
            # @TODO: get part of the common_img for speedup
            mask = common_img == idx
            if np.any(mask):  # figure may be entirely covered by others
                g = lbl.geometry
                new_bmp = sly.Bitmap(data=mask)
                if new_classes.get(lbl.obj_class.name) is None:
                    new_classes = new_classes.add(lbl.obj_class.clone(geometry_type=sly.Bitmap))

                new_lbl = lbl.clone(geometry=new_bmp, obj_class=new_classes.get(lbl.obj_class.name))
                new_labels.append(new_lbl)

    new_meta = meta.clone(obj_classes=new_classes)
    new_ann = ann.clone(labels=new_labels)
    return (new_meta, new_ann)
Ejemplo n.º 5
0
def get_ann(img_path, inst_path, default_classes_colors, default_colors_classes):
    global classes_dict
    global count_of_colors
    ann = sly.Annotation.from_img_path(img_path)
    curr_color_to_class = {}
    if inst_path is not None:
        instance_img = sly.image.read(inst_path)
        instance_img[np.where((instance_img == [0, 0, 0]).all(axis=2))] = [1, 1, 1]
        colored_img = instance_img * 10
        instance_img = instance_img * 10
        unique_colors = np.unique(instance_img.reshape(-1, instance_img.shape[2]), axis=0)
        ann_colors = np.array(unique_colors).tolist()
        for color in ann_colors:
            if not color in default_classes_colors.values():
                default_classes_colors['object{}'.format(count_of_colors)] = color
                default_colors_classes[tuple(color)] = 'object{}'.format(count_of_colors)
                curr_color_to_class[tuple(color)] = 'object{}'.format(count_of_colors)
                count_of_colors += 1
            else:
                curr_color_to_class[tuple(color)] = default_colors_classes[tuple(color)]

    for color, class_name in curr_color_to_class.items():
        mask = np.all(colored_img == color, axis=2)
        bitmap = sly.Bitmap(data=mask)
        if not classes_dict.has_key(class_name):
            obj_class = sly.ObjClass(name=class_name, geometry_type=sly.Bitmap, color=list(color))
            classes_dict = classes_dict.add(obj_class)  # make it for meta.json

        ann = ann.add_label(sly.Label(bitmap, classes_dict.get(class_name)))
    return ann
Ejemplo n.º 6
0
def get_ann(img_path, inst_path, default_classes_colors):
    global classes_dict
    instance_img = sly.image.read(inst_path)
    colored_img = instance_img
    ann = sly.Annotation.from_img_path(img_path)
    unique_colors = np.unique(instance_img.reshape(-1, instance_img.shape[2]),
                              axis=0)
    for color in unique_colors:
        mask = np.all(colored_img == color, axis=2)
        class_name = default_classes_colors[tuple(color)]
        mask = mask.astype(np.uint8) * 128
        im2, contours, hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL,
                                                    cv2.CHAIN_APPROX_SIMPLE)
        for i in range(len(contours)):
            arr = np.array(contours[i], dtype=int)
            mask_temp = np.zeros(mask.shape, dtype=np.uint8)
            cv2.fillPoly(mask_temp, [arr], (254, 254, 254))
            mask = mask_temp.astype(np.bool)
            bitmap = sly.Bitmap(data=mask)
            if not classes_dict.has_key(class_name):
                obj_class = sly.ObjClass(name=class_name,
                                         geometry_type=sly.Bitmap,
                                         color=list(color))
                classes_dict = classes_dict.add(obj_class)
            ann = ann.add_label(sly.Label(bitmap,
                                          classes_dict.get(class_name)))
    return ann
Ejemplo n.º 7
0
def get_ann(img_path, inst_path, number_class, pixel_color):
    global classes_dict
    ann = sly.Annotation.from_img_path(img_path)

    if inst_path is not None:
        instance_img = sly.image.read(inst_path)
        instance_img = instance_img[:, :, 0] + 1
        current_color2class = {}
        temp = np.unique(instance_img)
        for pixel in temp:
            current_color2class[pixel] = number_class[pixel]

        for pixel, class_name in current_color2class.items():
            new_color = pixel_color[pixel]
            imgray = np.where(instance_img == pixel, instance_img, 0)
            ret, thresh = cv2.threshold(imgray, 1, 255, 0)
            im2, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
            for i in range(len(contours)):
                arr = np.array(contours[i], dtype=int)
                mask_temp = np.zeros(instance_img.shape, dtype=np.uint8)

                cv2.fillPoly(mask_temp, [np.int32(arr)], (255, 255, 255))
                mask = mask_temp.astype(np.bool)
                bitmap = sly.Bitmap(data=mask)

                if not classes_dict.has_key(class_name):
                    obj_class = sly.ObjClass(name=class_name, geometry_type=sly.Bitmap, color=new_color)
                    classes_dict = classes_dict.add(obj_class)  # make it for meta.json

                ann = ann.add_label(sly.Label(bitmap, classes_dict.get(class_name)))
    return ann
Ejemplo n.º 8
0
def get_ann(img_path, inst_path, number_class, pixel_color):
    global classes_dict
    instance_img = []
    with open(inst_path) as file:
        for line in file:
            line = line.split('\n')[0]
            line = line.split(' ')
            instance_img.append(line)
    instance_img = np.array(instance_img, np.uint8)
    instance_img = instance_img + 2
    curr_color_to_class = {}
    temp = np.unique(instance_img)
    for pixel in temp:
        if pixel == 255:
            continue
        curr_color_to_class[pixel] = number_class[pixel]

    ann = sly.Annotation.from_img_path(img_path)

    for color, class_name in curr_color_to_class.items():
        new_color = list(pixel_color[color])
        mask = np.where(instance_img == color, instance_img, 0)
        im2, contours, hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        for i in range(len(contours)):
            arr = np.array(contours[i], dtype=int)
            mask_temp = np.zeros(instance_img.shape, dtype=np.uint8)
            cv2.fillPoly(mask_temp, [np.int32(arr)], (254, 254, 254))
            mask = mask_temp.astype(np.bool)
            bitmap = sly.Bitmap(data=mask)

            if not classes_dict.has_key(class_name):
                obj_class = sly.ObjClass(name=class_name, geometry_type=sly.Bitmap, color=new_color)
                classes_dict = classes_dict.add(obj_class)
            ann = ann.add_label(sly.Label(bitmap, classes_dict.get(class_name)))
    return ann
Ejemplo n.º 9
0
def get_ann(img_path, inst_path, number_class, pixel_color):
    global classes_dict
    ann = sly.Annotation.from_img_path(img_path)

    if inst_path is not None:
        mat = scipy.io.loadmat(inst_path)
        instance_img = mat['LabelMap']
        colored_img = cv2.merge((instance_img, instance_img, instance_img))
        current_color_to_class = {}
        temp = np.unique(instance_img)
        for pixel in temp:
            current_color_to_class[pixel] = number_class[str(pixel)]

        for pixel, class_name in current_color_to_class.items():
            mask = np.all(colored_img == pixel, axis=2)  # exact match (3-channel img & rgb color)
            new_color = pixel_color[str(pixel)]
            bitmap = sly.Bitmap(data=mask)

            if not classes_dict.has_key(class_name):
                obj_class = sly.ObjClass(name=class_name, geometry_type=sly.Bitmap, color=new_color)
                classes_dict = classes_dict.add(obj_class) # make it for meta.json

            ann = ann.add_label(sly.Label(bitmap, classes_dict.get(class_name)))
            #  clear used pixels in mask to check missing colors, see below
            colored_img[mask] = (0, 0, 0)

        if np.sum(colored_img) > 0:
            sly.logger.warn('Not all objects or classes are captured from source segmentation.')

    return ann
Ejemplo n.º 10
0
    def convert_to_nonoverlapping(src_ann: sly.Annotation) -> sly.Annotation:
        common_img = np.zeros(src_ann.img_size, np.int32)  # size is (h, w)
        for idx, lbl in enumerate(src_ann.labels, start=1):
            if need_convert(lbl.obj_class.geometry_type):
                if allow_render_non_spatial_for_any_shape(lbl) == True:
                    lbl.draw(common_img, color=idx)
                else:
                    sly.logger.warn(
                        "Object of class {!r} (class shape: {!r}) has non spatial shape {!r}. It will not be rendered."
                        .format(lbl.obj_class.name,
                                lbl.obj_class.geometry_type.geometry_name(),
                                lbl.geometry.geometry_name()))

        new_labels = []
        for idx, lbl in enumerate(src_ann.labels, start=1):
            new_cls = dst_project_meta.obj_classes.get(lbl.obj_class.name)
            if not need_convert(lbl.obj_class.geometry_type):
                new_lbl = lbl.clone(obj_class=new_cls)
                new_labels.append(new_lbl)
            else:
                if allow_render_non_spatial_for_any_shape(lbl) == False:
                    continue
                mask = common_img == idx
                if np.any(mask):  # figure may be entirely covered by others
                    g = lbl.geometry
                    new_bmp = sly.Bitmap(data=mask,
                                         labeler_login=g.labeler_login,
                                         updated_at=g.updated_at,
                                         created_at=g.created_at)
                    new_lbl = lbl.clone(geometry=new_bmp, obj_class=new_cls)
                    new_labels.append(new_lbl)

        return src_ann.clone(labels=new_labels)
Ejemplo n.º 11
0
def get_ann(img_path, inst_path, number_class, pixel_color):
    global classes_dict
    ann = sly.Annotation.from_img_path(img_path)
    mat = scipy.io.loadmat(inst_path)
    instance_img = mat['MM'][0][0][0]
    instance_img = instance_img.astype(np.uint8) + 1
    colored_img = instance_img
    unique_pixels = np.unique(instance_img)
    for pixel in unique_pixels:
        color = pixel_color[pixel]
        class_name = number_class[pixel]
        imgray = np.where(colored_img == pixel, colored_img, 0)
        ret, thresh = cv2.threshold(imgray, 1, 255, 0)
        im2, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL,
                                                    cv2.CHAIN_APPROX_SIMPLE)
        for i in range(len(contours)):
            arr = np.array(contours[i], dtype=int)
            mask_temp = np.zeros(instance_img.shape, dtype=np.uint8)
            cv2.fillPoly(mask_temp, [arr], (255, 255, 255))
            mask = mask_temp.astype(np.bool)
            bitmap = sly.Bitmap(data=mask)
            if not classes_dict.has_key(class_name):
                obj_class = sly.ObjClass(name=class_name,
                                         geometry_type=sly.Bitmap,
                                         color=list(color))
                classes_dict = classes_dict.add(obj_class)
            ann = ann.add_label(sly.Label(bitmap,
                                          classes_dict.get(class_name)))
    return ann
Ejemplo n.º 12
0
    def _get_ann(self, img_path, segm_path, inst_path):

        segmentation_img = sly.image.read(segm_path)

        if inst_path is not None:
            instance_img = sly.image.read(inst_path)
            colored_img = instance_img
            instance_img16 = instance_img.astype(np.uint16)
            col2coord = get_col2coord(instance_img16)
            curr_col2cls = ((col, self.color2class_name.get(tuple(segmentation_img[coord])))
                            for col, coord in col2coord.items())
            curr_col2cls = {k: v for k, v in curr_col2cls if v is not None}  # _instance_ color -> class name
        else:
            colored_img = segmentation_img
            curr_col2cls = self.color2class_name

        ann = sly.Annotation.from_img_path(img_path)

        for color, class_name in curr_col2cls.items():
            mask = np.all(colored_img == color, axis=2)  # exact match (3-channel img & rgb color)

            bitmap = sly.Bitmap(data=mask)
            obj_class = sly.ObjClass(name=class_name, geometry_type=sly.Bitmap, color=color)

            if not self.obj_classes.has_key(class_name):
                self.obj_classes = self.obj_classes.add(obj_class)

            ann = ann.add_label(sly.Label(bitmap, obj_class))
            #  clear used pixels in mask to check missing colors, see below
            colored_img[mask] = (0, 0, 0)

        if np.sum(colored_img) > 0:
            sly.logger.warn('Not all objects or classes are captured from source segmentation.')

        return ann
Ejemplo n.º 13
0
def get_ann(img_path, inst_path, default_classes_colors):
    global classes_dict
    ann = sly.Annotation.from_img_path(img_path)
    instance_img = sly.image.read(inst_path)

    img_gray = cv2.cvtColor(instance_img, cv2.COLOR_BGR2GRAY)
    _, mask_foreground = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY)
    mask_background = (img_gray == 0)

    class_name = 'background'
    new_color = default_classes_colors[class_name]
    bitmap = sly.Bitmap(data=mask_background)

    if not classes_dict.has_key(class_name):
        obj_class = sly.ObjClass(name=class_name,
                                 geometry_type=sly.Bitmap,
                                 color=new_color)
        classes_dict = classes_dict.add(obj_class)
    ann = ann.add_label(sly.Label(bitmap, classes_dict.get(class_name)))

    im2, contours, hierarchy = cv2.findContours(mask_foreground,
                                                cv2.RETR_EXTERNAL,
                                                cv2.CHAIN_APPROX_SIMPLE)
    class_name = 'skin'
    new_color = default_classes_colors[class_name]
    for i in range(len(contours)):
        arr = np.array(contours[i], dtype=int)
        mask_temp = np.zeros(instance_img.shape, dtype=np.uint8)
        cv2.fillPoly(mask_temp, [np.int32(arr)], (255, 255, 255))
        mask_temp = cv2.split(mask_temp)[0]
        mask = mask_temp.astype(np.bool)
        bitmap = sly.Bitmap(data=mask)

        if not classes_dict.has_key(class_name):
            obj_class = sly.ObjClass(name=class_name,
                                     geometry_type=sly.Bitmap,
                                     color=new_color)
            classes_dict = classes_dict.add(obj_class)
        ann = ann.add_label(sly.Label(bitmap, classes_dict.get(class_name)))
    return ann
def generate_example(augs_settings, augs=None, preview=True, product_id=None, img=None, ann=None):
    if product_id is None or img is None or ann is None:
        product_id, img, ann = get_random_product()

    if logging.getLevelName(sly.logger.level) == 'DEBUG':
        sly.image.write(os.path.join(vis_dir, "01_img.png"), img)

    label_image, label_mask = preprocess_product(img, ann, augs_settings, is_main=True)
    if logging.getLevelName(sly.logger.level) == 'DEBUG':
        sly.image.write(os.path.join(vis_dir, "02_label_image.png"), label_image)
        sly.image.write(os.path.join(vis_dir, "03_label_mask.png"), label_mask)

    orig_h, orig_w = label_image.shape[:2]
    for crop_f, place_f, range_index in zip(crops_funcs, place_funcs, list(range(0, 4))):
        if random.uniform(0, 1) <= augs_settings['noise']['corner_probability']:
            _, noise_img, noise_ann = get_random_product(ignore_id=product_id)
            noise_img, noise_ann = crop_label(noise_img, noise_ann, padding=0)
            noise_mask = draw_white_mask(noise_ann)
            if logging.getLevelName(sly.logger.level) == 'DEBUG':
                sly.image.write(os.path.join(vis_dir, "04_noise_img.png"), noise_img)
            if random.uniform(0, 1) <= augs_settings['noise']['aug_probability']:
                noise_img, noise_mask = augs.apply_to_foreground(noise_img, noise_mask)

            y_range = get_y_range(range_index, orig_h, portion=augs_settings["noise"]["max_occlusion_height"])
            x_range = get_x_range(range_index, orig_w, portion=augs_settings["noise"]["max_occlusion_width"])
            y = random.randint(int(y_range[0]), int(y_range[1]))
            x = random.randint(int(x_range[0]), int(x_range[1]))
            noise_img, noise_mask = crop_f(y, x, orig_h, orig_w, noise_img, noise_mask)

            if logging.getLevelName(sly.logger.level) == 'DEBUG':
                sly.image.write(os.path.join(vis_dir, f"04_noise_img_{range_index}.png"), noise_img)
                sly.image.write(os.path.join(vis_dir, f"05_noise_mask_{range_index}.png"), noise_mask)
            place_f(y, x, label_image, label_mask, noise_img, noise_mask)

    if logging.getLevelName(sly.logger.level) == 'DEBUG':
        sly.image.write(os.path.join(vis_dir, "06_final_mask.png"), label_mask)

    if not np.any(label_mask):  # if empty mask - figure may be entirely covered by others
        return None, None, None

    label_preview = None
    if preview is True:
        label_preview = sly.Label(
            sly.Bitmap(label_mask[:, :, 0].astype(bool), origin=sly.PointLocation(0, 0)),
            RESULT_CLASS
        )

    return label_image, label_mask, label_preview
Ejemplo n.º 15
0
def get_ann(img_path, inst_path):
    global classes_dict
    default_classes_colors = {}
    colors = [(0, 0, 0)]
    ann = sly.Annotation.from_img_path(img_path)

    if inst_path is not None:
        mat = scipy.io.loadmat(inst_path)
        mask = mat['anno']
        all_objects = mask[0][0][1][0]
        class_mask, unique_class_mask = {}, []

        for obj in all_objects:
            object_name, object_mask = obj[0], obj[2]
            class_mask[object_name[0]] = object_mask
            unique_class_mask.append([object_name[0], object_mask])
            if len(obj[3]) > 0:
                all_parts = obj[3][0]
                for part in all_parts:
                    class_mask[part[0][0]] = part[1]
                    unique_class_mask.append([part[0][0], part[1]])

        for class_name in class_mask.keys():
            if class_name not in default_classes_colors:
                new_color = generate_rgb(colors)
                colors.append(new_color)
                default_classes_colors[class_name] = new_color

        for temp in unique_class_mask:
            class_name, cl_mask = temp
            mask = cl_mask.astype(np.bool)
            new_color = default_classes_colors[class_name]
            bitmap = sly.Bitmap(data=mask)

            if not classes_dict.has_key(class_name):
                obj_class = sly.ObjClass(name=class_name,
                                         geometry_type=sly.Bitmap,
                                         color=new_color)
                classes_dict = classes_dict.add(
                    obj_class)  # make it for meta.json
                ann = ann.add_label(
                    sly.Label(bitmap, classes_dict.get(class_name)))
    return ann
Ejemplo n.º 16
0
def read_mask_labels(mask_path: str, classes_mapping: Dict, obj_classes: sly.ObjClassCollection) -> List[sly.Label]:
    mask = cv2.imread(mask_path)[:, :, 0]
    labels_list = []
    for cls_name, color in classes_mapping.items():
        if color == MATCH_ALL:
            bool_mask = mask > 0
        elif isinstance(color, int):
            bool_mask = mask == color
        elif isinstance(color, list):
            bool_mask = np.isin(mask, color)
        else:
            raise ValueError('Wrong color format. It must be integer, list of integers or special key string "__all__".')

        if bool_mask.sum() == 0:
            continue

        bitmap = sly.Bitmap(data=bool_mask)
        obj_class = obj_classes.get(cls_name)
        labels_list.append(sly.Label(geometry=bitmap, obj_class=obj_class))
    return labels_list
Ejemplo n.º 17
0
def get_ann(img_path, inst_path, number_class, pixel_color):
    global classes_dict
    if inst_path is not None:
        instance_img = sly.image.read(inst_path)
        class_mask = cv2.split(instance_img)[0]
        class_mask = np.where(class_mask != 0, class_mask, 10)
        current_color2class = {}
        unique_pixels = np.unique(class_mask)
        for pixel in unique_pixels:
            current_color2class[pixel] = number_class[pixel]
    ann = sly.Annotation.from_img_path(img_path)
    for pixel, class_name in current_color2class.items():
        new_color = pixel_color[pixel]
        mask = np.where(class_mask == pixel, class_mask, 0)
        mask = mask.astype(np.bool)
        bitmap = sly.Bitmap(data=mask)
        if not classes_dict.has_key(class_name):
            obj_class = sly.ObjClass(name=class_name,
                                     geometry_type=sly.Bitmap,
                                     color=list(new_color))
            classes_dict = classes_dict.add(obj_class)
        ann = ann.add_label(sly.Label(bitmap, classes_dict.get(class_name)))
    return ann
def transform_for_segmentation(meta: sly.ProjectMeta, ann: sly.Annotation) -> (sly.ProjectMeta, sly.Annotation):
    new_classes = {}
    class_masks = {}
    for obj_class in meta.obj_classes:
        obj_class: sly.ObjClass
        new_class = obj_class.clone(name=obj_class.name + "-mask")
        new_classes[obj_class.name] = new_class
        class_masks[obj_class.name] = np.zeros(ann.img_size, np.uint8)

    new_class_collection = sly.ObjClassCollection(list(new_classes.values()))
    for label in ann.labels:
        label.draw(class_masks[label.obj_class.name], color=255)

    new_labels = []
    for class_name, white_mask in class_masks.items():
        mask = white_mask == 255
        obj_class = new_classes[class_name]
        bitmap = sly.Bitmap(data=mask)
        new_labels.append(sly.Label(geometry=bitmap, obj_class=obj_class))

    res_meta = meta.clone(obj_classes=new_class_collection)
    res_ann = ann.clone(labels=new_labels)
    return (res_meta, res_ann)
Ejemplo n.º 19
0
def generate_annotation(src_img_path, inst_path, id_to_class, class_to_color,
                        classes_collection):
    ann = sly.Annotation.from_img_path(src_img_path)

    if os.path.isfile(inst_path):
        instance_img = cv2.imread(inst_path,
                                  cv2.IMREAD_UNCHANGED)  # expect uint16
        col2coord = get_color_to_coordinates(instance_img)

        # Some dirty hack to determine class correctly, low byte is unused. (Low byte describe)
        current_color_to_class = {
            color: id_to_class[int(color // 256)]
            for color in col2coord.keys()
        }

        for color, class_name in current_color_to_class.items():
            mask = (instance_img == color)  # exact match for 1d uint16
            bitmap = sly.Bitmap(mask)

            if not classes_collection.has_key(class_name):
                obj_class = sly.ObjClass(name=class_name,
                                         geometry_type=sly.Bitmap,
                                         color=class_to_color.get(
                                             class_name,
                                             sly.color.random_rgb()))
                classes_collection = classes_collection.add(obj_class)

            ann = ann.add_label(
                sly.Label(bitmap, classes_collection.get(class_name)))
            instance_img[mask] = 0  # to check missing colors, see below

        if np.sum(instance_img) > 0:
            sly.logger.warn(
                'Not all objects or classes are captured from source segmentation.',
                extra={})
    return ann, classes_collection
Ejemplo n.º 20
0
def convert_to_nonoverlapping(src_ann: sly.Annotation) -> sly.Annotation:
    common_img = np.zeros(src_ann.img_size, np.uint32)  # size is (h, w)
    for idx, lbl in enumerate(src_ann.labels, start=1):
        if account_label(lbl):
            lbl.draw(common_img, color=idx)

    new_labels = []
    for idx, lbl in enumerate(src_ann.labels, start=1):
        new_cls = dst_project_meta.obj_classes.get(lbl.obj_class.name)
        if not account_label(lbl):
            new_lbl = lbl.clone(obj_class=new_cls)
            new_labels.append(new_lbl)
        else:
            mask = common_img == idx
            if np.any(mask):  # figure may be entirely covered by others
                g = lbl.geometry
                new_bmp = sly.Bitmap(data=mask,
                                     labeler_login=g.labeler_login,
                                     updated_at=g.updated_at,
                                     created_at=g.created_at)
                new_lbl = lbl.clone(geometry=new_bmp, obj_class=new_cls)
                new_labels.append(new_lbl)

    return src_ann.clone(labels=new_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
Ejemplo n.º 22
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