Disparity calculation (#12)

* add filter for z < 40

* change figure name

* stereo results in figure

* stereo figure

* pylint

* pylint(2)

* pylint updated
This commit is contained in:
Lorenzo Bertoni 2019-10-07 11:28:54 +02:00 committed by GitHub
parent 4071971e48
commit 39eef3195b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 77 additions and 57 deletions

View File

@ -113,7 +113,7 @@ class EvalKitti:
def printer(self, show, save):
if save or show:
show_results(self.dic_stats, show, save)
show_results(self.dic_stats, show, save, stereo=self.stereo)
show_spread(self.dic_stats, show, save)
show_task_error(show, save)
@ -178,7 +178,7 @@ class EvalKitti:
self.update_uncertainty(stds_ale[idx], stds_epi[idx], dds[idx], dds_gt[idx_gt], cat)
dd_task_error = dds_gt[idx_gt] + (get_task_error(dds_gt[idx_gt]))**2
self.update_errors(dd_task_error, dds_gt[idx_gt], cat, self.errors['task_error'])
dd_pixel_error = get_pixel_error(dds_gt[idx_gt], zzs_gt[idx_gt])
dd_pixel_error = dds_gt[idx_gt] + get_pixel_error(zzs_gt[idx_gt])
self.update_errors(dd_pixel_error, dds_gt[idx_gt], cat, self.errors['pixel_error'])
def _compare_error(self, out_gt, methods_out):
@ -211,7 +211,7 @@ class EvalKitti:
self.update_errors(dd_monoloco, dd_gt, cat, self.errors['monoloco_merged'])
self.update_errors(dd_geometric, dd_gt, cat, self.errors['geometric_merged'])
self.update_errors(dd_gt + get_task_error(dd_gt), dd_gt, cat, self.errors['task_error_merged'])
dd_pixel = get_pixel_error(dd_gt, zzs_gt[idx_gt])
dd_pixel = dd_gt + get_pixel_error(zzs_gt[idx_gt])
self.update_errors(dd_pixel, dd_gt, cat, self.errors['pixel_error_merged'])
for key in self.methods:

View File

@ -20,7 +20,7 @@ def baselines_association(baselines, zzs, keypoints, keypoints_right, reid_featu
keypoints, keypoints_right, baselines, reid_features)
# count maximum possible associations
cnt_stereo['max'] = min(keypoints.shape[0], keypoints_r.shape[0])
cnt_stereo['max'] = min(keypoints.shape[0], keypoints_r.shape[0]) # pylint: disable=E1136
# Filter joints disparity and calculate avg disparity
avg_disparities, disparities_x, disparities_y = mask_joint_disparity(keypoints, keypoints_r)
@ -161,7 +161,8 @@ def verify_stereo(zz_stereo, zz_mono, disparity_x, disparity_y):
if abs(zz_stereo - zz_mono) < z_max_difference and \
avg_disparity_y < y_max_difference and \
cov < COV_MIN:
cov < COV_MIN\
and 4 < zz_stereo < 40:
return True
# if not np.isnan(zz_stereo):
# return True

View File

@ -128,7 +128,7 @@ def main():
elif args.command == 'eval':
if args.geometric:
assert args.joints, "joints argument not provided"
assert args.joints, "joints argument not provided"
from .eval import geometric_baseline
geometric_baseline(args.joints)

View File

@ -231,7 +231,7 @@ class Trainer:
# Debug plot for input-output distributions
if debug:
debug_plots(inputs, labels)
exit()
sys.exit()
# Forward pass
outputs = self.model(inputs)

View File

@ -93,8 +93,9 @@ def check_conditions(line, category, method, thresh=0.3):
check = True
else:
zz = float(line[13])
conf = float(line[15])
if conf >= thresh:
if conf >= thresh and 0.5 < zz < 70:
check = True
return check

View File

@ -30,12 +30,12 @@ def get_task_error(dd):
return dd * mm
def get_pixel_error(dd_gt, zz_gt):
def get_pixel_error(zz_gt):
"""calculate error in stereo distance due to 1 pixel mismatch (function of depth)"""
disp = 0.54 * 721 / zz_gt
delta_z = zz_gt - 0.54 * 721 / (disp - 1)
return dd_gt + delta_z
error = abs(zz_gt - 0.54 * 721 / (disp - 1))
return error
def open_annotations(path_ann):

View File

@ -1,4 +1,3 @@
# pylint: disable=R0915
import math
@ -9,11 +8,10 @@ import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Ellipse
from ..utils import get_task_error
from ..utils import get_task_error, get_pixel_error
def show_results(dic_stats, show=False, save=False):
def show_results(dic_stats, show=False, save=False, stereo=False):
"""
Visualize error as function of the distance and compare it with target errors based on human height analyses
"""
@ -22,40 +20,41 @@ def show_results(dic_stats, show=False, save=False):
phase = 'test'
x_min = 0
x_max = 38
y_min = 0
y_max = 4.7
xx = np.linspace(0, 60, 100)
excl_clusters = ['all', '50', '>50', 'easy', 'moderate', 'hard']
clusters = tuple([clst for clst in dic_stats[phase]['monoloco'] if clst not in excl_clusters])
yy_gender = get_task_error(xx)
plt.figure(0)
plt.grid(linewidth=0.2)
plt.xlabel("Ground-truth distance [m]")
plt.ylabel("Average localization error [m]")
plt.xlim(x_min, x_max)
labels = ['Mono3D', 'Geometric Baseline', 'MonoDepth', 'Our MonoLoco', '3DOP (stereo)']
mks = ['*', '^', 'p', 's', 'o']
mksizes = [6, 6, 6, 6, 6]
lws = [1.5, 1.5, 1.5, 2.2, 1.6]
colors = ['r', 'deepskyblue', 'grey', 'b', 'darkorange']
lstyles = ['solid', 'solid', 'solid', 'solid', 'dashdot']
styles = printing_styles(stereo)
for idx_style, (key, style) in enumerate(styles.items()):
plt.figure(idx_style)
plt.grid(linewidth=0.2)
plt.xlim(x_min, x_max)
plt.ylim(y_min, y_max)
plt.xlabel("Ground-truth distance [m]")
plt.ylabel("Average localization error [m]")
for idx, method in enumerate(style['methods']):
errs = [dic_stats[phase][method][clst]['mean'] for clst in clusters]
assert errs, "method %s empty" % method
xxs = get_distances(clusters)
for idx, method in enumerate(['m3d_merged', 'geometric_merged', 'monodepth_merged', 'monoloco_merged',
'3dop_merged']):
errs = [dic_stats[phase][method][clst]['mean'] for clst in clusters]
assert errs, "method %s empty" % method
xxs = get_distances(clusters)
plt.plot(xxs, errs, marker=style['mks'][idx], markersize=style['mksizes'][idx], linewidth=style['lws'][idx],
label=style['labels'][idx], linestyle=style['lstyles'][idx], color=style['colors'][idx])
plt.plot(xx, yy_gender, '--', label="Task error", color='lightgreen', linewidth=2.5)
if key == 'stereo':
yy_stereo = get_pixel_error(xx)
plt.plot(xx, yy_stereo, linewidth=1.7, color='k', label='Pixel error')
plt.plot(xxs, errs, marker=mks[idx], markersize=mksizes[idx], linewidth=lws[idx], label=labels[idx],
linestyle=lstyles[idx], color=colors[idx])
plt.plot(xx, yy_gender, '--', label="Task error", color='lightgreen', linewidth=2.5)
plt.legend(loc='upper left')
if save:
path_fig = os.path.join(dir_out, 'results.png')
plt.savefig(path_fig)
print("Figure of results saved in {}".format(path_fig))
if show:
plt.show()
plt.close()
plt.legend(loc='upper left')
if save:
path_fig = os.path.join(dir_out, 'results_' + key + '.png')
plt.savefig(path_fig)
print("Figure of results " + key + " saved in {}".format(path_fig))
if show:
plt.show()
plt.close()
def show_spread(dic_stats, show=False, save=False):
@ -66,7 +65,7 @@ def show_spread(dic_stats, show=False, save=False):
excl_clusters = ['all', '50', '>50', 'easy', 'moderate', 'hard']
clusters = tuple([clst for clst in dic_stats[phase]['our'] if clst not in excl_clusters])
plt.figure(1)
plt.figure(2)
fig, ax = plt.subplots(2, sharex=True)
plt.xlabel("Distance [m]")
plt.ylabel("Aleatoric uncertainty [m]")
@ -80,10 +79,10 @@ def show_spread(dic_stats, show=False, save=False):
yys = get_task_error(np.array(xxs))
ax[1].plot(xxs, bbs, marker='s', color='b', label="Spread b")
ax[1].plot(xxs, yys, '--', color='lightgreen', label="Task error", linewidth=2.5)
yys_up = [rec_c + ar/2 * scale * yy for yy in yys]
bbs_up = [rec_c + ar/2 * scale * bb for bb in bbs]
yys_down = [rec_c - ar/2 * scale * yy for yy in yys]
bbs_down = [rec_c - ar/2 * scale * bb for bb in bbs]
yys_up = [rec_c + ar / 2 * scale * yy for yy in yys]
bbs_up = [rec_c + ar / 2 * scale * bb for bb in bbs]
yys_down = [rec_c - ar / 2 * scale * yy for yy in yys]
bbs_down = [rec_c - ar / 2 * scale * bb for bb in bbs]
if plots_line:
ax[0].plot(xxs, yys_up, '--', color='lightgreen', markersize=5, linewidth=1.4)
@ -92,8 +91,8 @@ def show_spread(dic_stats, show=False, save=False):
ax[0].plot(xxs, bbs_down, marker='s', color='b', markersize=5, linewidth=0.7)
for idx, xx in enumerate(xxs):
te = Ellipse((xx, rec_c), width=yys[idx]*ar*scale, height=scale, angle=90, color='lightgreen', fill=True)
bi = Ellipse((xx, rec_c), width=bbs[idx]*ar*scale, height=scale, angle=90, color='b', linewidth=1.8,
te = Ellipse((xx, rec_c), width=yys[idx] * ar * scale, height=scale, angle=90, color='lightgreen', fill=True)
bi = Ellipse((xx, rec_c), width=bbs[idx] * ar * scale, height=scale, angle=90, color='b', linewidth=1.8,
fill=False)
ax[0].add_patch(te)
@ -113,9 +112,9 @@ def show_spread(dic_stats, show=False, save=False):
def show_task_error(show, save):
"""Task error figure"""
plt.figure(2)
plt.figure(3)
dir_out = 'docs'
xx = np.linspace(0, 40, 100)
xx = np.linspace(0.1, 50, 100)
mu_men = 178
mu_women = 165
mu_child_m = 164
@ -128,12 +127,14 @@ def show_task_error(show, save):
yy_young_male = target_error(xx, mm_young_male)
yy_young_female = target_error(xx, mm_young_female)
yy_gender = target_error(xx, mm_gmm)
yy_stereo = get_pixel_error(xx)
plt.grid(linewidth=0.3)
plt.plot(xx, yy_young_male, linestyle='dotted', linewidth=2.1, color='b', label='Adult/young male')
plt.plot(xx, yy_young_female, linestyle='dotted', linewidth=2.1, color='darkorange', label='Adult/young female')
plt.plot(xx, yy_gender, '--', color='lightgreen', linewidth=2.8, label='Generic adult (task error)')
plt.plot(xx, yy_female, '-.', linewidth=1.7, color='darkorange', label='Adult female')
plt.plot(xx, yy_male, '-.', linewidth=1.7, color='b', label='Adult male')
plt.plot(xx, yy_stereo, linewidth=1.7, color='k', label='Pixel error')
plt.xlim(np.min(xx), np.max(xx))
plt.xlabel("Ground-truth distance from the camera $d_{gt}$ [m]")
plt.ylabel("Localization error $\hat{e}$ due to human height variation [m]") # pylint: disable=W1401
@ -193,7 +194,6 @@ def calculate_gmm():
def get_confidence(xx, zz, std):
theta = math.atan2(zz, xx)
delta_x = std * math.cos(theta)
@ -215,11 +215,9 @@ def get_distances(clusters):
def get_confidence_points(confidences, distances, errors):
confidence_points = []
distance_points = []
for idx, dd in enumerate(distances):
conf_perc = confidences[idx]
confidence_points.append(errors[idx] + conf_perc)
confidence_points.append(errors[idx] - conf_perc)
@ -230,7 +228,6 @@ def get_confidence_points(confidences, distances, errors):
def height_distributions():
mu_men = 178
std_men = 7
mu_women = 165
@ -256,7 +253,7 @@ def expandgrid(*itrs):
def plot_dist(dist_gmm, dist_men, dist_women):
try:
import seaborn as sns
import seaborn as sns # pylint: disable=C0415
sns.distplot(dist_men, hist=False, rug=False, label="Men")
sns.distplot(dist_women, hist=False, rug=False, label="Women")
sns.distplot(dist_gmm, hist=False, rug=False, label="GMM")
@ -273,9 +270,30 @@ def get_percentile(dist_gmm):
dd_gt = 1000
mu_gmm = np.mean(dist_gmm)
dist_d = dd_gt * mu_gmm / dist_gmm
perc_d, _ = np.nanpercentile(dist_d, [18.5, 81.5]) # Laplace bi => 63%
perc_d, _ = np.nanpercentile(dist_d, [18.5, 81.5]) # Laplace bi => 63%
perc_d2, _ = np.nanpercentile(dist_d, [23, 77])
mu_d = np.mean(dist_d)
# mm_bi = (mu_d - perc_d) / mu_d
# mm_test = (mu_d - perc_d2) / mu_d
# mad_d = np.mean(np.abs(dist_d - mu_d))
def printing_styles(stereo):
style = {'mono': {"labels": ['Mono3D', 'Geometric Baseline', 'MonoDepth', 'Our MonoLoco', '3DOP (stereo)'],
"methods": ['m3d_merged', 'geometric_merged', 'monodepth_merged', 'monoloco_merged',
'3dop_merged'],
"mks": ['*', '^', 'p', 's', 'o'],
"mksizes": [6, 6, 6, 6, 6], "lws": [1.5, 1.5, 1.5, 2.2, 1.6],
"colors": ['r', 'deepskyblue', 'grey', 'b', 'darkorange'],
"lstyles": ['solid', 'solid', 'solid', 'solid', 'dashdot']}}
if stereo:
style['stereo'] = {"labels": ['3DOP', 'Pose Baseline', 'ReiD Baseline', 'Our MonoLoco (monocular)',
'Our Stereo Baseline'],
"methods": ['3dop_merged', 'pose_merged', 'reid_merged', 'monoloco_merged',
'ml_stereo_merged'],
"mks": ['o', '^', 'p', 's', 's'],
"mksizes": [6, 6, 6, 4, 6], "lws": [1.5, 1.5, 1.5, 1.2, 1.5],
"colors": ['darkorange', 'lightblue', 'red', 'b', 'b'],
"lstyles": ['solid', 'solid', 'solid', 'dashed', 'solid']}
return style