-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathevaluate_normal.py
executable file
·116 lines (94 loc) · 3.97 KB
/
evaluate_normal.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
## functions for evaluating normals
## Zhenheng Yang 06/27/2017
import numpy as np
import scipy.misc as sm
import argparse
from evaluation_utils import *
import os
import math
import time
import numpy.linalg as nla
import skimage.transform as st
def load_normals(pred_normals, split, gt_path, test_fn):
## pred normals can be a npy file containing all predicted normals
## or it can be a path containing normal images
## load gt_normals
if split in ["kitti", "eigen"]:
gt_normals = []
gt_files = os.listdir(gt_path)
gt_files.sort()
for file in gt_files:
if file[0] == ".": continue
gt_normals.append(transform(sm.imread(gt_path + file)))
if split == "cs":
num_samples = 500
gt_normals = [[] for i in range(num_samples)]
if split == "nyuv2":
gt_normals = []
with open(test_fn) as f:
for line in f:
gt_normal = sm.imread(gt_path + "normals/" + line.rstrip().split("/")[-1])
gt_mask = np.tile(np.expand_dims(sm.imread(gt_path + "masks/" + line.rstrip().split("/")[-1]), -1), (1,1,3))
gt_normals.append(transform(gt_normal * gt_mask))
pred_normals, gt_normals = np.array(pred_normals, dtype=np.float32), np.array(gt_normals, dtype=np.float32)
return pred_normals, gt_normals
def transform(normal_img):
return (normal_img / 255.0 * 2.0 -1.0)
def normalize_norm(normal_maps, axis):
## l2 normalize normal vector
import numpy.linalg as nla
norms = nla.norm(normal_maps, axis=axis)
for i in range(normal_maps.shape[axis]):
normal_maps[:,:,:,i] /= norms
return normal_maps
def eval_normal(pred_normals, gt_normals, split):
## normal evaluation core function
## input are two numpy arrays with same shape [batch, width, height, 3]
epsilon = 1e-5
degrees = []
for i in range(len(pred_normals)):
pred_normal = pred_normals[i]
if split != "cs":
gt_normal = gt_normals[i]
gt_normal_normed = gt_normal
pred_normal = np.clip(pred_normal, -1.0, 1.0)
pred_normal = st.resize(pred_normal, gt_normal.shape)
pred_normal_normed = pred_normal
masks = (gt_normal > -0.95)
mask = masks[:,:,0] | masks[:,:,1] | masks[:,:,2]
pred_normal_norm, gt_normal_norm = nla.norm(pred_normal, axis=2), nla.norm(gt_normal, axis=2)
for j in range(pred_normal.shape[-1]):
pred_normal_normed[:,:,j] /= (pred_normal_norm + 1e-6)
gt_normal_normed[:,:,j] /= (gt_normal_norm + 1e-6)
in_prod = np.sum(pred_normal_normed * gt_normal_normed, axis=-1)
degree_map = np.arccos(in_prod) / math.pi
else:
continue
degree = np.arccos(in_prod[mask])*180.0/math.pi
degrees += list(degree)
if split == "cs": return
degrees = np.array(degrees)
print ("{:>10}, {:>10}, {:>10}, {:>10}, {:>10}".format('mean', 'median', '11.25', '22.5', '30'))
print("{:10.4f}, {:10.4f}, {:10.3f}, {:10.3f}, {:10.3f}".format(np.mean(degrees), np.median(degrees), \
np.mean(degrees < 11.25), np.mean(degrees < 22.5), np.mean(degrees < 30)))
return np.mean(degrees), np.median(degrees), np.mean(degrees < 11.25), np.mean(degrees < 22.5), np.mean(degrees < 30)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Normal Evaluation')
parser.add_argument('--split', type=str, help='data split, kitti or eigen', default="kitti")
parser.add_argument('--pred_normals_path', type=str, help='path to estimated normals', required=True)
parser.add_argument('--gt_path', type=str, help='path to ground truth normals', required=True)
args = parser.parse_args()
split, pred_normals_path, gt_path = args.split, args.pred_normals_path, args.gt_path
start_time = time.time()
if pred_normals_path.split(".")[-1] == "npy":
pred_normals = np.load(pred_normals_path)
else:
pred_normals = []
pred_files = os.listdir(pred_normals_path)
pred_files.sort()
for file in pred_files:
if file[0] == ".": continue
pred_normals.append(transform(sm.imread(pred_normals_path + file)))
pred_normals, gt_normals = load_normals(pred_normals, split, gt_path, test_fn = "")
print (time.time() - start_time)
eval_normal(pred_normals, gt_normals)