166 lines
4.5 KiB
Python
166 lines
4.5 KiB
Python
|
|
import numpy as np
|
|
import copy
|
|
import math
|
|
|
|
from utils.camera import pixel_to_camera, get_keypoints
|
|
from eval.geom_baseline import compute_distance_single
|
|
|
|
|
|
def eval_geometric(uv_kps, uv_centers, uv_shoulders, kk, average_y=0.48):
|
|
"""
|
|
Evaluate geometric distance
|
|
"""
|
|
xy_centers = []
|
|
dds_geom = []
|
|
for idx, _ in enumerate(uv_centers):
|
|
uv_center = copy.deepcopy(uv_centers[idx])
|
|
uv_center.append(1)
|
|
uv_shoulder = copy.deepcopy(uv_shoulders[idx])
|
|
uv_shoulder.append(1)
|
|
uv_kp = uv_kps[idx]
|
|
xy_center = pixel_to_camera(uv_center, kk, 1)
|
|
xy_centers.append(xy_center.tolist())
|
|
|
|
uu_2, vv_2 = get_keypoints(uv_kp[0], uv_kp[1], mode='hip')
|
|
uv_hip = [uu_2, vv_2, 1]
|
|
|
|
zz, _ = compute_distance_single(uv_shoulder, uv_hip, kk, average_y)
|
|
xyz_center = np.array([xy_center[0], xy_center[1], zz])
|
|
dd_geom = float(np.linalg.norm(xyz_center))
|
|
dds_geom.append(dd_geom)
|
|
|
|
return dds_geom, xy_centers
|
|
|
|
|
|
def get_calibration(path_txt):
|
|
"""Read calibration parameters from txt file:
|
|
For the left color camera we use P2 which is K * [I|t]
|
|
|
|
P = [fu, 0, x0, fu*t1-x0*t3
|
|
0, fv, y0, fv*t2-y0*t3
|
|
0, 0, 1, t3]
|
|
|
|
check also http://ksimek.github.io/2013/08/13/intrinsic/
|
|
|
|
Simple case test:
|
|
xyz = np.array([2, 3, 30, 1]).reshape(4, 1)
|
|
xyz_2 = xyz[0:-1] + tt
|
|
uv_temp = np.dot(kk, xyz_2)
|
|
uv_1 = uv_temp / uv_temp[-1]
|
|
kk_1 = np.linalg.inv(kk)
|
|
xyz_temp2 = np.dot(kk_1, uv_1)
|
|
xyz_new_2 = xyz_temp2 * xyz_2[2]
|
|
xyz_fin_2 = xyz_new_2 - tt
|
|
"""
|
|
|
|
with open(path_txt, "r") as ff:
|
|
file = ff.readlines()
|
|
p2_str = file[2].split()[1:]
|
|
p2_list = [float(xx) for xx in p2_str]
|
|
p2 = np.array(p2_list).reshape(3, 4)
|
|
|
|
kk = p2[:, :-1]
|
|
f_x = kk[0, 0]
|
|
f_y = kk[1, 1]
|
|
x0 = kk[2, 0]
|
|
y0 = kk[2, 1]
|
|
aa = p2[0, 3]
|
|
bb = p2[1, 3]
|
|
t3 = p2[2, 3]
|
|
t1 = (aa - x0*t3) / f_x
|
|
t2 = (bb - y0*t3) / f_y
|
|
tt = np.array([t1, t2, t3]).reshape(3, 1)
|
|
return kk, tt
|
|
|
|
|
|
def get_simplified_calibration(path_txt):
|
|
|
|
with open(path_txt, "r") as ff:
|
|
file = ff.readlines()
|
|
|
|
for line in file:
|
|
if line[:4] == 'K_02':
|
|
kk_str = line[4:].split()[1:]
|
|
kk_list = [float(xx) for xx in kk_str]
|
|
kk = np.array(kk_list).reshape(3, 3).tolist()
|
|
return kk
|
|
|
|
raise ValueError('Matrix K_02 not found in the file')
|
|
|
|
|
|
def check_conditions(line, mode, thresh=0.5):
|
|
|
|
"""Check conditions of our or m3d txt file"""
|
|
|
|
check = False
|
|
assert mode == 'gt' or mode == 'm3d' or mode == '3dop' or mode == 'our', "Type not recognized"
|
|
|
|
if mode == 'm3d' or mode == '3dop':
|
|
conf = line.split()[15]
|
|
if line[:10] == 'pedestrian' and float(conf) >= thresh:
|
|
check = True
|
|
|
|
elif mode == 'gt':
|
|
if line[:10] == 'Pedestrian':
|
|
check = True
|
|
|
|
elif mode == 'our':
|
|
if line[10] >= thresh:
|
|
check = True
|
|
|
|
return check
|
|
|
|
|
|
def get_category(box, trunc, occ):
|
|
|
|
hh = box[3] - box[1]
|
|
|
|
if hh >= 40 and trunc <= 0.15 and occ <= 0:
|
|
cat = 'easy'
|
|
elif trunc <= 0.3 and occ <= 1:
|
|
cat = 'moderate'
|
|
else:
|
|
cat = 'hard'
|
|
|
|
return cat
|
|
|
|
|
|
def split_training(names_gt, path_train, path_val):
|
|
"""Split training and validation images"""
|
|
set_gt = set(names_gt)
|
|
set_train = set()
|
|
set_val = set()
|
|
|
|
with open(path_train, "r") as f_train:
|
|
for line in f_train:
|
|
set_train.add(line[:-1] + '.txt')
|
|
with open(path_val, "r") as f_val:
|
|
for line in f_val:
|
|
set_val.add(line[:-1] + '.txt')
|
|
|
|
set_train = tuple(set_gt.intersection(set_train))
|
|
set_val = tuple(set_gt.intersection(set_val))
|
|
assert set_train and set_val, "No validation or training annotations"
|
|
return set_train, set_val
|
|
|
|
|
|
def parse_ground_truth(path_gt):
|
|
"""Parse KITTI ground truth files"""
|
|
boxes_gt = []
|
|
dds_gt = []
|
|
truncs_gt = [] # Float from 0 to 1
|
|
occs_gt = [] # Either 0,1,2,3 fully visible, partly occluded, largely occluded, unknown
|
|
|
|
with open(path_gt, "r") as f_gt:
|
|
for line_gt in f_gt:
|
|
if check_conditions(line_gt, mode='gt'):
|
|
truncs_gt.append(float(line_gt.split()[1]))
|
|
occs_gt.append(int(line_gt.split()[2]))
|
|
boxes_gt.append([float(x) for x in line_gt.split()[4:8]])
|
|
loc_gt = [float(x) for x in line_gt.split()[11:14]]
|
|
dds_gt.append(math.sqrt(loc_gt[0] ** 2 + loc_gt[1] ** 2 + loc_gt[2] ** 2))
|
|
|
|
return boxes_gt, dds_gt, truncs_gt, occs_gt
|
|
|