Spaces:
Running
on
Zero
Running
on
Zero
| # This file is derived from [Atlas](https://github.com/magicleap/Atlas). | |
| # Originating Author: Zak Murez (zak.murez.com) | |
| # Modified for [NeuralRecon](https://github.com/zju3dv/NeuralRecon) by Yiming Xie. | |
| # Original header: | |
| # Copyright 2020 Magic Leap, Inc. | |
| # Licensed under the Apache License, Version 2.0 (the "License"); | |
| # you may not use this file except in compliance with the License. | |
| # You may obtain a copy of the License at | |
| # http://www.apache.org/licenses/LICENSE-2.0 | |
| # Unless required by applicable law or agreed to in writing, software | |
| # distributed under the License is distributed on an "AS IS" BASIS, | |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| # See the License for the specific language governing permissions and | |
| # limitations under the License. | |
| import open3d as o3d | |
| import numpy as np | |
| def eval_mesh(mesh_pred, mesh_trgt, threshold=.05, down_sample=.02): | |
| """ Compute Mesh metrics between prediction and target. | |
| Opens the Meshs and runs the metrics | |
| Args: | |
| file_pred: file path of prediction | |
| file_trgt: file path of target | |
| threshold: distance threshold used to compute precision/recal | |
| down_sample: use voxel_downsample to uniformly sample mesh points | |
| Returns: | |
| Dict of mesh metrics | |
| """ | |
| # pcd_pred = o3d.io.read_point_cloud(file_pred) | |
| # pcd_trgt = o3d.io.read_point_cloud(file_trgt) | |
| pcd_pred = o3d.geometry.PointCloud() | |
| pcd_pred.points = o3d.utility.Vector3dVector(mesh_pred.sample(100000).astype(np.float32)) | |
| pcd_trgt = o3d.geometry.PointCloud() | |
| pcd_trgt.points = o3d.utility.Vector3dVector(mesh_trgt.sample(100000).astype(np.float32)) | |
| if down_sample: | |
| pcd_pred = pcd_pred.voxel_down_sample(down_sample) | |
| pcd_trgt = pcd_trgt.voxel_down_sample(down_sample) | |
| verts_pred = np.asarray(pcd_pred.points) | |
| verts_trgt = np.asarray(pcd_trgt.points) | |
| _, dist1 = nn_correspondance(verts_pred, verts_trgt) | |
| _, dist2 = nn_correspondance(verts_trgt, verts_pred) | |
| dist1 = np.array(dist1) | |
| dist2 = np.array(dist2) | |
| precision = np.mean((dist2 < threshold).astype('float')) | |
| recal = np.mean((dist1 < threshold).astype('float')) | |
| fscore = 2 * precision * recal / (precision + recal) | |
| metrics = {'dist1': np.mean(dist2), | |
| 'dist2': np.mean(dist1), | |
| 'prec': precision, | |
| 'recal': recal, | |
| 'fscore': fscore, | |
| } | |
| return metrics | |
| def nn_correspondance(verts1, verts2): | |
| """ for each vertex in verts2 find the nearest vertex in verts1 | |
| Args: | |
| nx3 np.array's | |
| Returns: | |
| ([indices], [distances]) | |
| """ | |
| indices = [] | |
| distances = [] | |
| if len(verts1) == 0 or len(verts2) == 0: | |
| return indices, distances | |
| pcd = o3d.geometry.PointCloud() | |
| pcd.points = o3d.utility.Vector3dVector(verts1) | |
| kdtree = o3d.geometry.KDTreeFlann(pcd) | |
| for vert in verts2: | |
| _, inds, dist = kdtree.search_knn_vector_3d(vert, 1) | |
| indices.append(inds[0]) | |
| distances.append(np.sqrt(dist[0])) | |
| return indices, distances | |
| def eval_depth(depth_pred, depth_trgt): | |
| """ Computes 2d metrics between two depth maps | |
| Args: | |
| depth_pred: mxn np.array containing prediction | |
| depth_trgt: mxn np.array containing ground truth | |
| Returns: | |
| Dict of metrics | |
| """ | |
| mask1 = depth_pred > 0 # ignore values where prediction is 0 (% complete) | |
| mask = (depth_trgt < 10) * (depth_trgt > 0) * mask1 | |
| depth_pred = depth_pred[mask] | |
| depth_trgt = depth_trgt[mask] | |
| abs_diff = np.abs(depth_pred - depth_trgt) | |
| abs_rel = abs_diff / depth_trgt | |
| sq_diff = abs_diff ** 2 | |
| sq_rel = sq_diff / depth_trgt | |
| sq_log_diff = (np.log(depth_pred) - np.log(depth_trgt)) ** 2 | |
| thresh = np.maximum((depth_trgt / depth_pred), (depth_pred / depth_trgt)) | |
| r1 = (thresh < 1.25).astype('float') | |
| r2 = (thresh < 1.25 ** 2).astype('float') | |
| r3 = (thresh < 1.25 ** 3).astype('float') | |
| metrics = {} | |
| metrics['AbsRel'] = np.mean(abs_rel) | |
| metrics['AbsDiff'] = np.mean(abs_diff) | |
| metrics['SqRel'] = np.mean(sq_rel) | |
| metrics['RMSE'] = np.sqrt(np.mean(sq_diff)) | |
| metrics['LogRMSE'] = np.sqrt(np.mean(sq_log_diff)) | |
| metrics['r1'] = np.mean(r1) | |
| metrics['r2'] = np.mean(r2) | |
| metrics['r3'] = np.mean(r3) | |
| metrics['complete'] = np.mean(mask1.astype('float')) | |
| return metrics | |