zoukankan      html  css  js  c++  java
  • 3D_IOU 计算

    #! /usr/bin/env python
    # -*- coding: utf-8 -*-#
    # 3D IoU caculate code for 3D object detection
    # Kent 2018/12
    
    import numpy as np
    from scipy.spatial import ConvexHull
    from numpy import *
    
    
    def polygon_clip(subjectPolygon, clipPolygon):
        """ Clip a polygon with another polygon.
        Ref: https://rosettacode.org/wiki/Sutherland-Hodgman_polygon_clipping#Python
        Args:
          subjectPolygon: a list of (x,y) 2d points, any polygon.
          clipPolygon: a list of (x,y) 2d points, has to be *convex*
        Note:
          **points have to be counter-clockwise ordered**
        Return:
          a list of (x,y) vertex point for the intersection polygon.
        """
    
        def inside(p):
            return (cp2[0] - cp1[0]) * (p[1] - cp1[1]) > (cp2[1] - cp1[1]) * (p[0] - cp1[0])
    
        def computeIntersection():
            dc = [cp1[0] - cp2[0], cp1[1] - cp2[1]]
            dp = [s[0] - e[0], s[1] - e[1]]
            n1 = cp1[0] * cp2[1] - cp1[1] * cp2[0]
            n2 = s[0] * e[1] - s[1] * e[0]
            n3 = 1.0 / (dc[0] * dp[1] - dc[1] * dp[0])
            return [(n1 * dp[0] - n2 * dc[0]) * n3, (n1 * dp[1] - n2 * dc[1]) * n3]
    
        outputList = subjectPolygon
        cp1 = clipPolygon[-1]
    
        for clipVertex in clipPolygon:
            cp2 = clipVertex
            inputList = outputList
            outputList = []
            s = inputList[-1]
    
            for subjectVertex in inputList:
                e = subjectVertex
                if inside(e):
                    if not inside(s):
                        outputList.append(computeIntersection())
                    outputList.append(e)
                elif inside(s):
                    outputList.append(computeIntersection())
                s = e
            cp1 = cp2
            if len(outputList) == 0:
                return None
        return outputList
    
    
    def poly_area(x, y):
        """ Ref: http://stackoverflow.com/questions/24467972/calculate-area-of-polygon-given-x-y-coordinates """
        return 0.5 * np.abs(np.dot(x, np.roll(y, 1)) - np.dot(y, np.roll(x, 1)))
    
    
    def convex_hull_intersection(p1, p2):
        """ Compute area of two convex hull's intersection area.
            p1,p2 are a list of (x,y) tuples of hull vertices.
            return a list of (x,y) for the intersection and its volume
        """
        inter_p = polygon_clip(p1, p2)
        if inter_p is not None:
            hull_inter = ConvexHull(inter_p)
            return inter_p, hull_inter.volume
        else:
            return None, 0.0
    
    
    def box3d_vol(corners):
        """
        corners: (8,3) no assumption on axis direction
        """
        a = np.sqrt(np.sum((corners[0, :] - corners[1, :]) ** 2))
        b = np.sqrt(np.sum((corners[1, :] - corners[2, :]) ** 2))
        c = np.sqrt(np.sum((corners[0, :] - corners[4, :]) ** 2))
        return a * b * c
    
    
    def is_clockwise(p):
        x = p[:, 0]
        y = p[:, 1]
        return np.dot(x, np.roll(y, 1)) - np.dot(y, np.roll(x, 1)) > 0
    
    
    def box3d_iou(corners1, corners2):
        """ Compute 3D bounding box IoU.
        Input:
            corners1: numpy array (8,3), assume up direction is negative Y
            corners2: numpy array (8,3), assume up direction is negative Y
        Output:
            iou: 3D bounding box IoU
            iou_2d: bird's eye view 2D bounding box IoU
        todo (kent): add more description on corner points' orders.
        """
        # corner points are in counter clockwise order
        rect1 = [(corners1[i, 0], corners1[i, 2]) for i in range(3, -1, -1)]
        rect2 = [(corners2[i, 0], corners2[i, 2]) for i in range(3, -1, -1)]
    
        area1 = poly_area(np.array(rect1)[:, 0], np.array(rect1)[:, 1])
        area2 = poly_area(np.array(rect2)[:, 0], np.array(rect2)[:, 1])
    
        inter, inter_area = convex_hull_intersection(rect1, rect2)
        iou_2d = inter_area / (area1 + area2 - inter_area)
        ymax = min(corners1[0, 1], corners2[0, 1])
        ymin = max(corners1[4, 1], corners2[4, 1])
    
        inter_vol = inter_area * max(0.0, ymax - ymin)
    
        vol1 = box3d_vol(corners1)
        vol2 = box3d_vol(corners2)
        iou = inter_vol / (vol1 + vol2 - inter_vol)
        return iou, iou_2d
    
    
    # ----------------------------------
    # Helper functions for evaluation
    # ----------------------------------
    
    def get_3d_box(box_size, heading_angle, center):
        """ Calculate 3D bounding box corners from its parameterization.
        Input:
            box_size: tuple of (length,wide,height)
            heading_angle: rad scalar, clockwise from pos x axis
            center: tuple of (x,y,z)
        Output:
            corners_3d: numpy array of shape (8,3) for 3D box cornders
        """
    
        def roty(t):
            c = np.cos(t)
            s = np.sin(t)
            return np.array([[c, 0, s],
                             [0, 1, 0],
                             [-s, 0, c]])
    
        R = roty(heading_angle)
        l, w, h = box_size
        x_corners = [l / 2, l / 2, -l / 2, -l / 2, l / 2, l / 2, -l / 2, -l / 2]
        y_corners = [h / 2, h / 2, h / 2, h / 2, -h / 2, -h / 2, -h / 2, -h / 2]
        z_corners = [w / 2, -w / 2, -w / 2, w / 2, w / 2, -w / 2, -w / 2, w / 2]
        corners_3d = np.dot(R, np.vstack([x_corners, y_corners, z_corners]))
        corners_3d[0, :] = corners_3d[0, :] + center[0]
        corners_3d[1, :] = corners_3d[1, :] + center[1]
        corners_3d[2, :] = corners_3d[2, :] + center[2]
        corners_3d = np.transpose(corners_3d)
        return corners_3d
    
    
    if __name__ == '__main__':
        print('------------------')
        # get_3d_box(box_size, heading_angle, center)
        corners_3d_ground = get_3d_box((1.497255, 1.644981, 3.628938), -1.531692, (2.882992, 1.698800, 20.785644))
        corners_3d_predict = get_3d_box((1.458242, 1.604773, 3.707947), -1.549553, (2.756923, 1.661275, 20.943280))
        (IOU_3d, IOU_2d) = box3d_iou(corners_3d_predict, corners_3d_ground)
        print(IOU_3d, IOU_2d)  # 3d IoU/ 2d IoU of BEV(bird eye's view)
    
    不论你在什么时候开始,重要的是开始之后就不要停止。 不论你在什么时候结束,重要的是结束之后就不要悔恨。
  • 相关阅读:
    python pandas groupby
    ORC 资料Mark
    python split() 用法
    Hive 中的变量
    特征选择方法
    Introduction to SIFT (Scale-Invariant Feature Transform)
    SIFT 、Hog 、LBP 了解
    python None 和 NaN
    判断特征中是否含有空值、空值填充
    vue 子组件引用
  • 原文地址:https://www.cnblogs.com/yunhgu/p/15524127.html
Copyright © 2011-2022 走看看