jsjuan commited on
Commit
ba6f338
1 Parent(s): 237424f

Upload local_utils.py

Browse files
Files changed (1) hide show
  1. local_utils.py +230 -0
local_utils.py ADDED
@@ -0,0 +1,230 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import cv2
3
+ import numpy as np
4
+ import os
5
+
6
+
7
+ def getPath(test_image_root = "./TDCN_IMG/"):
8
+
9
+ path_list={}
10
+ for i,angle_path in enumerate(os.listdir(test_image_root)):
11
+
12
+ angle = os.path.join(test_image_root,angle_path)
13
+
14
+
15
+ path_list[angle_path]=[]
16
+ for img in os.listdir(angle):
17
+ path_= os.path.join(angle,img)
18
+ path_list[angle_path].append([img.strip('.jpeg'),path_])
19
+ return path_list
20
+
21
+
22
+
23
+ class Label:
24
+ def __init__(self, cl=-1, tl=np.array([0., 0.]), br=np.array([0., 0.]), prob=None):
25
+ self.__tl = tl
26
+ self.__br = br
27
+ self.__cl = cl
28
+ self.__prob = prob
29
+
30
+ def __str__(self):
31
+ return 'Class: %d, top left(x: %f, y: %f), bottom right(x: %f, y: %f)' % (
32
+ self.__cl, self.__tl[0], self.__tl[1], self.__br[0], self.__br[1])
33
+
34
+ def copy(self):
35
+ return Label(self.__cl, self.__tl, self.__br)
36
+
37
+ def wh(self):
38
+ return self.__br - self.__tl
39
+
40
+ def cc(self):
41
+ return self.__tl + self.wh() / 2
42
+
43
+ def tl(self):
44
+ return self.__tl
45
+
46
+ def br(self):
47
+ return self.__br
48
+
49
+ def tr(self):
50
+ return np.array([self.__br[0], self.__tl[1]])
51
+
52
+ def bl(self):
53
+ return np.array([self.__tl[0], self.__br[1]])
54
+
55
+ def cl(self):
56
+ return self.__cl
57
+
58
+ def area(self):
59
+ return np.prod(self.wh())
60
+
61
+ def prob(self):
62
+ return self.__prob
63
+
64
+ def set_class(self, cl):
65
+ self.__cl = cl
66
+
67
+ def set_tl(self, tl):
68
+ self.__tl = tl
69
+
70
+ def set_br(self, br):
71
+ self.__br = br
72
+
73
+ def set_wh(self, wh):
74
+ cc = self.cc()
75
+ self.__tl = cc - .5 * wh
76
+ self.__br = cc + .5 * wh
77
+
78
+ def set_prob(self, prob):
79
+ self.__prob = prob
80
+
81
+
82
+
83
+ class DLabel(Label):
84
+ def __init__(self, cl, pts, prob):
85
+ self.pts = pts
86
+ tl = np.amin(pts, axis=1)
87
+ br = np.amax(pts, axis=1)
88
+ Label.__init__(self, cl, tl, br, prob)
89
+
90
+ def getWH(shape):
91
+ return np.array(shape[1::-1]).astype(float)
92
+
93
+ def IOU(tl1, br1, tl2, br2):
94
+ wh1, wh2 = br1-tl1, br2-tl2
95
+ assert((wh1 >= 0).all() and (wh2 >= 0).all())
96
+
97
+ intersection_wh = np.maximum(np.minimum(br1, br2) - np.maximum(tl1, tl2), 0)
98
+ intersection_area = np.prod(intersection_wh)
99
+ area1, area2 = (np.prod(wh1), np.prod(wh2))
100
+ union_area = area1 + area2 - intersection_area
101
+ return intersection_area/union_area
102
+
103
+ def IOU_labels(l1, l2):
104
+ return IOU(l1.tl(), l1.br(), l2.tl(), l2.br())
105
+
106
+ def nms(Labels, iou_threshold=0.5):
107
+ SelectedLabels = []
108
+ Labels.sort(key=lambda l: l.prob(), reverse=True)
109
+
110
+ for label in Labels:
111
+ non_overlap = True
112
+ for sel_label in SelectedLabels:
113
+ if IOU_labels(label, sel_label) > iou_threshold:
114
+ non_overlap = False
115
+ break
116
+
117
+ if non_overlap:
118
+ SelectedLabels.append(label)
119
+ return SelectedLabels
120
+
121
+
122
+
123
+ def find_T_matrix(pts, t_pts):
124
+ A = np.zeros((8, 9))
125
+ for i in range(0, 4):
126
+ xi = pts[:, i]
127
+ xil = t_pts[:, i]
128
+ xi = xi.T
129
+
130
+ A[i*2, 3:6] = -xil[2]*xi
131
+ A[i*2, 6:] = xil[1]*xi
132
+ A[i*2+1, :3] = xil[2]*xi
133
+ A[i*2+1, 6:] = -xil[0]*xi
134
+
135
+ [U, S, V] = np.linalg.svd(A)
136
+ H = V[-1, :].reshape((3, 3))
137
+ return H
138
+
139
+ def getRectPts(tlx, tly, brx, bry):
140
+ return np.matrix([[tlx, brx, brx, tlx], [tly, tly, bry, bry], [1, 1, 1, 1]], dtype=float)
141
+
142
+ def normal(pts, side, mn, MN):
143
+ pts_MN_center_mn = pts * side
144
+ pts_MN = pts_MN_center_mn + mn.reshape((2, 1))
145
+ pts_prop = pts_MN / MN.reshape((2, 1))
146
+ return pts_prop
147
+
148
+ # Reconstruction function from predict value into plate crpoped from image
149
+ def reconstruct(I, Iresized, Yr, lp_threshold):
150
+ # 4 max-pooling layers, stride = 2
151
+ net_stride = 2**4
152
+ side = ((208 + 40)/2)/net_stride
153
+
154
+ # one line and two lines license plate size
155
+ one_line = (470, 110)
156
+ two_lines = (280, 200)
157
+
158
+ Probs = Yr[..., 0]
159
+ Affines = Yr[..., 2:]
160
+
161
+ xx, yy = np.where(Probs > lp_threshold)
162
+ # CNN input image size
163
+ WH = getWH(Iresized.shape)
164
+ # output feature map size
165
+ MN = WH/net_stride
166
+
167
+ vxx = vyy = 0.5 #alpha
168
+ base = lambda vx, vy: np.matrix([[-vx, -vy, 1], [vx, -vy, 1], [vx, vy, 1], [-vx, vy, 1]]).T
169
+ labels = []
170
+ labels_frontal = []
171
+
172
+ for i in range(len(xx)):
173
+ x, y = xx[i], yy[i]
174
+ affine = Affines[x, y]
175
+ prob = Probs[x, y]
176
+
177
+ mn = np.array([float(y) + 0.5, float(x) + 0.5])
178
+
179
+ # affine transformation matrix
180
+ A = np.reshape(affine, (2, 3))
181
+ A[0, 0] = max(A[0, 0], 0)
182
+ A[1, 1] = max(A[1, 1], 0)
183
+ # identity transformation
184
+ B = np.zeros((2, 3))
185
+ B[0, 0] = max(A[0, 0], 0)
186
+ B[1, 1] = max(A[1, 1], 0)
187
+
188
+ pts = np.array(A*base(vxx, vyy))
189
+ pts_frontal = np.array(B*base(vxx, vyy))
190
+
191
+ pts_prop = normal(pts, side, mn, MN)
192
+ frontal = normal(pts_frontal, side, mn, MN)
193
+
194
+ labels.append(DLabel(0, pts_prop, prob))
195
+ labels_frontal.append(DLabel(0, frontal, prob))
196
+
197
+ final_labels = nms(labels, 0.1)
198
+ final_labels_frontal = nms(labels_frontal, 0.1)
199
+
200
+ #print(final_labels_frontal)
201
+ assert final_labels_frontal, "No License plate is founded!"
202
+
203
+ # LP size and type
204
+ out_size, lp_type = (two_lines, 2) if ((final_labels_frontal[0].wh()[0] / final_labels_frontal[0].wh()[1]) < 1.7) else (one_line, 1)
205
+
206
+ TLp = []
207
+ Cor = []
208
+ if len(final_labels):
209
+ final_labels.sort(key=lambda x: x.prob(), reverse=True)
210
+ for _, label in enumerate(final_labels):
211
+ t_ptsh = getRectPts(0, 0, out_size[0], out_size[1])
212
+ ptsh = np.concatenate((label.pts * getWH(I.shape).reshape((2, 1)), np.ones((1, 4))))
213
+ H = find_T_matrix(ptsh, t_ptsh)
214
+ Ilp = cv2.warpPerspective(I, H, out_size, borderValue=0)
215
+ TLp.append(Ilp)
216
+ Cor.append(ptsh)
217
+ return final_labels, TLp, lp_type, Cor
218
+
219
+ def detect_lp(model, I, max_dim, lp_threshold):
220
+ min_dim_img = min(I.shape[:2])
221
+ factor = float(max_dim) / min_dim_img
222
+ w, h = (np.array(I.shape[1::-1], dtype=float) * factor).astype(int).tolist()
223
+ Iresized = cv2.resize(I, (w, h))
224
+ T = Iresized.copy()
225
+ T = T.reshape((1, T.shape[0], T.shape[1], T.shape[2]))
226
+ Yr = model.predict(T)
227
+ Yr = np.squeeze(Yr)
228
+ #print(Yr.shape)
229
+ L, TLp, lp_type, Cor = reconstruct(I, Iresized, Yr, lp_threshold)
230
+ return L, TLp, lp_type, Cor