Skip to content

Commit

Permalink
Disparity calculation (#12)
Browse files Browse the repository at this point in the history
* add filter for z < 40

* change figure name

* stereo results in figure

* stereo figure

* pylint

* pylint(2)

* pylint updated
  • Loading branch information
bertoni9 committed Oct 7, 2019
1 parent 4071971 commit 39eef31
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 59 deletions.
6 changes: 3 additions & 3 deletions monoloco/eval/eval_kitti.py
Expand Up @@ -113,7 +113,7 @@ def run(self):

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)

Expand Down Expand Up @@ -178,7 +178,7 @@ def _estimate_error(self, out_gt, out, method):
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):
Expand Down Expand Up @@ -211,7 +211,7 @@ def _compare_error(self, out_gt, methods_out):
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:
Expand Down
5 changes: 3 additions & 2 deletions monoloco/eval/stereo_baselines.py
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion monoloco/run.py
Expand Up @@ -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)

Expand Down
2 changes: 1 addition & 1 deletion monoloco/train/trainer.py
Expand Up @@ -231,7 +231,7 @@ def evaluate(self, load=False, model=None, debug=False):
# Debug plot for input-output distributions
if debug:
debug_plots(inputs, labels)
exit()
sys.exit()

# Forward pass
outputs = self.model(inputs)
Expand Down
3 changes: 2 additions & 1 deletion monoloco/utils/kitti.py
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions monoloco/utils/misc.py
Expand Up @@ -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):
Expand Down
114 changes: 66 additions & 48 deletions monoloco/visuals/figures.py
@@ -1,4 +1,3 @@

# pylint: disable=R0915

import math
Expand All @@ -9,11 +8,10 @@
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
"""
Expand All @@ -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']

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=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()
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)

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.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):
Expand All @@ -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]")
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -193,7 +194,6 @@ def calculate_gmm():


def get_confidence(xx, zz, std):

theta = math.atan2(zz, xx)

delta_x = std * math.cos(theta)
Expand All @@ -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)
Expand All @@ -230,7 +228,6 @@ def get_confidence_points(confidences, distances, errors):


def height_distributions():

mu_men = 178
std_men = 7
mu_women = 165
Expand All @@ -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")
Expand All @@ -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

0 comments on commit 39eef31

Please sign in to comment.