-
Notifications
You must be signed in to change notification settings - Fork 34
/
test_PC.py
210 lines (161 loc) · 6.47 KB
/
test_PC.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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
from __future__ import print_function
from __future__ import division
import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np
print("PyTorch Version: ",torch.__version__)
import pickle
import os
import scipy.io as sio
from model import *
from pano import get_ini_cor
from pano_opt import optimize_cor_id
from utils_eval import eval_PE, eval_3diou
# Top level data directory. Here we assume the format of the directory conforms
# to the ImageFolder structure
test_path = './data/test_PC/'
weight_path = './model/resnet34_PC.pth'
save_path = './result/'
# Pre-trained models to choose from [resnet18, resnet34, resnet50]
#model_name = "resnet18"
model_name = "resnet34"
#model_name = "resnet50"
num_classes = 1024
print("Load Models...")
# Define the encoder
encoder = initialize_encoder(model_name, num_classes,use_pretrained=True)
# Full model
model_ft = SegNet(encoder, num_classes)
model_ft.load_state_dict(torch.load(weight_path))
# Detect if we have a GPU available
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
# Send the model to GPU
model_ft = model_ft.to(device)
# evaluation mode
model_ft.eval()
# Load data
gt_txt_path = './gt/panoContext_test.txt'
namelist = []
with open(gt_txt_path, 'r') as f:
while(True):
line = f.readline().strip()
if not line:
break
namelist.append(line)
criterion = nn.BCELoss()
criterion2 = nn.BCELoss()
cnt = 0
num = 0
loss_cor = 0.0
loss_pe = 0.0
loss_3d = 0.0
loss_sum = 0.0
for file_list in namelist:
#file_list = np.random.choice(namelist, 1)
#file_list = file_list[0]
#print(file_list)
pkl_path = test_path+'PCts_'+ "{:04d}".format(cnt) + '.pkl'
pkl = pickle.load(open(pkl_path, 'rb'))
img = pkl['image'].astype('float32')
label = pkl['edge'].astype('float32')
label2 = pkl['junc'].astype('float32')
mask = pkl['line'].astype('float32')
# lr flip
img2 = np.fliplr(img).copy()
mask2 = np.fliplr(mask).copy()
image = torch.tensor(img).to(device).float()
labels = torch.tensor(label).to(device).float()
labels2 = torch.tensor(label2).to(device).float()
masks = torch.tensor(mask).to(device).float()
inputs = image.permute(2,0,1)
inputs = inputs.unsqueeze(0)
masks = masks.permute(2,0,1)
masks = masks.unsqueeze(0)
inputs = torch.cat((inputs,masks),1)
labels = labels.permute(2,0,1)
labels = labels.unsqueeze(0)
labels2 = labels2.permute(2,0,1)
labels2 = labels2.unsqueeze(0)
image2 = torch.tensor(img2).to(device).float()
masks2 = torch.tensor(mask2).to(device).float()
inputs2 = image2.permute(2,0,1)
inputs2 = inputs2.unsqueeze(0)
masks2 = masks2.permute(2,0,1)
masks2 = masks2.unsqueeze(0)
inputs2 = torch.cat((inputs2,masks2),1)
inputs = torch.cat((inputs, inputs2),0)
outputs, outputs2 = model_ft(inputs)
# lr flip and take mean
outputs1 = outputs[1]
outputs22 = outputs2[1]
inv_idx = torch.arange(outputs1.size(2)-1, -1, -1).to(device).long()
outputs1 = outputs1.index_select(2, inv_idx)
outputs = torch.mean(torch.cat((outputs[0].unsqueeze(0), outputs1.unsqueeze(0)), 0), 0, True)
outputs22 = outputs22.index_select(2, inv_idx)
outputs2 = torch.mean(torch.cat((outputs2[0].unsqueeze(0), outputs22.unsqueeze(0)), 0), 0, True)
loss = criterion(outputs, labels) + criterion(outputs2, labels2)
loss_sum += loss.data.cpu().numpy()
labels = labels.squeeze(0).permute(1,2,0)
outputs = outputs.squeeze(0).permute(1,2,0)
labels2 = labels2.squeeze(0).squeeze(0)
outputs2 = outputs2.squeeze(0).squeeze(0)
inputs = inputs[0].permute(1,2,0)
#gradient ascent refinement
cor_img = outputs2.data.cpu().numpy()
edg_img = outputs.data.cpu().numpy()
# load gt
path = os.path.join('./data/layoutnet_dataset/test', 'label_cor', '%s.txt' % file_list[:-4])
with open(path) as f:
gt = np.array([line.strip().split() for line in f], np.float64)
# sort gt, since it's box shape
gt_id = np.argsort(gt[:,0])
gt = gt[gt_id,:]
for row in range(0,gt.shape[0],2):
gt_id = np.argsort(gt[row:row+2,1])
gt[row:row+2,:] = gt[row:row+2,gt_id]
# initial corners
cor_id = get_ini_cor(cor_img, 21, 3)
# refinement
cor_id = optimize_cor_id(cor_id, edg_img, cor_img, num_iters=100, verbose=False)
# sort cor_id, since it's box
cor_idd = np.argsort(cor_id[:,0])
cor_id = cor_id[cor_idd,:]
for row in range(0,cor_id.shape[0],2):
cor_idd = np.argsort(cor_id[row:row+2,1])
cor_id[row:row+2,:] = cor_id[row:row+2,cor_idd]
cor_error = ((gt - cor_id) ** 2).sum(1) ** 0.5
cor_error /= np.sqrt(cor_img.shape[0] ** 2 + cor_img.shape[1] ** 2)
cor_error = cor_error.mean()
# rotate variations
cor_id2 = np.concatenate((cor_id[2:,:], cor_id[:2,:]), axis=0)
cor_id2[6:,0] = 1024+cor_id2[6:,0]
cor_error2 = ((gt - cor_id2) ** 2).sum(1) ** 0.5
cor_error2 /= np.sqrt(cor_img.shape[0] ** 2 + cor_img.shape[1] ** 2)
cor_error2 = cor_error2.mean()
cor_id3 = np.concatenate((cor_id[6:,:], cor_id[:6,:]), axis=0)
cor_id3[:2,0] = cor_id3[:2,0]-1024
cor_error3 = ((gt - cor_id3) ** 2).sum(1) ** 0.5
cor_error3 /= np.sqrt(cor_img.shape[0] ** 2 + cor_img.shape[1] ** 2)
cor_error3 = cor_error3.mean()
if cor_error2 <= cor_error and cor_error <= cor_error3:
cor_error = cor_error2
if cor_error3 <= cor_error and cor_error <= cor_error2:
cor_error = cor_error3
# pixel error
pe_error, surface, surface_gt = eval_PE(cor_id[0::2], cor_id[1::2], gt[0::2], gt[1::2])
# 3D IoU
iou3d = eval_3diou(cor_id[1::2], cor_id[0::2], gt[1::2], gt[0::2])
loss_cor += cor_error
loss_pe += pe_error
loss_3d += iou3d
# save
print(save_path+file_list[:-3]+'mat')
#sio.savemat(save_path+file_list[:-3]+'mat',{'image':inputs.data.cpu().numpy(), 'pred2':cor_img, 'pred':edg_img, 'cor_id':cor_id})
# sio.savemat(save_path+'PCts_'+ "{:04d}".format(cnt)+'.mat',{'image':inputs.data.cpu().numpy(), 'pred2':cor_img, 'pred':edg_img, 'cor_id':cor_id})
torch.cuda.empty_cache()
del outputs1, outputs, outputs2, outputs22, labels, labels2, inputs, inputs2, loss
cnt += 1
num += 1
print('No. {}, cor Loss: {:.6f}, pc Loss: {:.6f}, 3d Loss: {:.6f}'.format(cnt,loss_cor/cnt,loss_pe/cnt,loss_3d/cnt))
print('Total No. {}, cor Loss: {:.6f}, pc Loss: {:.6f}, 3d Loss: {:.6f}'.format(cnt,loss_cor/cnt, loss_pe/cnt, loss_3d/cnt))