|
""" |
|
@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) |
|
|
|
|
|
|
|
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 |
|
|
|
|
|
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) |
|
|
|
|
|
|
|
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) |
|
|