Ejemplo n.º 1
0
def apply_perspective_transform_to_image_data(
        image_data: ImageData, perspective_matrix: np.ndarray,
        result_width: int, result_height: int,
        allow_negative_and_large_coords: bool,
        remove_bad_coords: bool) -> ImageData:
    image = image_data.open_image()
    image = cv2.warpPerspective(image, perspective_matrix,
                                (result_width, result_height))

    image_data = copy.deepcopy(image_data)
    image_data.keypoints = apply_perspective_transform_to_points(
        image_data.keypoints, perspective_matrix, result_width, result_height,
        allow_negative_and_large_coords, remove_bad_coords)
    image_data.bboxes_data = [
        _apply_perspective_transform_to_bbox_data(
            bbox_data, perspective_matrix, result_width, result_height,
            allow_negative_and_large_coords, remove_bad_coords)
        for bbox_data in image_data.bboxes_data
    ]
    image_data.bboxes_data = [
        bbox_data for bbox_data in image_data.bboxes_data
        if bbox_data is not None
    ]
    image_data.image_path = None
    image_data.image = image

    return image_data
Ejemplo n.º 2
0
def non_max_suppression_image_data(image_data: ImageData,
                                   iou: float) -> ImageData:
    image_data = copy.deepcopy(image_data)
    current_bboxes_data = image_data.bboxes_data.copy()
    new_bboxes_data = []
    while len(current_bboxes_data) != 0:
        current_bbox_data = current_bboxes_data[0]
        success = True
        if len(current_bboxes_data) > 1:
            for idx, bbox_data in enumerate(current_bboxes_data):
                if idx == 0:
                    continue
                bbox_iou = intersection_over_union(current_bbox_data,
                                                   bbox_data)

                if bbox_iou >= iou:
                    pairs_bboxes_data = [bbox_data, current_bbox_data]
                    pairs_scores = [
                        possible_bbox_data.detection_score if
                        possible_bbox_data.detection_score is not None else 1.
                        for possible_bbox_data in pairs_bboxes_data
                    ]
                    top_score_idx = np.argmax(pairs_scores)
                    current_bboxes_data.pop(idx)
                    current_bboxes_data.pop(0)
                    current_bboxes_data.append(
                        BboxData(
                            xmin=min(bbox_data.xmin, current_bbox_data.xmin),
                            ymin=min(bbox_data.ymin, current_bbox_data.ymin),
                            xmax=max(bbox_data.xmax, current_bbox_data.xmax),
                            ymax=max(bbox_data.ymax, current_bbox_data.ymax),
                            detection_score=pairs_bboxes_data[top_score_idx].
                            detection_score,
                            label=pairs_bboxes_data[top_score_idx].label,
                            keypoints=pairs_bboxes_data[top_score_idx].
                            keypoints,
                            additional_bboxes_data=pairs_bboxes_data[
                                top_score_idx].additional_bboxes_data,
                            additional_info=pairs_bboxes_data[top_score_idx].
                            additional_info))
                    success = False
                    break
        if success:
            new_bboxes_data.append(current_bboxes_data.pop(0))

    image_data.bboxes_data = new_bboxes_data
    image_data.image_path = image_data.image_path
    image_data.image = image_data.image
    return image_data
Ejemplo n.º 3
0
def flatten_additional_bboxes_data_in_image_data(
    image_data: ImageData,
    additional_bboxes_data_depth: Optional[int] = None,
) -> ImageData:
    image_data = copy.deepcopy(image_data)
    bboxes_data = []

    def _append_bbox_data(bbox_data: BboxData, depth: int):
        if additional_bboxes_data_depth is not None and depth > additional_bboxes_data_depth:
            return
        bboxes_data.append(bbox_data)
        for additional_bbox_data in bbox_data.additional_bboxes_data:
            _append_bbox_data(additional_bbox_data)
        bbox_data.additional_bboxes_data = []

    for bbox_data in bboxes_data:
        _append_bbox_data(bbox_data, depth=0)

    image_data.bboxes_data = bboxes_data
    return image_data
Ejemplo n.º 4
0
def non_max_suppression_image_data_using_tf(image_data: ImageData,
                                            iou: float) -> ImageData:
    import tensorflow as tf
    image_data = copy.deepcopy(image_data)
    if len(image_data.bboxes_data) <= 1:
        return image_data
    bboxes = [(bbox_data.ymin, bbox_data.xmin, bbox_data.ymax, bbox_data.xmax)
              for bbox_data in image_data.bboxes_data]
    scores = [
        bbox_data.detection_score
        if bbox_data.detection_score is not None else 1.
        for bbox_data in image_data.bboxes_data
    ]
    result = tf.image.non_max_suppression(bboxes,
                                          scores,
                                          len(image_data.bboxes_data),
                                          iou_threshold=iou)
    image_data.bboxes_data = [
        image_data.bboxes_data[i] for i in result.numpy()
    ]
    return image_data
Ejemplo n.º 5
0
def concat_images_data(image_data_a: ImageData,
                       image_data_b: ImageData,
                       background_color_a: Tuple[int, int, int, int] = None,
                       background_color_b: Tuple[int, int, int, int] = None,
                       thumbnail_size_a: Tuple[int, int] = None,
                       thumbnail_size_b: Tuple[int, int] = None,
                       how: Literal['horizontally',
                                    'vertically'] = 'horizontally',
                       mode: Literal['L', 'RGB', 'RGBA'] = 'RGBA',
                       background_edge_width: int = 3,
                       between_edge_width: int = 0) -> ImageData:

    image_data_a = copy.deepcopy(image_data_a)
    image_data_b = copy.deepcopy(image_data_b)

    if image_data_a is None and image_data_b is not None:
        return image_data_b
    if image_data_a is not None and image_data_b is None:
        return image_data_a

    image_a = image_data_a.open_image()
    image_b = image_data_b.open_image()

    ha, wa = image_a.shape[:2]
    hb, wb = image_b.shape[:2]

    image = concat_images(image_a=image_a,
                          image_b=image_b,
                          background_color_a=background_color_a,
                          background_color_b=background_color_b,
                          thumbnail_size_a=thumbnail_size_a,
                          thumbnail_size_b=thumbnail_size_b,
                          how=how,
                          mode=mode,
                          background_edge_width=background_edge_width,
                          between_edge_width=between_edge_width)
    image_data_a_new_xmin, image_data_a_new_ymin = None, None
    image_data_b_new_xmin, image_data_b_new_ymin = None, None

    if how == 'horizontally':
        max_height = np.max([ha, hb])
        min_ha = max_height // 2 - ha // 2
        max_ha = max_height // 2 + ha // 2
        min_hb = max_height // 2 - hb // 2
        max_hb = max_height // 2 + hb // 2
        image_data_a_new_xmin = 0
        image_data_a_new_ymin = min_ha
        image_data_a_new_xmax = wa
        image_data_a_new_ymax = max_ha
        image_data_b_new_xmin = wa + between_edge_width
        image_data_b_new_ymin = min_hb
        image_data_b_new_xmax = wa + between_edge_width + wb
        image_data_b_new_ymax = max_hb

    elif how == 'vertically':
        max_width = np.max([wa, wb])
        min_wa = max_width // 2 - wa // 2
        max_wa = max_width // 2 + wa // 2
        min_wb = max_width // 2 - wb // 2
        max_wb = max_width // 2 + wb // 2
        image_data_a_new_xmin = min_wa
        image_data_a_new_ymin = 0
        image_data_a_new_xmax = max_wa
        image_data_a_new_ymax = ha
        image_data_b_new_xmin = min_wb
        image_data_b_new_ymin = ha + between_edge_width
        image_data_b_new_xmax = max_wb
        image_data_b_new_ymax = ha + between_edge_width + hb

    keypoints_a = image_data_a.keypoints
    keypoints_b = image_data_a.keypoints
    keypoints_a[:, 0] += image_data_a_new_xmin
    keypoints_a[:, 1] += image_data_a_new_ymin
    keypoints_b[:, 0] += image_data_b_new_xmin
    keypoints_b[:, 1] += image_data_b_new_ymin

    def _get_new_coords_for_bbox_data(bbox_data: BboxData, xmin: int,
                                      ymin: int):
        bbox_data.keypoints[:, 0] += xmin
        bbox_data.keypoints[:, 1] += ymin
        bbox_data.xmin += xmin
        bbox_data.ymin += ymin
        bbox_data.xmax += xmin
        bbox_data.ymax += ymin
        bbox_data.image = None
        bbox_data.image_path = None
        bbox_data.cropped_image = None
        for additional_bbox_data in bbox_data.additional_bboxes_data:
            _get_new_coords_for_bbox_data(additional_bbox_data, xmin, ymin)

    for bbox_data in image_data_a.bboxes_data:
        _get_new_coords_for_bbox_data(bbox_data, image_data_a_new_xmin,
                                      image_data_a_new_ymin)

    if 'concat_images_data__image_data' not in [
            bbox_data.label for bbox_data in image_data_a.bboxes_data
    ]:
        bbox_data_a_into = [
            BboxData(xmin=image_data_a_new_xmin,
                     ymin=image_data_a_new_ymin,
                     xmax=image_data_a_new_xmax,
                     ymax=image_data_a_new_ymax,
                     label='concat_images_data__image_data',
                     additional_bboxes_data=[
                         bbox_data for bbox_data in image_data_a.bboxes_data
                         if 'concat_images_data__image_data' != bbox_data.label
                     ])
        ]
    else:
        bbox_data_a_into = []
    image_data_a.bboxes_data = [
        bbox_data for bbox_data in image_data_a.bboxes_data
        if 'concat_images_data__image_data' == bbox_data.label
    ] + bbox_data_a_into

    for bbox_data in image_data_b.bboxes_data:
        _get_new_coords_for_bbox_data(bbox_data, image_data_b_new_xmin,
                                      image_data_b_new_ymin)
    if 'concat_images_data__image_data' not in [
            bbox_data.label for bbox_data in image_data_b.bboxes_data
    ]:
        bbox_data_b_into = [
            BboxData(xmin=image_data_b_new_xmin,
                     ymin=image_data_b_new_ymin,
                     xmax=image_data_b_new_xmax,
                     ymax=image_data_b_new_ymax,
                     label='concat_images_data__image_data',
                     additional_bboxes_data=[
                         bbox_data for bbox_data in image_data_b.bboxes_data
                         if 'concat_images_data__image_data' != bbox_data.label
                     ])
        ]
    else:
        bbox_data_b_into = []
    image_data_b.bboxes_data = [
        bbox_data for bbox_data in image_data_b.bboxes_data
        if 'concat_images_data__image_data' == bbox_data.label
    ] + bbox_data_b_into

    image_data = ImageData(image_path=None,
                           image=image,
                           bboxes_data=image_data_a.bboxes_data +
                           image_data_b.bboxes_data,
                           label=None,
                           keypoints=np.concatenate([keypoints_a, keypoints_b],
                                                    axis=0),
                           additional_info={
                               **image_data_a.additional_info,
                               **image_data_b.additional_info
                           })

    return image_data
Ejemplo n.º 6
0
def crop_image_data(
    image_data: ImageData,
    xmin: int,
    ymin: int,
    xmax: int,
    ymax: int,
    allow_negative_and_large_coords: bool,
    remove_bad_coords: bool,
) -> ImageData:

    assert 0 <= xmin and 0 <= ymin
    assert xmin <= xmax and ymin <= ymax

    image_data = copy.deepcopy(image_data)
    image = image_data.open_image()
    height, width, _ = image.shape

    assert xmax <= width and ymax <= height

    image = image[ymin:ymax, xmin:xmax]
    new_height, new_width, _ = image.shape

    def resize_coords(bbox_data: BboxData):
        bbox_data.xmin = bbox_data.xmin - xmin
        bbox_data.ymin = bbox_data.ymin - ymin
        bbox_data.xmax = bbox_data.xmax - xmin
        bbox_data.ymax = bbox_data.ymax - ymin
        bbox_data.keypoints[:, 0] -= xmin
        bbox_data.keypoints[:, 1] -= ymin
        bbox_data.cropped_image = None
        if not allow_negative_and_large_coords:
            bbox_data.xmin = max(0, min(bbox_data.xmin, new_width - 1))
            bbox_data.ymin = max(0, min(bbox_data.ymin, new_height - 1))
            bbox_data.xmax = max(0, min(bbox_data.xmax, new_width - 1))
            bbox_data.ymax = max(0, min(bbox_data.ymax, new_height - 1))
            keypoints = []
            for (x, y) in bbox_data.keypoints:
                x = max(0, min(x, new_width - 1))
                y = max(0, min(y, new_height - 1))
                keypoints.append([x, y])
            bbox_data.keypoints = np.array(keypoints).reshape(-1, 2)
        for additional_bbox_data in bbox_data.additional_bboxes_data:
            resize_coords(additional_bbox_data)

    for bbox_data in image_data.bboxes_data:
        resize_coords(bbox_data)

    keypoints = []
    for (x, y) in image_data.keypoints:
        x = max(0, min(x - xmin, new_width - 1))
        y = max(0, min(y - ymin, new_height - 1))
        keypoints.append([x, y])
    image_data.keypoints = np.array(keypoints).reshape(-1, 2)

    def if_bbox_data_inside_crop(bbox_data: BboxData):
        bbox_data.keypoints = bbox_data.keypoints[(
            (bbox_data.keypoints[:, 0] >= 0) & (bbox_data.keypoints[:, 1] >= 0)
            & (bbox_data.keypoints[:, 0] < new_height) &
            (bbox_data.keypoints[:, 1] < new_width))]
        bbox_data.additional_bboxes_data = [
            additional_bbox_data
            for additional_bbox_data in bbox_data.additional_bboxes_data
            if if_bbox_data_inside_crop(additional_bbox_data)
        ]
        return (bbox_data.xmin >= 0 and bbox_data.ymin >= 0
                and bbox_data.xmax < new_width and bbox_data.ymax < new_height
                and bbox_data.xmin < bbox_data.xmax
                and bbox_data.ymin < bbox_data.ymax)

    if remove_bad_coords:
        image_data.bboxes_data = [
            bbox_data for bbox_data in image_data.bboxes_data
            if if_bbox_data_inside_crop(bbox_data)
        ]
        image_data.keypoints = image_data.keypoints[(
            (image_data.keypoints[:, 0] >= 0) &
            (image_data.keypoints[:, 1] >= 0) &
            (image_data.keypoints[:, 0] < new_height) &
            (image_data.keypoints[:, 1] < new_width))]

    image_data.image_path = None
    image_data.image = image

    return image_data