-
Notifications
You must be signed in to change notification settings - Fork 244
/
predict.py
161 lines (139 loc) · 4.84 KB
/
predict.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
#encoding:utf-8
#
#created by xiongzihua
#
import torch
from torch.autograd import Variable
import torch.nn as nn
from net import vgg16
import torchvision.transforms as transforms
import cv2
import numpy as np
VOC_CLASSES = ( # always index 0
'aeroplane', 'bicycle', 'bird', 'boat',
'bottle', 'bus', 'car', 'cat', 'chair',
'cow', 'diningtable', 'dog', 'horse',
'motorbike', 'person', 'pottedplant',
'sheep', 'sofa', 'train', 'tvmonitor')
def decoder(pred):
'''
pred (tensor) 1x7x7x30
return (tensor) box[[x1,y1,x2,y2]] label[...]
'''
boxes=[]
cls_indexs=[]
probs = []
cell_size = 1./7
pred = pred.data
pred = pred.squeeze(0) #7x7x30
contain1 = pred[:,:,4].unsqueeze(2)
contain2 = pred[:,:,9].unsqueeze(2)
contain = torch.cat((contain1,contain2),2)
mask1 = contain > 0.9 #大于阈值
mask2 = (contain==contain.max()) #we always select the best contain_prob what ever it>0.9
mask = (mask1+mask2).gt(0)
min_score,min_index = torch.min(mask,2) #每个cell只选最大概率的那个预测框
for i in range(7):
for j in range(7):
for b in range(2):
index = min_index[i,j]
mask[i,j,index] = 0
if mask[i,j,b] == 1:
#print(i,j,b)
box = pred[i,j,b*5:b*5+4]
contain_prob = torch.FloatTensor([pred[i,j,b*5+4]])
xy = torch.FloatTensor([j,i])*cell_size #cell左上角 up left of cell
box[:2] = box[:2]*cell_size + xy # return cxcy relative to image
box_xy = torch.FloatTensor(box.size())#转换成xy形式 convert[cx,cy,w,h] to [x1,xy1,x2,y2]
box_xy[:2] = box[:2] - 0.5*box[2:]
box_xy[2:] = box[:2] + 0.5*box[2:]
max_prob,cls_index = torch.max(pred[i,j,10:],0)
boxes.append(box_xy.view(1,4))
cls_indexs.append(cls_index)
probs.append(contain_prob)
boxes = torch.cat(boxes,0) #(n,4)
probs = torch.cat(probs,0) #(n,)
cls_indexs = torch.cat(cls_indexs,0) #(n,)
keep = nms(boxes,probs)
return boxes[keep],cls_indexs[keep],probs[keep]
def nms(bboxes,scores,threshold=0.5):
'''
bboxes(tensor) [N,4]
scores(tensor) [N,]
'''
x1 = bboxes[:,0]
y1 = bboxes[:,1]
x2 = bboxes[:,2]
y2 = bboxes[:,3]
areas = (x2-x1) * (y2-y1)
_,order = scores.sort(0,descending=True)
keep = []
while order.numel() > 0:
i = order[0]
keep.append(i)
if order.numel() == 1:
break
xx1 = x1[order[1:]].clamp(min=x1[i])
yy1 = y1[order[1:]].clamp(min=y1[i])
xx2 = x2[order[1:]].clamp(max=x2[i])
yy2 = y2[order[1:]].clamp(max=y2[i])
w = (xx2-xx1).clamp(min=0)
h = (yy2-yy1).clamp(min=0)
inter = w*h
ovr = inter / (areas[i] + areas[order[1:]] - inter)
ids = (ovr<=threshold).nonzero().squeeze()
if ids.numel() == 0:
break
order = order[ids+1]
return torch.LongTensor(keep)
#
#start predict one image
#
def predict_gpu(model,image_name,root_path=''):
result = []
image = cv2.imread(root_path+image_name)
h,w,_ = image.shape
img = cv2.resize(image,(224,224))
img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
mean = (123,117,104)#RGB
img = img - np.array(mean,dtype=np.float32)
transform = transforms.Compose([transforms.ToTensor(),])
img = transform(img)
img = Variable(img[None,:,:,:],volatile=True)
img = img.cuda()
pred = model(img) #1x7x7x30
pred = pred.cpu()
boxes,cls_indexs,probs = decoder(pred)
for i,box in enumerate(boxes):
x1 = int(box[0]*w)
x2 = int(box[2]*w)
y1 = int(box[1]*h)
y2 = int(box[3]*h)
cls_index = cls_indexs[i]
cls_index = int(cls_index) # convert LongTensor to int
prob = probs[i]
prob = float(prob)
result.append([(x1,y1),(x2,y2),VOC_CLASSES[cls_index],image_name,prob])
return result
if __name__ == '__main__':
model = vgg16(pretrained=False)
model.classifier = nn.Sequential(
nn.Linear(512 * 7 * 7, 4096),
nn.ReLU(True),
nn.Dropout(),
#nn.Linear(4096, 4096),
#nn.ReLU(True),
#nn.Dropout(),
nn.Linear(4096, 1470),
)
model.load_state_dict(torch.load('yolo.pth'))
model.eval()
model.cuda()
image_name = 'test.jpg'
image = cv2.imread(image_name)
result = predict_gpu(model,image_name)
for left_up,right_bottom,class_name,_,prob in result:
cv2.rectangle(image,left_up,right_bottom,(0,255,0),2)
cv2.putText(image,class_name,left_up,cv2.FONT_HERSHEY_SIMPLEX,1,(0,0,255),1,cv2.LINE_AA)
print(prob)
cv2.imwrite('result.jpg',image)