• 【Detectron2】代码库学习-5.标注格式- 矩形框, 旋转框,关键点, mask, 实例标注,IOU计算, 旋转框IOU计算,


    Detectron2 内置的标注格式

    • Boxes
    • RotatedBoxes
    • BitMasks
    • PolygonMasks
    • ROIMasks
    • Keypoints
    • Instances
    • ImageList

    BoxMode 表示方式

    • XYXY_ABS
    • XYWH_ABS
    • XYXY_REL # 相对模式
    • XYWH_REL # 相对模式
    • XYWHA_ABS # 带角度的旋转框 xc, yc 中心点坐标; A, 逆时针度数

    实用API

    成对Boxes 交集计算

    def pairwise_intersection(boxes1: Boxes, boxes2: Boxes) -> torch.Tensor:
        """
        Given two lists of boxes of size N and M,
        compute the intersection area between __all__ N x M pairs of boxes.
        The box order must be (xmin, ymin, xmax, ymax)
    
        Args:
            boxes1,boxes2 (Boxes): two `Boxes`. Contains N & M boxes, respectively.
    
        Returns:
            Tensor: intersection, sized [N,M].
        """
        boxes1, boxes2 = boxes1.tensor, boxes2.tensor
        width_height = torch.min(boxes1[:, None, 2:], boxes2[:, 2:]) - torch.max(
            boxes1[:, None, :2], boxes2[:, :2]
        )  # [N,M,2]
    
        width_height.clamp_(min=0)  # [N,M,2]
        intersection = width_height.prod(dim=2)  # [N,M]
        return intersection
        ```
    
    成对Boxes IOU 计算
    ```python
    def pairwise_iou(boxes1: Boxes, boxes2: Boxes) -> torch.Tensor:
        """
        Given two lists of boxes of size N and M, compute the IoU
        (intersection over union) between **all** N x M pairs of boxes.
        The box order must be (xmin, ymin, xmax, ymax).
    
        Args:
            boxes1,boxes2 (Boxes): two `Boxes`. Contains N & M boxes, respectively.
    
        Returns:
            Tensor: IoU, sized [N,M].
        """
        area1 = boxes1.area()  # [N]
        area2 = boxes2.area()  # [M]
        inter = pairwise_intersection(boxes1, boxes2)
    
        # handle empty boxes
        iou = torch.where(
            inter > 0,
            inter / (area1[:, None] + area2 - inter),
            torch.zeros(1, dtype=inter.dtype, device=inter.device),
        )
        return iou
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    RotatedBoxes

    旋转框 表示 N x 5, N个 框, cx, cy, w,h, angle 。 旋转框角度 无范围限制, 推荐 在 [-180, 180)
    旋转角表示法:
    hbox
    r1
    r2

    def inside_box(self, box_size: Tuple[int, int], boundary_threshold: int = 0) -> torch.Tensor:
    
    • 1

    支持旋转框尺度放缩,

        def scale(self, scale_x: float, scale_y: float) -> None:
            """
            Scale the rotated box with horizontal and vertical scaling factors
            Note: when scale_factor_x != scale_factor_y,
            the rotated box does not preserve the rectangular shape when the angle
            is not a multiple of 90 degrees under resize transformation.
            Instead, the shape is a parallelogram (that has skew)
            Here we make an approximation by fitting a rotated rectangle to the parallelogram.
            """
            self.tensor[:, 0] *= scale_x
            self.tensor[:, 1] *= scale_y
            theta = self.tensor[:, 4] * math.pi / 180.0
            c = torch.cos(theta)
            s = torch.sin(theta)
    
            # In image space, y is top->down and x is left->right
            # Consider the local coordintate system for the rotated box,
            # where the box center is located at (0, 0), and the four vertices ABCD are
            # A(-w / 2, -h / 2), B(w / 2, -h / 2), C(w / 2, h / 2), D(-w / 2, h / 2)
            # the midpoint of the left edge AD of the rotated box E is:
            # E = (A+D)/2 = (-w / 2, 0)
            # the midpoint of the top edge AB of the rotated box F is:
            # F(0, -h / 2)
            # To get the old coordinates in the global system, apply the rotation transformation
            # (Note: the right-handed coordinate system for image space is yOx):
            # (old_x, old_y) = (s * y + c * x, c * y - s * x)
            # E(old) = (s * 0 + c * (-w/2), c * 0 - s * (-w/2)) = (-c * w / 2, s * w / 2)
            # F(old) = (s * (-h / 2) + c * 0, c * (-h / 2) - s * 0) = (-s * h / 2, -c * h / 2)
            # After applying the scaling factor (sfx, sfy):
            # E(new) = (-sfx * c * w / 2, sfy * s * w / 2)
            # F(new) = (-sfx * s * h / 2, -sfy * c * h / 2)
            # The new width after scaling tranformation becomes:
    
            # w(new) = |E(new) - O| * 2
            #        = sqrt[(sfx * c * w / 2)^2 + (sfy * s * w / 2)^2] * 2
            #        = sqrt[(sfx * c)^2 + (sfy * s)^2] * w
            # i.e., scale_factor_w = sqrt[(sfx * c)^2 + (sfy * s)^2]
            #
            # For example,
            # when angle = 0 or 180, |c| = 1, s = 0, scale_factor_w == scale_factor_x;
            # when |angle| = 90, c = 0, |s| = 1, scale_factor_w == scale_factor_y
            self.tensor[:, 2] *= torch.sqrt((scale_x * c) ** 2 + (scale_y * s) ** 2)
    
            # h(new) = |F(new) - O| * 2
            #        = sqrt[(sfx * s * h / 2)^2 + (sfy * c * h / 2)^2] * 2
            #        = sqrt[(sfx * s)^2 + (sfy * c)^2] * h
            # i.e., scale_factor_h = sqrt[(sfx * s)^2 + (sfy * c)^2]
            #
            # For example,
            # when angle = 0 or 180, |c| = 1, s = 0, scale_factor_h == scale_factor_y;
            # when |angle| = 90, c = 0, |s| = 1, scale_factor_h == scale_factor_x
            self.tensor[:, 3] *= torch.sqrt((scale_x * s) ** 2 + (scale_y * c) ** 2)
    
            # The angle is the rotation angle from y-axis in image space to the height
            # vector (top->down in the box's local coordinate system) of the box in CCW.
            #
            # angle(new) = angle_yOx(O - F(new))
            #            = angle_yOx( (sfx * s * h / 2, sfy * c * h / 2) )
            #            = atan2(sfx * s * h / 2, sfy * c * h / 2)
            #            = atan2(sfx * s, sfy * c)
            #
            # For example,
            # when sfx == sfy, angle(new) == atan2(s, c) == angle(old)
            self.tensor[:, 4] = torch.atan2(scale_x * s, scale_y * c) * 180 / math.pi
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64

    支持计算成对旋转框 IOU 计算,

    def pairwise_iou(boxes1: RotatedBoxes, boxes2: RotatedBoxes) -> None:
        """
        Given two lists of rotated boxes of size N and M,
        compute the IoU (intersection over union)
        between **all** N x M pairs of boxes.
        The box order must be (x_center, y_center, width, height, angle).
    
        Args:
            boxes1, boxes2 (RotatedBoxes):
                two `RotatedBoxes`. Contains N & M rotated boxes, respectively.
    
        Returns:
            Tensor: IoU, sized [N,M].
        """
        return pairwise_iou_rotated(boxes1.tensor, boxes2.tensor)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    Instances 实例标注

    Instances数据结构包含一个图像的所有实例,如Boxes, Masks,可通过域操作设置和获取值。所有属性对应的实例数量许保持一致。

    instances=Instances((640,640), ...) 
    instances.gt_boxes= Boxes(...)
    pred_boxes=instances.pred_masks
    
    • 1
    • 2
    • 3

    可以通过python 语法判断是否包含特定结果。

    assert "gt_mask" in instances
    
    • 1

    可以通过len获取实例个数

    print(len(instances))
    
    • 1

    可以通过 index 获取特定实例

    # 获取得分大于0.9 的 实例
    confident_detections = instances[instances.scores > 0.9]
    
    
    • 1
    • 2
    • 3

    Keypoints

    存储关键点标注数据,

    gt_points= keypoints.gt_keypoints # (N, K,3)
    # N 个实例,每个实例K 个点, 每个点  x,y, visible
    
    • 1
    • 2

    可将 keypoint 转为 方形heatmap 格式。

    heatmaps= keypoints.to_heatmap(boxes, heatmap_size)
    
    • 1

    可将预测heatmap 转换为 keypoint 格式

    Masks

    通过COCO API 将多边形转为 Masks

    def polygons_to_bitmask(polygons: List[np.ndarray], height: int, width: int) -> np.ndarray:
        """
        Args:
            polygons (list[ndarray]): each array has shape (Nx2,)
            height, width (int)
    
        Returns:
            ndarray: a bool mask of shape (height, width)
        """
        if len(polygons) == 0:
            # COCOAPI does not support empty polygons
            return np.zeros((height, width)).astype(np.bool)
        rles = mask_util.frPyObjects(polygons, height, width)
        rle = mask_util.merge(rles)
        return mask_util.decode(rle).astype(np.bool)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    BitMasks 标注

    PolygonMasks

    ROI Masks

    均支持 get_bounding box 和 计算面积。

    结语

    detectron2 提供了多种标注类型的标准数据结构和丰富多样的API, 方便直接使用或者在其他项目中使用。

  • 相关阅读:
    C++ opencv随机数与随机颜色
    C#界面实时显示当前时间 定时器
    Java基础—重新抛出异常
    Word转为PDF后图片模糊怎么办?Word转为PDF的技巧介绍
    Python爬虫实战,requests+re模块,Python实现爬取豆瓣电影《魔女2》影评
    小程序中的confirm-type设置键盘的确认按钮
    USACO Guide银组3. 自定义比较器和坐标压缩
    PLGA10K-PEG2K-GA/疏水性嵌段聚丙交酯PLGA10K-乙交酯PEG2K-聚乙二醇GA
    【负载均衡式在线OJ项目day5】OJ服务模块概要
    同态加密简介HE
  • 原文地址:https://blog.csdn.net/u014515463/article/details/127927358