Initial snapshot: hand motion pipeline (Dyn-HaMR + dex-retargeting + SPIDER)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+134
@@ -0,0 +1,134 @@
|
||||
import sys
|
||||
sys.path.append('droid_slam')
|
||||
|
||||
from tqdm import tqdm
|
||||
import numpy as np
|
||||
import torch
|
||||
import lietorch
|
||||
import cv2
|
||||
import os
|
||||
import glob
|
||||
import time
|
||||
import argparse
|
||||
|
||||
import torch.nn.functional as F
|
||||
from droid import Droid
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
|
||||
def show_image(image):
|
||||
image = image.permute(1, 2, 0).cpu().numpy()
|
||||
cv2.imshow('image', image / 255.0)
|
||||
cv2.waitKey(1)
|
||||
|
||||
def image_stream(datapath, use_depth=False, stride=1):
|
||||
""" image generator """
|
||||
|
||||
fx, fy, cx, cy = np.loadtxt(os.path.join(datapath, 'calibration.txt')).tolist()
|
||||
image_list = sorted(glob.glob(os.path.join(datapath, 'rgb', '*.png')))[::stride]
|
||||
depth_list = sorted(glob.glob(os.path.join(datapath, 'depth', '*.png')))[::stride]
|
||||
|
||||
for t, (image_file, depth_file) in enumerate(zip(image_list, depth_list)):
|
||||
image = cv2.imread(image_file)
|
||||
depth = cv2.imread(depth_file, cv2.IMREAD_ANYDEPTH) / 5000.0
|
||||
|
||||
h0, w0, _ = image.shape
|
||||
h1 = int(h0 * np.sqrt((384 * 512) / (h0 * w0)))
|
||||
w1 = int(w0 * np.sqrt((384 * 512) / (h0 * w0)))
|
||||
|
||||
image = cv2.resize(image, (w1, h1))
|
||||
image = image[:h1-h1%8, :w1-w1%8]
|
||||
image = torch.as_tensor(image).permute(2, 0, 1)
|
||||
|
||||
depth = torch.as_tensor(depth)
|
||||
depth = F.interpolate(depth[None,None], (h1, w1)).squeeze()
|
||||
depth = depth[:h1-h1%8, :w1-w1%8]
|
||||
|
||||
intrinsics = torch.as_tensor([fx, fy, cx, cy])
|
||||
intrinsics[0::2] *= (w1 / w0)
|
||||
intrinsics[1::2] *= (h1 / h0)
|
||||
|
||||
if use_depth:
|
||||
yield t, image[None], depth, intrinsics
|
||||
|
||||
else:
|
||||
yield t, image[None], intrinsics
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--datapath")
|
||||
parser.add_argument("--weights", default="droid.pth")
|
||||
parser.add_argument("--buffer", type=int, default=1024)
|
||||
parser.add_argument("--image_size", default=[240, 320])
|
||||
parser.add_argument("--disable_vis", action="store_true")
|
||||
|
||||
parser.add_argument("--beta", type=float, default=0.5)
|
||||
parser.add_argument("--filter_thresh", type=float, default=2.0)
|
||||
parser.add_argument("--warmup", type=int, default=8)
|
||||
parser.add_argument("--keyframe_thresh", type=float, default=3.5)
|
||||
parser.add_argument("--frontend_thresh", type=float, default=16.0)
|
||||
parser.add_argument("--frontend_window", type=int, default=16)
|
||||
parser.add_argument("--frontend_radius", type=int, default=1)
|
||||
parser.add_argument("--frontend_nms", type=int, default=0)
|
||||
|
||||
parser.add_argument("--stereo", action="store_true")
|
||||
parser.add_argument("--depth", action="store_true")
|
||||
|
||||
parser.add_argument("--backend_thresh", type=float, default=22.0)
|
||||
parser.add_argument("--backend_radius", type=int, default=2)
|
||||
parser.add_argument("--backend_nms", type=int, default=3)
|
||||
args = parser.parse_args()
|
||||
|
||||
torch.multiprocessing.set_start_method('spawn')
|
||||
|
||||
print("Running evaluation on {}".format(args.datapath))
|
||||
print(args)
|
||||
|
||||
# this can usually be set to 2-3 except for "camera_shake" scenes
|
||||
# set to 2 for test scenes
|
||||
stride = 1
|
||||
|
||||
tstamps = []
|
||||
for (t, image, depth, intrinsics) in tqdm(image_stream(args.datapath, use_depth=True, stride=stride)):
|
||||
if not args.disable_vis:
|
||||
show_image(image[0])
|
||||
|
||||
if t == 0:
|
||||
args.image_size = [image.shape[2], image.shape[3]]
|
||||
droid = Droid(args)
|
||||
|
||||
droid.track(t, image, depth, intrinsics=intrinsics)
|
||||
|
||||
traj_est = droid.terminate(image_stream(args.datapath, use_depth=False, stride=stride))
|
||||
|
||||
### run evaluation ###
|
||||
|
||||
print("#"*20 + " Results...")
|
||||
|
||||
import evo
|
||||
from evo.core.trajectory import PoseTrajectory3D
|
||||
from evo.tools import file_interface
|
||||
from evo.core import sync
|
||||
import evo.main_ape as main_ape
|
||||
from evo.core.metrics import PoseRelation
|
||||
|
||||
image_path = os.path.join(args.datapath, 'rgb')
|
||||
images_list = sorted(glob.glob(os.path.join(image_path, '*.png')))[::stride]
|
||||
tstamps = [float(x.split('/')[-1][:-4]) for x in images_list]
|
||||
|
||||
traj_est = PoseTrajectory3D(
|
||||
positions_xyz=traj_est[:,:3],
|
||||
orientations_quat_wxyz=traj_est[:,3:],
|
||||
timestamps=np.array(tstamps))
|
||||
|
||||
gt_file = os.path.join(args.datapath, 'groundtruth.txt')
|
||||
traj_ref = file_interface.read_tum_trajectory_file(gt_file)
|
||||
|
||||
traj_ref, traj_est = sync.associate_trajectories(traj_ref, traj_est)
|
||||
|
||||
result = main_ape.ape(traj_ref, traj_est, est_name='traj',
|
||||
pose_relation=PoseRelation.translation_part, align=True, correct_scale=False)
|
||||
|
||||
print(result.stats)
|
||||
|
||||
+142
@@ -0,0 +1,142 @@
|
||||
import sys
|
||||
sys.path.append('droid_slam')
|
||||
|
||||
from tqdm import tqdm
|
||||
import numpy as np
|
||||
import torch
|
||||
import lietorch
|
||||
import cv2
|
||||
import os
|
||||
import glob
|
||||
import time
|
||||
import argparse
|
||||
|
||||
from torch.multiprocessing import Process
|
||||
from droid import Droid
|
||||
|
||||
import torch.nn.functional as F
|
||||
|
||||
|
||||
|
||||
def show_image(image):
|
||||
image = image.permute(1, 2, 0).cpu().numpy()
|
||||
cv2.imshow('image', image / 255.0)
|
||||
cv2.waitKey(1)
|
||||
|
||||
def image_stream(datapath, image_size=[320, 512], stereo=False, stride=1):
|
||||
""" image generator """
|
||||
|
||||
K_l = np.array([458.654, 0.0, 367.215, 0.0, 457.296, 248.375, 0.0, 0.0, 1.0]).reshape(3,3)
|
||||
d_l = np.array([-0.28340811, 0.07395907, 0.00019359, 1.76187114e-05, 0.0])
|
||||
R_l = np.array([
|
||||
0.999966347530033, -0.001422739138722922, 0.008079580483432283,
|
||||
0.001365741834644127, 0.9999741760894847, 0.007055629199258132,
|
||||
-0.008089410156878961, -0.007044357138835809, 0.9999424675829176
|
||||
]).reshape(3,3)
|
||||
|
||||
P_l = np.array([435.2046959714599, 0, 367.4517211914062, 0, 0, 435.2046959714599, 252.2008514404297, 0, 0, 0, 1, 0]).reshape(3,4)
|
||||
map_l = cv2.initUndistortRectifyMap(K_l, d_l, R_l, P_l[:3,:3], (752, 480), cv2.CV_32F)
|
||||
|
||||
K_r = np.array([457.587, 0.0, 379.999, 0.0, 456.134, 255.238, 0.0, 0.0, 1]).reshape(3,3)
|
||||
d_r = np.array([-0.28368365, 0.07451284, -0.00010473, -3.555907e-05, 0.0]).reshape(5)
|
||||
R_r = np.array([
|
||||
0.9999633526194376, -0.003625811871560086, 0.007755443660172947,
|
||||
0.003680398547259526, 0.9999684752771629, -0.007035845251224894,
|
||||
-0.007729688520722713, 0.007064130529506649, 0.999945173484644
|
||||
]).reshape(3,3)
|
||||
|
||||
P_r = np.array([435.2046959714599, 0, 367.4517211914062, -47.90639384423901, 0, 435.2046959714599, 252.2008514404297, 0, 0, 0, 1, 0]).reshape(3,4)
|
||||
map_r = cv2.initUndistortRectifyMap(K_r, d_r, R_r, P_r[:3,:3], (752, 480), cv2.CV_32F)
|
||||
|
||||
intrinsics_vec = [435.2046959714599, 435.2046959714599, 367.4517211914062, 252.2008514404297]
|
||||
ht0, wd0 = [480, 752]
|
||||
|
||||
# read all png images in folder
|
||||
images_left = sorted(glob.glob(os.path.join(datapath, 'mav0/cam0/data/*.png')))[::stride]
|
||||
images_right = [x.replace('cam0', 'cam1') for x in images_left]
|
||||
|
||||
for t, (imgL, imgR) in enumerate(zip(images_left, images_right)):
|
||||
if stereo and not os.path.isfile(imgR):
|
||||
continue
|
||||
tstamp = float(imgL.split('/')[-1][:-4])
|
||||
images = [cv2.remap(cv2.imread(imgL), map_l[0], map_l[1], interpolation=cv2.INTER_LINEAR)]
|
||||
if stereo:
|
||||
images += [cv2.remap(cv2.imread(imgR), map_r[0], map_r[1], interpolation=cv2.INTER_LINEAR)]
|
||||
|
||||
images = torch.from_numpy(np.stack(images, 0))
|
||||
images = images.permute(0, 3, 1, 2).to("cuda:0", dtype=torch.float32)
|
||||
images = F.interpolate(images, image_size, mode="bilinear", align_corners=False)
|
||||
|
||||
intrinsics = torch.as_tensor(intrinsics_vec).cuda()
|
||||
intrinsics[0] *= image_size[1] / wd0
|
||||
intrinsics[1] *= image_size[0] / ht0
|
||||
intrinsics[2] *= image_size[1] / wd0
|
||||
intrinsics[3] *= image_size[0] / ht0
|
||||
|
||||
yield stride*t, images, intrinsics
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--datapath", help="path to euroc sequence")
|
||||
parser.add_argument("--gt", help="path to gt file")
|
||||
parser.add_argument("--weights", default="droid.pth")
|
||||
parser.add_argument("--buffer", type=int, default=512)
|
||||
parser.add_argument("--image_size", default=[320,512])
|
||||
parser.add_argument("--disable_vis", action="store_true")
|
||||
parser.add_argument("--stereo", action="store_true")
|
||||
|
||||
parser.add_argument("--beta", type=float, default=0.3)
|
||||
parser.add_argument("--filter_thresh", type=float, default=2.4)
|
||||
parser.add_argument("--warmup", type=int, default=15)
|
||||
parser.add_argument("--keyframe_thresh", type=float, default=3.5)
|
||||
parser.add_argument("--frontend_thresh", type=float, default=17.5)
|
||||
parser.add_argument("--frontend_window", type=int, default=20)
|
||||
parser.add_argument("--frontend_radius", type=int, default=2)
|
||||
parser.add_argument("--frontend_nms", type=int, default=1)
|
||||
|
||||
parser.add_argument("--backend_thresh", type=float, default=24.0)
|
||||
parser.add_argument("--backend_radius", type=int, default=2)
|
||||
parser.add_argument("--backend_nms", type=int, default=2)
|
||||
args = parser.parse_args()
|
||||
|
||||
torch.multiprocessing.set_start_method('spawn')
|
||||
|
||||
print("Running evaluation on {}".format(args.datapath))
|
||||
print(args)
|
||||
|
||||
droid = Droid(args)
|
||||
time.sleep(5)
|
||||
|
||||
for (t, image, intrinsics) in tqdm(image_stream(args.datapath, stereo=args.stereo, stride=2)):
|
||||
droid.track(t, image, intrinsics=intrinsics)
|
||||
|
||||
traj_est = droid.terminate(image_stream(args.datapath, stride=1))
|
||||
|
||||
### run evaluation ###
|
||||
|
||||
import evo
|
||||
from evo.core.trajectory import PoseTrajectory3D
|
||||
from evo.tools import file_interface
|
||||
from evo.core import sync
|
||||
import evo.main_ape as main_ape
|
||||
from evo.core.metrics import PoseRelation
|
||||
|
||||
images_list = sorted(glob.glob(os.path.join(args.datapath, 'mav0/cam0/data/*.png')))
|
||||
tstamps = [float(x.split('/')[-1][:-4]) for x in images_list]
|
||||
|
||||
traj_est = PoseTrajectory3D(
|
||||
positions_xyz=1.10 * traj_est[:,:3],
|
||||
orientations_quat_wxyz=traj_est[:,3:],
|
||||
timestamps=np.array(tstamps))
|
||||
|
||||
traj_ref = file_interface.read_tum_trajectory_file(args.gt)
|
||||
|
||||
traj_ref, traj_est = sync.associate_trajectories(traj_ref, traj_est)
|
||||
|
||||
result = main_ape.ape(traj_ref, traj_est, est_name='traj',
|
||||
pose_relation=PoseRelation.translation_part, align=True, correct_scale=True)
|
||||
|
||||
print(result)
|
||||
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
import sys
|
||||
sys.path.append('droid_slam')
|
||||
|
||||
from tqdm import tqdm
|
||||
import numpy as np
|
||||
import torch
|
||||
import lietorch
|
||||
import cv2
|
||||
import os
|
||||
import glob
|
||||
import time
|
||||
import argparse
|
||||
|
||||
import torch.nn.functional as F
|
||||
from droid import Droid
|
||||
|
||||
|
||||
def show_image(image):
|
||||
image = image.permute(1, 2, 0).cpu().numpy()
|
||||
cv2.imshow('image', image / 255.0)
|
||||
cv2.waitKey(1)
|
||||
|
||||
def image_stream(datapath, image_size=[320, 512]):
|
||||
""" image generator """
|
||||
|
||||
fx, fy, cx, cy = 517.3, 516.5, 318.6, 255.3
|
||||
|
||||
K_l = np.array([fx, 0.0, cx, 0.0, fy, cy, 0.0, 0.0, 1.0]).reshape(3,3)
|
||||
d_l = np.array([0.2624, -0.9531, -0.0054, 0.0026, 1.1633])
|
||||
|
||||
# read all png images in folder
|
||||
images_list = sorted(glob.glob(os.path.join(datapath, 'rgb', '*.png')))[::2]
|
||||
|
||||
for t, imfile in enumerate(images_list):
|
||||
image = cv2.imread(imfile)
|
||||
ht0, wd0, _ = image.shape
|
||||
image = cv2.undistort(image, K_l, d_l)
|
||||
image = cv2.resize(image, (320+32, 240+16))
|
||||
image = torch.from_numpy(image).permute(2,0,1)
|
||||
|
||||
intrinsics = torch.as_tensor([fx, fy, cx, cy]).cuda()
|
||||
intrinsics[0] *= image.shape[2] / 640.0
|
||||
intrinsics[1] *= image.shape[1] / 480.0
|
||||
intrinsics[2] *= image.shape[2] / 640.0
|
||||
intrinsics[3] *= image.shape[1] / 480.0
|
||||
|
||||
# crop image to remove distortion boundary
|
||||
intrinsics[2] -= 16
|
||||
intrinsics[3] -= 8
|
||||
image = image[:, 8:-8, 16:-16]
|
||||
|
||||
yield t, image[None], intrinsics
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--datapath")
|
||||
parser.add_argument("--weights", default="droid.pth")
|
||||
parser.add_argument("--buffer", type=int, default=512)
|
||||
parser.add_argument("--image_size", default=[240, 320])
|
||||
parser.add_argument("--disable_vis", action="store_true")
|
||||
|
||||
parser.add_argument("--beta", type=float, default=0.6)
|
||||
parser.add_argument("--filter_thresh", type=float, default=1.75)
|
||||
parser.add_argument("--warmup", type=int, default=12)
|
||||
parser.add_argument("--keyframe_thresh", type=float, default=2.25)
|
||||
parser.add_argument("--frontend_thresh", type=float, default=12.0)
|
||||
parser.add_argument("--frontend_window", type=int, default=25)
|
||||
parser.add_argument("--frontend_radius", type=int, default=2)
|
||||
parser.add_argument("--frontend_nms", type=int, default=1)
|
||||
|
||||
parser.add_argument("--backend_thresh", type=float, default=15.0)
|
||||
parser.add_argument("--backend_radius", type=int, default=2)
|
||||
parser.add_argument("--backend_nms", type=int, default=3)
|
||||
args = parser.parse_args()
|
||||
|
||||
args.stereo = False
|
||||
torch.multiprocessing.set_start_method('spawn')
|
||||
|
||||
print("Running evaluation on {}".format(args.datapath))
|
||||
print(args)
|
||||
|
||||
droid = Droid(args)
|
||||
time.sleep(5)
|
||||
|
||||
tstamps = []
|
||||
for (t, image, intrinsics) in tqdm(image_stream(args.datapath)):
|
||||
if not args.disable_vis:
|
||||
show_image(image)
|
||||
droid.track(t, image, intrinsics=intrinsics)
|
||||
|
||||
|
||||
traj_est = droid.terminate(image_stream(args.datapath))
|
||||
|
||||
### run evaluation ###
|
||||
|
||||
print("#"*20 + " Results...")
|
||||
|
||||
import evo
|
||||
from evo.core.trajectory import PoseTrajectory3D
|
||||
from evo.tools import file_interface
|
||||
from evo.core import sync
|
||||
import evo.main_ape as main_ape
|
||||
from evo.core.metrics import PoseRelation
|
||||
|
||||
image_path = os.path.join(args.datapath, 'rgb')
|
||||
images_list = sorted(glob.glob(os.path.join(image_path, '*.png')))[::2]
|
||||
tstamps = [float(x.split('/')[-1][:-4]) for x in images_list]
|
||||
|
||||
traj_est = PoseTrajectory3D(
|
||||
positions_xyz=traj_est[:,:3],
|
||||
orientations_quat_wxyz=traj_est[:,3:],
|
||||
timestamps=np.array(tstamps))
|
||||
|
||||
gt_file = os.path.join(args.datapath, 'groundtruth.txt')
|
||||
traj_ref = file_interface.read_tum_trajectory_file(gt_file)
|
||||
|
||||
traj_ref, traj_est = sync.associate_trajectories(traj_ref, traj_est)
|
||||
result = main_ape.ape(traj_ref, traj_est, est_name='traj',
|
||||
pose_relation=PoseRelation.translation_part, align=True, correct_scale=True)
|
||||
|
||||
|
||||
print(result)
|
||||
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
import sys
|
||||
sys.path.append('droid_slam')
|
||||
sys.path.append('thirdparty/tartanair_tools')
|
||||
|
||||
from tqdm import tqdm
|
||||
import numpy as np
|
||||
import torch
|
||||
import lietorch
|
||||
import cv2
|
||||
import os
|
||||
import glob
|
||||
import time
|
||||
import yaml
|
||||
import argparse
|
||||
|
||||
from droid import Droid
|
||||
|
||||
def image_stream(datapath, image_size=[384, 512], intrinsics_vec=[320.0, 320.0, 320.0, 240.0], stereo=False):
|
||||
""" image generator """
|
||||
|
||||
# read all png images in folder
|
||||
ht0, wd0 = [480, 640]
|
||||
images_left = sorted(glob.glob(os.path.join(datapath, 'image_left/*.png')))
|
||||
images_right = sorted(glob.glob(os.path.join(datapath, 'image_right/*.png')))
|
||||
|
||||
data = []
|
||||
for t in range(len(images_left)):
|
||||
images = [ cv2.resize(cv2.imread(images_left[t]), (image_size[1], image_size[0])) ]
|
||||
if stereo:
|
||||
images += [ cv2.resize(cv2.imread(images_right[t]), (image_size[1], image_size[0])) ]
|
||||
|
||||
images = torch.from_numpy(np.stack(images, 0)).permute(0,3,1,2)
|
||||
intrinsics = .8 * torch.as_tensor(intrinsics_vec)
|
||||
|
||||
data.append((t, images, intrinsics))
|
||||
|
||||
return data
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--datapath", default="datasets/TartanAir")
|
||||
parser.add_argument("--weights", default="droid.pth")
|
||||
parser.add_argument("--buffer", type=int, default=1000)
|
||||
parser.add_argument("--image_size", default=[384,512])
|
||||
parser.add_argument("--stereo", action="store_true")
|
||||
parser.add_argument("--disable_vis", action="store_true")
|
||||
parser.add_argument("--plot_curve", action="store_true")
|
||||
parser.add_argument("--id", type=int, default=-1)
|
||||
|
||||
parser.add_argument("--beta", type=float, default=0.3)
|
||||
parser.add_argument("--filter_thresh", type=float, default=2.4)
|
||||
parser.add_argument("--warmup", type=int, default=12)
|
||||
parser.add_argument("--keyframe_thresh", type=float, default=3.5)
|
||||
parser.add_argument("--frontend_thresh", type=float, default=15)
|
||||
parser.add_argument("--frontend_window", type=int, default=20)
|
||||
parser.add_argument("--frontend_radius", type=int, default=1)
|
||||
parser.add_argument("--frontend_nms", type=int, default=1)
|
||||
|
||||
parser.add_argument("--backend_thresh", type=float, default=20.0)
|
||||
parser.add_argument("--backend_radius", type=int, default=2)
|
||||
parser.add_argument("--backend_nms", type=int, default=3)
|
||||
|
||||
args = parser.parse_args()
|
||||
torch.multiprocessing.set_start_method('spawn')
|
||||
|
||||
from data_readers.tartan import test_split
|
||||
from evaluation.tartanair_evaluator import TartanAirEvaluator
|
||||
|
||||
if not os.path.isdir("figures"):
|
||||
os.mkdir("figures")
|
||||
|
||||
if args.id >= 0:
|
||||
test_split = [ test_split[args.id] ]
|
||||
|
||||
ate_list = []
|
||||
for scene in test_split:
|
||||
print("Performing evaluation on {}".format(scene))
|
||||
torch.cuda.empty_cache()
|
||||
droid = Droid(args)
|
||||
|
||||
scenedir = os.path.join(args.datapath, scene)
|
||||
|
||||
for (tstamp, image, intrinsics) in tqdm(image_stream(scenedir, stereo=args.stereo)):
|
||||
droid.track(tstamp, image, intrinsics=intrinsics)
|
||||
|
||||
# fill in non-keyframe poses + global BA
|
||||
traj_est = droid.terminate(image_stream(scenedir))
|
||||
|
||||
### do evaluation ###
|
||||
evaluator = TartanAirEvaluator()
|
||||
gt_file = os.path.join(scenedir, "pose_left.txt")
|
||||
traj_ref = np.loadtxt(gt_file, delimiter=' ')[:, [1, 2, 0, 4, 5, 3, 6]] # ned -> xyz
|
||||
|
||||
# usually stereo should not be scale corrected, but we are comparing monocular and stereo here
|
||||
results = evaluator.evaluate_one_trajectory(
|
||||
traj_ref, traj_est, scale=True, title=scenedir[-20:].replace('/', '_'))
|
||||
|
||||
print(results)
|
||||
ate_list.append(results["ate_score"])
|
||||
|
||||
print("Results")
|
||||
print(ate_list)
|
||||
|
||||
if args.plot_curve:
|
||||
import matplotlib.pyplot as plt
|
||||
ate = np.array(ate_list)
|
||||
xs = np.linspace(0.0, 1.0, 512)
|
||||
ys = [np.count_nonzero(ate < t) / ate.shape[0] for t in xs]
|
||||
|
||||
plt.plot(xs, ys)
|
||||
plt.xlabel("ATE [m]")
|
||||
plt.ylabel("% runs")
|
||||
plt.show()
|
||||
|
||||
Reference in New Issue
Block a user