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)
    
    不论你在什么时候开始,重要的是开始之后就不要停止。 不论你在什么时候结束,重要的是结束之后就不要悔恨。
  • 相关阅读:
    C语言-if语句
    C语言-表达式
    C语言-基础
    Java for LeetCode 187 Repeated DNA Sequences
    Java for LeetCode 179 Largest Number
    Java for LeetCode 174 Dungeon Game
    Java for LeetCode 173 Binary Search Tree Iterator
    Java for LeetCode 172 Factorial Trailing Zeroes
    Java for LeetCode 171 Excel Sheet Column Number
    Java for LeetCode 169 Majority Element
  • 原文地址:https://www.cnblogs.com/yunhgu/p/15524127.html
Copyright © 2011-2022 走看看