File size: 5,751 Bytes
88b0dcb |
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 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
"""
@date: 2021/6/29
@description:
The method with "_floorplan" suffix is only for comparison, which is used for calculation in LED2-net.
However, the floorplan is affected by show_radius. Setting too large will result in the decrease of accuracy,
and setting too small will result in the failure of calculation beyond the range.
"""
import numpy as np
from shapely.geometry import Polygon
def calc_inter_area(dt_xz, gt_xz):
"""
:param dt_xz: Prediction boundaries can also be corners, format: [[x1, z1], [x2, z2], ...]
:param gt_xz: Ground truth boundaries can also be corners, format: [[x1, z1], [x2, z2], ...]
:return:
"""
dt_polygon = Polygon(dt_xz)
gt_polygon = Polygon(gt_xz)
dt_area = dt_polygon.area
gt_area = gt_polygon.area
inter_area = dt_polygon.intersection(gt_polygon).area
return dt_area, gt_area, inter_area
def calc_IoU_2D(dt_xz, gt_xz):
"""
:param dt_xz: Prediction boundaries can also be corners, format: [[x1, z1], [x2, z2], ...]
:param gt_xz: Ground truth boundaries can also be corners, format: [[x1, z1], [x2, z2], ...]
:return:
"""
dt_area, gt_area, inter_area = calc_inter_area(dt_xz, gt_xz)
iou_2d = inter_area / (gt_area + dt_area - inter_area)
return iou_2d
def calc_IoU_3D(dt_xz, gt_xz, dt_height, gt_height):
"""
:param dt_xz: Prediction boundaries can also be corners, format: [[x1, z1], [x2, z2], ...]
:param gt_xz: Ground truth boundaries can also be corners, format: [[x1, z1], [x2, z2], ...]
:param dt_height:
:param gt_height:
:return:
"""
dt_area, gt_area, inter_area = calc_inter_area(dt_xz, gt_xz)
dt_volume = dt_area * dt_height
gt_volume = gt_area * gt_height
inter_volume = inter_area * min(dt_height, gt_height)
iou_3d = inter_volume / (dt_volume + gt_volume - inter_volume)
return iou_3d
def calc_IoU(dt_xz, gt_xz, dt_height, gt_height):
"""
:param dt_xz: Prediction boundaries can also be corners, format: [[x1, z1], [x2, z2], ...]
:param gt_xz: Ground truth boundaries can also be corners, format: [[x1, z1], [x2, z2], ...]
:param dt_height:
:param gt_height:
:return:
"""
dt_area, gt_area, inter_area = calc_inter_area(dt_xz, gt_xz)
iou_2d = inter_area / (gt_area + dt_area - inter_area)
dt_volume = dt_area * dt_height
gt_volume = gt_area * gt_height
inter_volume = inter_area * min(dt_height, gt_height)
iou_3d = inter_volume / (dt_volume + gt_volume - inter_volume)
return iou_2d, iou_3d
def calc_Iou_height(dt_height, gt_height):
return min(dt_height, gt_height) / max(dt_height, gt_height)
# the following is for testing only
def calc_inter_area_floorplan(dt_floorplan, gt_floorplan):
intersect = np.sum(np.logical_and(dt_floorplan, gt_floorplan))
dt_area = np.sum(dt_floorplan)
gt_area = np.sum(gt_floorplan)
return dt_area, gt_area, intersect
def calc_IoU_2D_floorplan(dt_floorplan, gt_floorplan):
dt_area, gt_area, inter_area = calc_inter_area_floorplan(dt_floorplan, gt_floorplan)
iou_2d = inter_area / (gt_area + dt_area - inter_area)
return iou_2d
def calc_IoU_3D_floorplan(dt_floorplan, gt_floorplan, dt_height, gt_height):
dt_area, gt_area, inter_area = calc_inter_area_floorplan(dt_floorplan, gt_floorplan)
dt_volume = dt_area * dt_height
gt_volume = gt_area * gt_height
inter_volume = inter_area * min(dt_height, gt_height)
iou_3d = inter_volume / (dt_volume + gt_volume - inter_volume)
return iou_3d
def calc_IoU_floorplan(dt_floorplan, gt_floorplan, dt_height, gt_height):
dt_area, gt_area, inter_area = calc_inter_area_floorplan(dt_floorplan, gt_floorplan)
iou_2d = inter_area / (gt_area + dt_area - inter_area)
dt_volume = dt_area * dt_height
gt_volume = gt_area * gt_height
inter_volume = inter_area * min(dt_height, gt_height)
iou_3d = inter_volume / (dt_volume + gt_volume - inter_volume)
return iou_2d, iou_3d
if __name__ == '__main__':
from visualization.floorplan import draw_floorplan, draw_iou_floorplan
from visualization.boundary import draw_boundaries, corners2boundaries
from utils.conversion import uv2xyz
from utils.height import height2ratio
# dummy data
dt_floor_corners = np.array([[0.2, 0.7],
[0.4, 0.7],
[0.6, 0.7],
[0.8, 0.7]])
dt_height = 2.8
gt_floor_corners = np.array([[0.3, 0.7],
[0.5, 0.7],
[0.7, 0.7],
[0.9, 0.7]])
gt_height = 3.2
dt_xz = uv2xyz(dt_floor_corners)[..., ::2]
gt_xz = uv2xyz(gt_floor_corners)[..., ::2]
dt_floorplan = draw_floorplan(dt_xz, show=False, show_radius=1)
gt_floorplan = draw_floorplan(gt_xz, show=False, show_radius=1)
# dt_floorplan = draw_floorplan(dt_xz, show=False, show_radius=2)
# gt_floorplan = draw_floorplan(gt_xz, show=False, show_radius=2)
iou_2d, iou_3d = calc_IoU_floorplan(dt_floorplan, gt_floorplan, dt_height, gt_height)
print('use floor plan image:', iou_2d, iou_3d)
iou_2d, iou_3d = calc_IoU(dt_xz, gt_xz, dt_height, gt_height)
print('use floor plan polygon:', iou_2d, iou_3d)
draw_iou_floorplan(dt_xz, gt_xz, show=True, iou_2d=iou_2d, iou_3d=iou_3d)
pano_bd = draw_boundaries(np.zeros([512, 1024, 3]), corners_list=[dt_floor_corners],
boundary_color=[0, 0, 1], ratio=height2ratio(dt_height), draw_corners=False)
pano_bd = draw_boundaries(pano_bd, corners_list=[gt_floor_corners],
boundary_color=[0, 1, 0], ratio=height2ratio(gt_height), show=True, draw_corners=False)
|