-
Notifications
You must be signed in to change notification settings - Fork 32
/
Copy patheval_utils.py
145 lines (129 loc) · 5.9 KB
/
eval_utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# Jadie Adams
import os
import re
import shutil
import subprocess
import numpy as np
import shapeworks as sw
def get_distance_meshes(out_dir, DT_dir, prediction_dir, mean_prefix):
# Step 1: Get list of test names
test_names = []
for file in os.listdir(prediction_dir):
test_names.append(get_prefix(file))
# Step 2: Get original meshes from test distance transforms
print("\n\nGetting original meshes from distance transforms...")
DT_files = []
for file in os.listdir(DT_dir):
prefix = get_prefix(file)
if prefix in test_names:
DT_files.append(DT_dir + '/' + file)
orig_mesh_list = sorted(get_mesh_from_DT(DT_files, out_dir + "OriginalMeshes/"))
# Step 3: Get predicted meshes from predicted particles
print("\n\nGetting meshes from predicted particles...")
particle_files = []
for file in os.listdir(prediction_dir):
particle_files.append(prediction_dir + file)
template_mesh = mean_prefix + "_dense.vtk"
template_points = mean_prefix + "_sparse.particles"
pred_mesh_list = sorted(
get_mesh_from_particles(particle_files, out_dir + "PredictedMeshes/", template_points, template_mesh))
# Step 4: Get distance between original and predicted mesh
print("\n\nGetting distance between original and predicted meshes...")
orig_dist_mesh_list, pred_dist_mesh_list, avg_distance = surface_to_surface_distance(orig_mesh_list, pred_mesh_list,
out_dir)
print("Done.\n")
return avg_distance
def get_prefix(path):
file_name = os.path.basename(path)
file_name = file_name.replace("predicted_ft_", "")
prefix = "_".join(file_name.split("_")[0:2])
prefix = prefix.split(".")[0]
return prefix
def get_mesh_from_DT(DT_list, mesh_dir):
if not os.path.exists(mesh_dir):
os.makedirs(mesh_dir)
mesh_files = []
xml_filename = mesh_dir + "temp.xml"
for input_file in DT_list:
print(' ' + get_prefix(input_file))
output_vtk = mesh_dir + "original_" + get_prefix(input_file) + ".vtk"
image = sw.Image(input_file)
image.toMesh(isovalue=0).write(output_vtk)
mesh_files.append(output_vtk)
return sorted(mesh_files)
def get_mesh_from_particles(particle_list, mesh_dir, template_particles, template_mesh, planes=None):
num_particles = np.loadtxt(particle_list[0]).shape[0]
particle_dir = os.path.dirname(particle_list[0]) + '/'
execCommand = ["shapeworks",
"warp-mesh", "--reference_mesh", template_mesh,
"--reference_points", template_particles,
"--target_points"]
for fl in particle_list:
execCommand.append(fl)
execCommand.append('--')
print(f"Running: {' '.join(execCommand)}")
subprocess.check_call(execCommand)
if not os.path.exists(mesh_dir):
os.makedirs(mesh_dir)
outmeshes = []
for i in range(len(particle_list)):
infnm = particle_list[i].replace('.particles', '.vtk')
outfnm = infnm.replace(particle_dir, mesh_dir)
outmeshes.append(outfnm)
shutil.move(infnm, outfnm)
if planes is not None:
for index in range(len(outmeshes)):
sw.Mesh(outmeshes[index]).clip(planes[index][0], planes[index][1], planes[index][2]).write(outmeshes[index])
return sorted(outmeshes)
def surface_to_surface_distance(orig_list, pred_list, out_dir):
orig_out_dir = out_dir + "OriginalMeshesWithDistance/"
if not os.path.exists(orig_out_dir):
os.makedirs(orig_out_dir)
pred_out_dir = out_dir + "PredictedMeshesWithDistance/"
if not os.path.exists(pred_out_dir):
os.makedirs(pred_out_dir)
orig_out_list = []
pred_out_list = []
mean_distances = []
for index in range(len(orig_list)):
orig = orig_list[index]
pred = pred_list[index]
name = os.path.basename(orig).replace("original_", "")
orig_out = orig_out_dir + name
pred_out = pred_out_dir + name
orig_out_list.append(orig_out)
pred_out_list.append(pred_out)
orig_mesh = sw.Mesh(orig)
pred_mesh = sw.Mesh(pred)
dist1 = sw.mean(orig_mesh.distance(pred_mesh).write(orig_out).getField("distance", Mesh.Point))
dist2 = sw.mean(pred_mesh.distance(orig_mesh).write(pred_out).getField("distance", Mesh.Point))
mean_distances.append(dist1)
mean_distances.append(dist2)
return orig_out_list, pred_out_list, np.mean(np.array(mean_distances))
def get_MSE(pred_particle_files, true_particle_files):
MSEs = []
for i in range(len(pred_particle_files)):
pred_particles = np.loadtxt(pred_particle_files[i])
true_particles = np.loadtxt(true_particle_files[i])
MSEs.append(np.mean((pred_particles - true_particles) ** 2))
MSEs = np.array(MSEs)
return np.mean(MSEs), np.std(MSEs)
def get_mesh_distance(pred_particle_files, mesh_list, template_particles, template_mesh, out_dir, planes=None):
# Step 1: Get predicted meshes from predicted particles
print("Getting meshes from predicted local particles...")
pred_mesh_list = sorted(
get_mesh_from_particles(pred_particle_files, out_dir + "/predicted_meshes/", template_particles, template_mesh,
planes))
print(f"pred_mesh_list: {pred_mesh_list}")
# Step 2: Get distance between original and predicted mesh
mean_distances = []
for index in range(len(mesh_list)):
orig_mesh = sw.Mesh(mesh_list[index])
if planes is not None:
orig_mesh.clip(planes[index][0], planes[index][1], planes[index][2])
pred_mesh = sw.Mesh(pred_mesh_list[index])
orig_mesh.write("/tmp/orig_mesh.vtk")
pred_mesh.write("/tmp/pred_mesh.vtk")
mean_distances.append(np.mean(orig_mesh.distance(pred_mesh)[0]))
mean_distances.append(np.mean(pred_mesh.distance(orig_mesh)[0]))
return np.mean(np.array(mean_distances))