├── README.md
├── anchors.csv
├── config.py
├── control.py
├── convert_hand3d_tflite_pb.py
├── drawing_helpers.py
├── flatc.exe
├── gesture.py
├── gesture_rules.py
├── hand_landmark_small.pb
├── hand_landmark_small.tflite
├── hand_tracker_multi.py
├── nms.py
├── out.gif
├── palm_detection_builtin.pb
├── palm_detection_without_custom_op.tflite
├── process_keypoints.py
├── run.py
└── trainer.py
/README.md:
--------------------------------------------------------------------------------
1 | # Multi-HandTrackingGPU Python
2 | Multi-Hand Tracking on GPU using Mediapipe models in python
3 |
4 | ```
5 | $ pip install opencv-python tensorflow
6 | $ python run.py
7 | ```
8 | Mediapipe currently does not have GPU support for windows. This repo provides high FPS multi-hand tracking using GPU on python.
9 |
10 | 
11 |
12 | References:
13 | *mediapipe-models*: https://github.com/junhwanjang/mediapipe-models/tree/master/palm_detection/mediapipe_models
14 | *mediapipe*: https://github.com/google/mediapipe/tree/master/mediapipe/models
15 | *hand_tracking*: https://github.com/wolterlw/hand_tracking , https://github.com/metalwhale/hand_tracking
16 | *Convert tflite to pb base*: https://gist.github.com/tworuler/bd7bd4c6cd9a8fbbeb060e7b64cfa008
17 |
--------------------------------------------------------------------------------
/anchors.csv:
--------------------------------------------------------------------------------
1 | 0.015625,0.015625,1,1
2 | 0.015625,0.015625,1,1
3 | 0.046875,0.015625,1,1
4 | 0.046875,0.015625,1,1
5 | 0.078125,0.015625,1,1
6 | 0.078125,0.015625,1,1
7 | 0.109375,0.015625,1,1
8 | 0.109375,0.015625,1,1
9 | 0.140625,0.015625,1,1
10 | 0.140625,0.015625,1,1
11 | 0.171875,0.015625,1,1
12 | 0.171875,0.015625,1,1
13 | 0.203125,0.015625,1,1
14 | 0.203125,0.015625,1,1
15 | 0.234375,0.015625,1,1
16 | 0.234375,0.015625,1,1
17 | 0.265625,0.015625,1,1
18 | 0.265625,0.015625,1,1
19 | 0.296875,0.015625,1,1
20 | 0.296875,0.015625,1,1
21 | 0.328125,0.015625,1,1
22 | 0.328125,0.015625,1,1
23 | 0.359375,0.015625,1,1
24 | 0.359375,0.015625,1,1
25 | 0.390625,0.015625,1,1
26 | 0.390625,0.015625,1,1
27 | 0.421875,0.015625,1,1
28 | 0.421875,0.015625,1,1
29 | 0.453125,0.015625,1,1
30 | 0.453125,0.015625,1,1
31 | 0.484375,0.015625,1,1
32 | 0.484375,0.015625,1,1
33 | 0.515625,0.015625,1,1
34 | 0.515625,0.015625,1,1
35 | 0.546875,0.015625,1,1
36 | 0.546875,0.015625,1,1
37 | 0.578125,0.015625,1,1
38 | 0.578125,0.015625,1,1
39 | 0.609375,0.015625,1,1
40 | 0.609375,0.015625,1,1
41 | 0.640625,0.015625,1,1
42 | 0.640625,0.015625,1,1
43 | 0.671875,0.015625,1,1
44 | 0.671875,0.015625,1,1
45 | 0.703125,0.015625,1,1
46 | 0.703125,0.015625,1,1
47 | 0.734375,0.015625,1,1
48 | 0.734375,0.015625,1,1
49 | 0.765625,0.015625,1,1
50 | 0.765625,0.015625,1,1
51 | 0.796875,0.015625,1,1
52 | 0.796875,0.015625,1,1
53 | 0.828125,0.015625,1,1
54 | 0.828125,0.015625,1,1
55 | 0.859375,0.015625,1,1
56 | 0.859375,0.015625,1,1
57 | 0.890625,0.015625,1,1
58 | 0.890625,0.015625,1,1
59 | 0.921875,0.015625,1,1
60 | 0.921875,0.015625,1,1
61 | 0.953125,0.015625,1,1
62 | 0.953125,0.015625,1,1
63 | 0.984375,0.015625,1,1
64 | 0.984375,0.015625,1,1
65 | 0.015625,0.046875,1,1
66 | 0.015625,0.046875,1,1
67 | 0.046875,0.046875,1,1
68 | 0.046875,0.046875,1,1
69 | 0.078125,0.046875,1,1
70 | 0.078125,0.046875,1,1
71 | 0.109375,0.046875,1,1
72 | 0.109375,0.046875,1,1
73 | 0.140625,0.046875,1,1
74 | 0.140625,0.046875,1,1
75 | 0.171875,0.046875,1,1
76 | 0.171875,0.046875,1,1
77 | 0.203125,0.046875,1,1
78 | 0.203125,0.046875,1,1
79 | 0.234375,0.046875,1,1
80 | 0.234375,0.046875,1,1
81 | 0.265625,0.046875,1,1
82 | 0.265625,0.046875,1,1
83 | 0.296875,0.046875,1,1
84 | 0.296875,0.046875,1,1
85 | 0.328125,0.046875,1,1
86 | 0.328125,0.046875,1,1
87 | 0.359375,0.046875,1,1
88 | 0.359375,0.046875,1,1
89 | 0.390625,0.046875,1,1
90 | 0.390625,0.046875,1,1
91 | 0.421875,0.046875,1,1
92 | 0.421875,0.046875,1,1
93 | 0.453125,0.046875,1,1
94 | 0.453125,0.046875,1,1
95 | 0.484375,0.046875,1,1
96 | 0.484375,0.046875,1,1
97 | 0.515625,0.046875,1,1
98 | 0.515625,0.046875,1,1
99 | 0.546875,0.046875,1,1
100 | 0.546875,0.046875,1,1
101 | 0.578125,0.046875,1,1
102 | 0.578125,0.046875,1,1
103 | 0.609375,0.046875,1,1
104 | 0.609375,0.046875,1,1
105 | 0.640625,0.046875,1,1
106 | 0.640625,0.046875,1,1
107 | 0.671875,0.046875,1,1
108 | 0.671875,0.046875,1,1
109 | 0.703125,0.046875,1,1
110 | 0.703125,0.046875,1,1
111 | 0.734375,0.046875,1,1
112 | 0.734375,0.046875,1,1
113 | 0.765625,0.046875,1,1
114 | 0.765625,0.046875,1,1
115 | 0.796875,0.046875,1,1
116 | 0.796875,0.046875,1,1
117 | 0.828125,0.046875,1,1
118 | 0.828125,0.046875,1,1
119 | 0.859375,0.046875,1,1
120 | 0.859375,0.046875,1,1
121 | 0.890625,0.046875,1,1
122 | 0.890625,0.046875,1,1
123 | 0.921875,0.046875,1,1
124 | 0.921875,0.046875,1,1
125 | 0.953125,0.046875,1,1
126 | 0.953125,0.046875,1,1
127 | 0.984375,0.046875,1,1
128 | 0.984375,0.046875,1,1
129 | 0.015625,0.078125,1,1
130 | 0.015625,0.078125,1,1
131 | 0.046875,0.078125,1,1
132 | 0.046875,0.078125,1,1
133 | 0.078125,0.078125,1,1
134 | 0.078125,0.078125,1,1
135 | 0.109375,0.078125,1,1
136 | 0.109375,0.078125,1,1
137 | 0.140625,0.078125,1,1
138 | 0.140625,0.078125,1,1
139 | 0.171875,0.078125,1,1
140 | 0.171875,0.078125,1,1
141 | 0.203125,0.078125,1,1
142 | 0.203125,0.078125,1,1
143 | 0.234375,0.078125,1,1
144 | 0.234375,0.078125,1,1
145 | 0.265625,0.078125,1,1
146 | 0.265625,0.078125,1,1
147 | 0.296875,0.078125,1,1
148 | 0.296875,0.078125,1,1
149 | 0.328125,0.078125,1,1
150 | 0.328125,0.078125,1,1
151 | 0.359375,0.078125,1,1
152 | 0.359375,0.078125,1,1
153 | 0.390625,0.078125,1,1
154 | 0.390625,0.078125,1,1
155 | 0.421875,0.078125,1,1
156 | 0.421875,0.078125,1,1
157 | 0.453125,0.078125,1,1
158 | 0.453125,0.078125,1,1
159 | 0.484375,0.078125,1,1
160 | 0.484375,0.078125,1,1
161 | 0.515625,0.078125,1,1
162 | 0.515625,0.078125,1,1
163 | 0.546875,0.078125,1,1
164 | 0.546875,0.078125,1,1
165 | 0.578125,0.078125,1,1
166 | 0.578125,0.078125,1,1
167 | 0.609375,0.078125,1,1
168 | 0.609375,0.078125,1,1
169 | 0.640625,0.078125,1,1
170 | 0.640625,0.078125,1,1
171 | 0.671875,0.078125,1,1
172 | 0.671875,0.078125,1,1
173 | 0.703125,0.078125,1,1
174 | 0.703125,0.078125,1,1
175 | 0.734375,0.078125,1,1
176 | 0.734375,0.078125,1,1
177 | 0.765625,0.078125,1,1
178 | 0.765625,0.078125,1,1
179 | 0.796875,0.078125,1,1
180 | 0.796875,0.078125,1,1
181 | 0.828125,0.078125,1,1
182 | 0.828125,0.078125,1,1
183 | 0.859375,0.078125,1,1
184 | 0.859375,0.078125,1,1
185 | 0.890625,0.078125,1,1
186 | 0.890625,0.078125,1,1
187 | 0.921875,0.078125,1,1
188 | 0.921875,0.078125,1,1
189 | 0.953125,0.078125,1,1
190 | 0.953125,0.078125,1,1
191 | 0.984375,0.078125,1,1
192 | 0.984375,0.078125,1,1
193 | 0.015625,0.109375,1,1
194 | 0.015625,0.109375,1,1
195 | 0.046875,0.109375,1,1
196 | 0.046875,0.109375,1,1
197 | 0.078125,0.109375,1,1
198 | 0.078125,0.109375,1,1
199 | 0.109375,0.109375,1,1
200 | 0.109375,0.109375,1,1
201 | 0.140625,0.109375,1,1
202 | 0.140625,0.109375,1,1
203 | 0.171875,0.109375,1,1
204 | 0.171875,0.109375,1,1
205 | 0.203125,0.109375,1,1
206 | 0.203125,0.109375,1,1
207 | 0.234375,0.109375,1,1
208 | 0.234375,0.109375,1,1
209 | 0.265625,0.109375,1,1
210 | 0.265625,0.109375,1,1
211 | 0.296875,0.109375,1,1
212 | 0.296875,0.109375,1,1
213 | 0.328125,0.109375,1,1
214 | 0.328125,0.109375,1,1
215 | 0.359375,0.109375,1,1
216 | 0.359375,0.109375,1,1
217 | 0.390625,0.109375,1,1
218 | 0.390625,0.109375,1,1
219 | 0.421875,0.109375,1,1
220 | 0.421875,0.109375,1,1
221 | 0.453125,0.109375,1,1
222 | 0.453125,0.109375,1,1
223 | 0.484375,0.109375,1,1
224 | 0.484375,0.109375,1,1
225 | 0.515625,0.109375,1,1
226 | 0.515625,0.109375,1,1
227 | 0.546875,0.109375,1,1
228 | 0.546875,0.109375,1,1
229 | 0.578125,0.109375,1,1
230 | 0.578125,0.109375,1,1
231 | 0.609375,0.109375,1,1
232 | 0.609375,0.109375,1,1
233 | 0.640625,0.109375,1,1
234 | 0.640625,0.109375,1,1
235 | 0.671875,0.109375,1,1
236 | 0.671875,0.109375,1,1
237 | 0.703125,0.109375,1,1
238 | 0.703125,0.109375,1,1
239 | 0.734375,0.109375,1,1
240 | 0.734375,0.109375,1,1
241 | 0.765625,0.109375,1,1
242 | 0.765625,0.109375,1,1
243 | 0.796875,0.109375,1,1
244 | 0.796875,0.109375,1,1
245 | 0.828125,0.109375,1,1
246 | 0.828125,0.109375,1,1
247 | 0.859375,0.109375,1,1
248 | 0.859375,0.109375,1,1
249 | 0.890625,0.109375,1,1
250 | 0.890625,0.109375,1,1
251 | 0.921875,0.109375,1,1
252 | 0.921875,0.109375,1,1
253 | 0.953125,0.109375,1,1
254 | 0.953125,0.109375,1,1
255 | 0.984375,0.109375,1,1
256 | 0.984375,0.109375,1,1
257 | 0.015625,0.140625,1,1
258 | 0.015625,0.140625,1,1
259 | 0.046875,0.140625,1,1
260 | 0.046875,0.140625,1,1
261 | 0.078125,0.140625,1,1
262 | 0.078125,0.140625,1,1
263 | 0.109375,0.140625,1,1
264 | 0.109375,0.140625,1,1
265 | 0.140625,0.140625,1,1
266 | 0.140625,0.140625,1,1
267 | 0.171875,0.140625,1,1
268 | 0.171875,0.140625,1,1
269 | 0.203125,0.140625,1,1
270 | 0.203125,0.140625,1,1
271 | 0.234375,0.140625,1,1
272 | 0.234375,0.140625,1,1
273 | 0.265625,0.140625,1,1
274 | 0.265625,0.140625,1,1
275 | 0.296875,0.140625,1,1
276 | 0.296875,0.140625,1,1
277 | 0.328125,0.140625,1,1
278 | 0.328125,0.140625,1,1
279 | 0.359375,0.140625,1,1
280 | 0.359375,0.140625,1,1
281 | 0.390625,0.140625,1,1
282 | 0.390625,0.140625,1,1
283 | 0.421875,0.140625,1,1
284 | 0.421875,0.140625,1,1
285 | 0.453125,0.140625,1,1
286 | 0.453125,0.140625,1,1
287 | 0.484375,0.140625,1,1
288 | 0.484375,0.140625,1,1
289 | 0.515625,0.140625,1,1
290 | 0.515625,0.140625,1,1
291 | 0.546875,0.140625,1,1
292 | 0.546875,0.140625,1,1
293 | 0.578125,0.140625,1,1
294 | 0.578125,0.140625,1,1
295 | 0.609375,0.140625,1,1
296 | 0.609375,0.140625,1,1
297 | 0.640625,0.140625,1,1
298 | 0.640625,0.140625,1,1
299 | 0.671875,0.140625,1,1
300 | 0.671875,0.140625,1,1
301 | 0.703125,0.140625,1,1
302 | 0.703125,0.140625,1,1
303 | 0.734375,0.140625,1,1
304 | 0.734375,0.140625,1,1
305 | 0.765625,0.140625,1,1
306 | 0.765625,0.140625,1,1
307 | 0.796875,0.140625,1,1
308 | 0.796875,0.140625,1,1
309 | 0.828125,0.140625,1,1
310 | 0.828125,0.140625,1,1
311 | 0.859375,0.140625,1,1
312 | 0.859375,0.140625,1,1
313 | 0.890625,0.140625,1,1
314 | 0.890625,0.140625,1,1
315 | 0.921875,0.140625,1,1
316 | 0.921875,0.140625,1,1
317 | 0.953125,0.140625,1,1
318 | 0.953125,0.140625,1,1
319 | 0.984375,0.140625,1,1
320 | 0.984375,0.140625,1,1
321 | 0.015625,0.171875,1,1
322 | 0.015625,0.171875,1,1
323 | 0.046875,0.171875,1,1
324 | 0.046875,0.171875,1,1
325 | 0.078125,0.171875,1,1
326 | 0.078125,0.171875,1,1
327 | 0.109375,0.171875,1,1
328 | 0.109375,0.171875,1,1
329 | 0.140625,0.171875,1,1
330 | 0.140625,0.171875,1,1
331 | 0.171875,0.171875,1,1
332 | 0.171875,0.171875,1,1
333 | 0.203125,0.171875,1,1
334 | 0.203125,0.171875,1,1
335 | 0.234375,0.171875,1,1
336 | 0.234375,0.171875,1,1
337 | 0.265625,0.171875,1,1
338 | 0.265625,0.171875,1,1
339 | 0.296875,0.171875,1,1
340 | 0.296875,0.171875,1,1
341 | 0.328125,0.171875,1,1
342 | 0.328125,0.171875,1,1
343 | 0.359375,0.171875,1,1
344 | 0.359375,0.171875,1,1
345 | 0.390625,0.171875,1,1
346 | 0.390625,0.171875,1,1
347 | 0.421875,0.171875,1,1
348 | 0.421875,0.171875,1,1
349 | 0.453125,0.171875,1,1
350 | 0.453125,0.171875,1,1
351 | 0.484375,0.171875,1,1
352 | 0.484375,0.171875,1,1
353 | 0.515625,0.171875,1,1
354 | 0.515625,0.171875,1,1
355 | 0.546875,0.171875,1,1
356 | 0.546875,0.171875,1,1
357 | 0.578125,0.171875,1,1
358 | 0.578125,0.171875,1,1
359 | 0.609375,0.171875,1,1
360 | 0.609375,0.171875,1,1
361 | 0.640625,0.171875,1,1
362 | 0.640625,0.171875,1,1
363 | 0.671875,0.171875,1,1
364 | 0.671875,0.171875,1,1
365 | 0.703125,0.171875,1,1
366 | 0.703125,0.171875,1,1
367 | 0.734375,0.171875,1,1
368 | 0.734375,0.171875,1,1
369 | 0.765625,0.171875,1,1
370 | 0.765625,0.171875,1,1
371 | 0.796875,0.171875,1,1
372 | 0.796875,0.171875,1,1
373 | 0.828125,0.171875,1,1
374 | 0.828125,0.171875,1,1
375 | 0.859375,0.171875,1,1
376 | 0.859375,0.171875,1,1
377 | 0.890625,0.171875,1,1
378 | 0.890625,0.171875,1,1
379 | 0.921875,0.171875,1,1
380 | 0.921875,0.171875,1,1
381 | 0.953125,0.171875,1,1
382 | 0.953125,0.171875,1,1
383 | 0.984375,0.171875,1,1
384 | 0.984375,0.171875,1,1
385 | 0.015625,0.203125,1,1
386 | 0.015625,0.203125,1,1
387 | 0.046875,0.203125,1,1
388 | 0.046875,0.203125,1,1
389 | 0.078125,0.203125,1,1
390 | 0.078125,0.203125,1,1
391 | 0.109375,0.203125,1,1
392 | 0.109375,0.203125,1,1
393 | 0.140625,0.203125,1,1
394 | 0.140625,0.203125,1,1
395 | 0.171875,0.203125,1,1
396 | 0.171875,0.203125,1,1
397 | 0.203125,0.203125,1,1
398 | 0.203125,0.203125,1,1
399 | 0.234375,0.203125,1,1
400 | 0.234375,0.203125,1,1
401 | 0.265625,0.203125,1,1
402 | 0.265625,0.203125,1,1
403 | 0.296875,0.203125,1,1
404 | 0.296875,0.203125,1,1
405 | 0.328125,0.203125,1,1
406 | 0.328125,0.203125,1,1
407 | 0.359375,0.203125,1,1
408 | 0.359375,0.203125,1,1
409 | 0.390625,0.203125,1,1
410 | 0.390625,0.203125,1,1
411 | 0.421875,0.203125,1,1
412 | 0.421875,0.203125,1,1
413 | 0.453125,0.203125,1,1
414 | 0.453125,0.203125,1,1
415 | 0.484375,0.203125,1,1
416 | 0.484375,0.203125,1,1
417 | 0.515625,0.203125,1,1
418 | 0.515625,0.203125,1,1
419 | 0.546875,0.203125,1,1
420 | 0.546875,0.203125,1,1
421 | 0.578125,0.203125,1,1
422 | 0.578125,0.203125,1,1
423 | 0.609375,0.203125,1,1
424 | 0.609375,0.203125,1,1
425 | 0.640625,0.203125,1,1
426 | 0.640625,0.203125,1,1
427 | 0.671875,0.203125,1,1
428 | 0.671875,0.203125,1,1
429 | 0.703125,0.203125,1,1
430 | 0.703125,0.203125,1,1
431 | 0.734375,0.203125,1,1
432 | 0.734375,0.203125,1,1
433 | 0.765625,0.203125,1,1
434 | 0.765625,0.203125,1,1
435 | 0.796875,0.203125,1,1
436 | 0.796875,0.203125,1,1
437 | 0.828125,0.203125,1,1
438 | 0.828125,0.203125,1,1
439 | 0.859375,0.203125,1,1
440 | 0.859375,0.203125,1,1
441 | 0.890625,0.203125,1,1
442 | 0.890625,0.203125,1,1
443 | 0.921875,0.203125,1,1
444 | 0.921875,0.203125,1,1
445 | 0.953125,0.203125,1,1
446 | 0.953125,0.203125,1,1
447 | 0.984375,0.203125,1,1
448 | 0.984375,0.203125,1,1
449 | 0.015625,0.234375,1,1
450 | 0.015625,0.234375,1,1
451 | 0.046875,0.234375,1,1
452 | 0.046875,0.234375,1,1
453 | 0.078125,0.234375,1,1
454 | 0.078125,0.234375,1,1
455 | 0.109375,0.234375,1,1
456 | 0.109375,0.234375,1,1
457 | 0.140625,0.234375,1,1
458 | 0.140625,0.234375,1,1
459 | 0.171875,0.234375,1,1
460 | 0.171875,0.234375,1,1
461 | 0.203125,0.234375,1,1
462 | 0.203125,0.234375,1,1
463 | 0.234375,0.234375,1,1
464 | 0.234375,0.234375,1,1
465 | 0.265625,0.234375,1,1
466 | 0.265625,0.234375,1,1
467 | 0.296875,0.234375,1,1
468 | 0.296875,0.234375,1,1
469 | 0.328125,0.234375,1,1
470 | 0.328125,0.234375,1,1
471 | 0.359375,0.234375,1,1
472 | 0.359375,0.234375,1,1
473 | 0.390625,0.234375,1,1
474 | 0.390625,0.234375,1,1
475 | 0.421875,0.234375,1,1
476 | 0.421875,0.234375,1,1
477 | 0.453125,0.234375,1,1
478 | 0.453125,0.234375,1,1
479 | 0.484375,0.234375,1,1
480 | 0.484375,0.234375,1,1
481 | 0.515625,0.234375,1,1
482 | 0.515625,0.234375,1,1
483 | 0.546875,0.234375,1,1
484 | 0.546875,0.234375,1,1
485 | 0.578125,0.234375,1,1
486 | 0.578125,0.234375,1,1
487 | 0.609375,0.234375,1,1
488 | 0.609375,0.234375,1,1
489 | 0.640625,0.234375,1,1
490 | 0.640625,0.234375,1,1
491 | 0.671875,0.234375,1,1
492 | 0.671875,0.234375,1,1
493 | 0.703125,0.234375,1,1
494 | 0.703125,0.234375,1,1
495 | 0.734375,0.234375,1,1
496 | 0.734375,0.234375,1,1
497 | 0.765625,0.234375,1,1
498 | 0.765625,0.234375,1,1
499 | 0.796875,0.234375,1,1
500 | 0.796875,0.234375,1,1
501 | 0.828125,0.234375,1,1
502 | 0.828125,0.234375,1,1
503 | 0.859375,0.234375,1,1
504 | 0.859375,0.234375,1,1
505 | 0.890625,0.234375,1,1
506 | 0.890625,0.234375,1,1
507 | 0.921875,0.234375,1,1
508 | 0.921875,0.234375,1,1
509 | 0.953125,0.234375,1,1
510 | 0.953125,0.234375,1,1
511 | 0.984375,0.234375,1,1
512 | 0.984375,0.234375,1,1
513 | 0.015625,0.265625,1,1
514 | 0.015625,0.265625,1,1
515 | 0.046875,0.265625,1,1
516 | 0.046875,0.265625,1,1
517 | 0.078125,0.265625,1,1
518 | 0.078125,0.265625,1,1
519 | 0.109375,0.265625,1,1
520 | 0.109375,0.265625,1,1
521 | 0.140625,0.265625,1,1
522 | 0.140625,0.265625,1,1
523 | 0.171875,0.265625,1,1
524 | 0.171875,0.265625,1,1
525 | 0.203125,0.265625,1,1
526 | 0.203125,0.265625,1,1
527 | 0.234375,0.265625,1,1
528 | 0.234375,0.265625,1,1
529 | 0.265625,0.265625,1,1
530 | 0.265625,0.265625,1,1
531 | 0.296875,0.265625,1,1
532 | 0.296875,0.265625,1,1
533 | 0.328125,0.265625,1,1
534 | 0.328125,0.265625,1,1
535 | 0.359375,0.265625,1,1
536 | 0.359375,0.265625,1,1
537 | 0.390625,0.265625,1,1
538 | 0.390625,0.265625,1,1
539 | 0.421875,0.265625,1,1
540 | 0.421875,0.265625,1,1
541 | 0.453125,0.265625,1,1
542 | 0.453125,0.265625,1,1
543 | 0.484375,0.265625,1,1
544 | 0.484375,0.265625,1,1
545 | 0.515625,0.265625,1,1
546 | 0.515625,0.265625,1,1
547 | 0.546875,0.265625,1,1
548 | 0.546875,0.265625,1,1
549 | 0.578125,0.265625,1,1
550 | 0.578125,0.265625,1,1
551 | 0.609375,0.265625,1,1
552 | 0.609375,0.265625,1,1
553 | 0.640625,0.265625,1,1
554 | 0.640625,0.265625,1,1
555 | 0.671875,0.265625,1,1
556 | 0.671875,0.265625,1,1
557 | 0.703125,0.265625,1,1
558 | 0.703125,0.265625,1,1
559 | 0.734375,0.265625,1,1
560 | 0.734375,0.265625,1,1
561 | 0.765625,0.265625,1,1
562 | 0.765625,0.265625,1,1
563 | 0.796875,0.265625,1,1
564 | 0.796875,0.265625,1,1
565 | 0.828125,0.265625,1,1
566 | 0.828125,0.265625,1,1
567 | 0.859375,0.265625,1,1
568 | 0.859375,0.265625,1,1
569 | 0.890625,0.265625,1,1
570 | 0.890625,0.265625,1,1
571 | 0.921875,0.265625,1,1
572 | 0.921875,0.265625,1,1
573 | 0.953125,0.265625,1,1
574 | 0.953125,0.265625,1,1
575 | 0.984375,0.265625,1,1
576 | 0.984375,0.265625,1,1
577 | 0.015625,0.296875,1,1
578 | 0.015625,0.296875,1,1
579 | 0.046875,0.296875,1,1
580 | 0.046875,0.296875,1,1
581 | 0.078125,0.296875,1,1
582 | 0.078125,0.296875,1,1
583 | 0.109375,0.296875,1,1
584 | 0.109375,0.296875,1,1
585 | 0.140625,0.296875,1,1
586 | 0.140625,0.296875,1,1
587 | 0.171875,0.296875,1,1
588 | 0.171875,0.296875,1,1
589 | 0.203125,0.296875,1,1
590 | 0.203125,0.296875,1,1
591 | 0.234375,0.296875,1,1
592 | 0.234375,0.296875,1,1
593 | 0.265625,0.296875,1,1
594 | 0.265625,0.296875,1,1
595 | 0.296875,0.296875,1,1
596 | 0.296875,0.296875,1,1
597 | 0.328125,0.296875,1,1
598 | 0.328125,0.296875,1,1
599 | 0.359375,0.296875,1,1
600 | 0.359375,0.296875,1,1
601 | 0.390625,0.296875,1,1
602 | 0.390625,0.296875,1,1
603 | 0.421875,0.296875,1,1
604 | 0.421875,0.296875,1,1
605 | 0.453125,0.296875,1,1
606 | 0.453125,0.296875,1,1
607 | 0.484375,0.296875,1,1
608 | 0.484375,0.296875,1,1
609 | 0.515625,0.296875,1,1
610 | 0.515625,0.296875,1,1
611 | 0.546875,0.296875,1,1
612 | 0.546875,0.296875,1,1
613 | 0.578125,0.296875,1,1
614 | 0.578125,0.296875,1,1
615 | 0.609375,0.296875,1,1
616 | 0.609375,0.296875,1,1
617 | 0.640625,0.296875,1,1
618 | 0.640625,0.296875,1,1
619 | 0.671875,0.296875,1,1
620 | 0.671875,0.296875,1,1
621 | 0.703125,0.296875,1,1
622 | 0.703125,0.296875,1,1
623 | 0.734375,0.296875,1,1
624 | 0.734375,0.296875,1,1
625 | 0.765625,0.296875,1,1
626 | 0.765625,0.296875,1,1
627 | 0.796875,0.296875,1,1
628 | 0.796875,0.296875,1,1
629 | 0.828125,0.296875,1,1
630 | 0.828125,0.296875,1,1
631 | 0.859375,0.296875,1,1
632 | 0.859375,0.296875,1,1
633 | 0.890625,0.296875,1,1
634 | 0.890625,0.296875,1,1
635 | 0.921875,0.296875,1,1
636 | 0.921875,0.296875,1,1
637 | 0.953125,0.296875,1,1
638 | 0.953125,0.296875,1,1
639 | 0.984375,0.296875,1,1
640 | 0.984375,0.296875,1,1
641 | 0.015625,0.328125,1,1
642 | 0.015625,0.328125,1,1
643 | 0.046875,0.328125,1,1
644 | 0.046875,0.328125,1,1
645 | 0.078125,0.328125,1,1
646 | 0.078125,0.328125,1,1
647 | 0.109375,0.328125,1,1
648 | 0.109375,0.328125,1,1
649 | 0.140625,0.328125,1,1
650 | 0.140625,0.328125,1,1
651 | 0.171875,0.328125,1,1
652 | 0.171875,0.328125,1,1
653 | 0.203125,0.328125,1,1
654 | 0.203125,0.328125,1,1
655 | 0.234375,0.328125,1,1
656 | 0.234375,0.328125,1,1
657 | 0.265625,0.328125,1,1
658 | 0.265625,0.328125,1,1
659 | 0.296875,0.328125,1,1
660 | 0.296875,0.328125,1,1
661 | 0.328125,0.328125,1,1
662 | 0.328125,0.328125,1,1
663 | 0.359375,0.328125,1,1
664 | 0.359375,0.328125,1,1
665 | 0.390625,0.328125,1,1
666 | 0.390625,0.328125,1,1
667 | 0.421875,0.328125,1,1
668 | 0.421875,0.328125,1,1
669 | 0.453125,0.328125,1,1
670 | 0.453125,0.328125,1,1
671 | 0.484375,0.328125,1,1
672 | 0.484375,0.328125,1,1
673 | 0.515625,0.328125,1,1
674 | 0.515625,0.328125,1,1
675 | 0.546875,0.328125,1,1
676 | 0.546875,0.328125,1,1
677 | 0.578125,0.328125,1,1
678 | 0.578125,0.328125,1,1
679 | 0.609375,0.328125,1,1
680 | 0.609375,0.328125,1,1
681 | 0.640625,0.328125,1,1
682 | 0.640625,0.328125,1,1
683 | 0.671875,0.328125,1,1
684 | 0.671875,0.328125,1,1
685 | 0.703125,0.328125,1,1
686 | 0.703125,0.328125,1,1
687 | 0.734375,0.328125,1,1
688 | 0.734375,0.328125,1,1
689 | 0.765625,0.328125,1,1
690 | 0.765625,0.328125,1,1
691 | 0.796875,0.328125,1,1
692 | 0.796875,0.328125,1,1
693 | 0.828125,0.328125,1,1
694 | 0.828125,0.328125,1,1
695 | 0.859375,0.328125,1,1
696 | 0.859375,0.328125,1,1
697 | 0.890625,0.328125,1,1
698 | 0.890625,0.328125,1,1
699 | 0.921875,0.328125,1,1
700 | 0.921875,0.328125,1,1
701 | 0.953125,0.328125,1,1
702 | 0.953125,0.328125,1,1
703 | 0.984375,0.328125,1,1
704 | 0.984375,0.328125,1,1
705 | 0.015625,0.359375,1,1
706 | 0.015625,0.359375,1,1
707 | 0.046875,0.359375,1,1
708 | 0.046875,0.359375,1,1
709 | 0.078125,0.359375,1,1
710 | 0.078125,0.359375,1,1
711 | 0.109375,0.359375,1,1
712 | 0.109375,0.359375,1,1
713 | 0.140625,0.359375,1,1
714 | 0.140625,0.359375,1,1
715 | 0.171875,0.359375,1,1
716 | 0.171875,0.359375,1,1
717 | 0.203125,0.359375,1,1
718 | 0.203125,0.359375,1,1
719 | 0.234375,0.359375,1,1
720 | 0.234375,0.359375,1,1
721 | 0.265625,0.359375,1,1
722 | 0.265625,0.359375,1,1
723 | 0.296875,0.359375,1,1
724 | 0.296875,0.359375,1,1
725 | 0.328125,0.359375,1,1
726 | 0.328125,0.359375,1,1
727 | 0.359375,0.359375,1,1
728 | 0.359375,0.359375,1,1
729 | 0.390625,0.359375,1,1
730 | 0.390625,0.359375,1,1
731 | 0.421875,0.359375,1,1
732 | 0.421875,0.359375,1,1
733 | 0.453125,0.359375,1,1
734 | 0.453125,0.359375,1,1
735 | 0.484375,0.359375,1,1
736 | 0.484375,0.359375,1,1
737 | 0.515625,0.359375,1,1
738 | 0.515625,0.359375,1,1
739 | 0.546875,0.359375,1,1
740 | 0.546875,0.359375,1,1
741 | 0.578125,0.359375,1,1
742 | 0.578125,0.359375,1,1
743 | 0.609375,0.359375,1,1
744 | 0.609375,0.359375,1,1
745 | 0.640625,0.359375,1,1
746 | 0.640625,0.359375,1,1
747 | 0.671875,0.359375,1,1
748 | 0.671875,0.359375,1,1
749 | 0.703125,0.359375,1,1
750 | 0.703125,0.359375,1,1
751 | 0.734375,0.359375,1,1
752 | 0.734375,0.359375,1,1
753 | 0.765625,0.359375,1,1
754 | 0.765625,0.359375,1,1
755 | 0.796875,0.359375,1,1
756 | 0.796875,0.359375,1,1
757 | 0.828125,0.359375,1,1
758 | 0.828125,0.359375,1,1
759 | 0.859375,0.359375,1,1
760 | 0.859375,0.359375,1,1
761 | 0.890625,0.359375,1,1
762 | 0.890625,0.359375,1,1
763 | 0.921875,0.359375,1,1
764 | 0.921875,0.359375,1,1
765 | 0.953125,0.359375,1,1
766 | 0.953125,0.359375,1,1
767 | 0.984375,0.359375,1,1
768 | 0.984375,0.359375,1,1
769 | 0.015625,0.390625,1,1
770 | 0.015625,0.390625,1,1
771 | 0.046875,0.390625,1,1
772 | 0.046875,0.390625,1,1
773 | 0.078125,0.390625,1,1
774 | 0.078125,0.390625,1,1
775 | 0.109375,0.390625,1,1
776 | 0.109375,0.390625,1,1
777 | 0.140625,0.390625,1,1
778 | 0.140625,0.390625,1,1
779 | 0.171875,0.390625,1,1
780 | 0.171875,0.390625,1,1
781 | 0.203125,0.390625,1,1
782 | 0.203125,0.390625,1,1
783 | 0.234375,0.390625,1,1
784 | 0.234375,0.390625,1,1
785 | 0.265625,0.390625,1,1
786 | 0.265625,0.390625,1,1
787 | 0.296875,0.390625,1,1
788 | 0.296875,0.390625,1,1
789 | 0.328125,0.390625,1,1
790 | 0.328125,0.390625,1,1
791 | 0.359375,0.390625,1,1
792 | 0.359375,0.390625,1,1
793 | 0.390625,0.390625,1,1
794 | 0.390625,0.390625,1,1
795 | 0.421875,0.390625,1,1
796 | 0.421875,0.390625,1,1
797 | 0.453125,0.390625,1,1
798 | 0.453125,0.390625,1,1
799 | 0.484375,0.390625,1,1
800 | 0.484375,0.390625,1,1
801 | 0.515625,0.390625,1,1
802 | 0.515625,0.390625,1,1
803 | 0.546875,0.390625,1,1
804 | 0.546875,0.390625,1,1
805 | 0.578125,0.390625,1,1
806 | 0.578125,0.390625,1,1
807 | 0.609375,0.390625,1,1
808 | 0.609375,0.390625,1,1
809 | 0.640625,0.390625,1,1
810 | 0.640625,0.390625,1,1
811 | 0.671875,0.390625,1,1
812 | 0.671875,0.390625,1,1
813 | 0.703125,0.390625,1,1
814 | 0.703125,0.390625,1,1
815 | 0.734375,0.390625,1,1
816 | 0.734375,0.390625,1,1
817 | 0.765625,0.390625,1,1
818 | 0.765625,0.390625,1,1
819 | 0.796875,0.390625,1,1
820 | 0.796875,0.390625,1,1
821 | 0.828125,0.390625,1,1
822 | 0.828125,0.390625,1,1
823 | 0.859375,0.390625,1,1
824 | 0.859375,0.390625,1,1
825 | 0.890625,0.390625,1,1
826 | 0.890625,0.390625,1,1
827 | 0.921875,0.390625,1,1
828 | 0.921875,0.390625,1,1
829 | 0.953125,0.390625,1,1
830 | 0.953125,0.390625,1,1
831 | 0.984375,0.390625,1,1
832 | 0.984375,0.390625,1,1
833 | 0.015625,0.421875,1,1
834 | 0.015625,0.421875,1,1
835 | 0.046875,0.421875,1,1
836 | 0.046875,0.421875,1,1
837 | 0.078125,0.421875,1,1
838 | 0.078125,0.421875,1,1
839 | 0.109375,0.421875,1,1
840 | 0.109375,0.421875,1,1
841 | 0.140625,0.421875,1,1
842 | 0.140625,0.421875,1,1
843 | 0.171875,0.421875,1,1
844 | 0.171875,0.421875,1,1
845 | 0.203125,0.421875,1,1
846 | 0.203125,0.421875,1,1
847 | 0.234375,0.421875,1,1
848 | 0.234375,0.421875,1,1
849 | 0.265625,0.421875,1,1
850 | 0.265625,0.421875,1,1
851 | 0.296875,0.421875,1,1
852 | 0.296875,0.421875,1,1
853 | 0.328125,0.421875,1,1
854 | 0.328125,0.421875,1,1
855 | 0.359375,0.421875,1,1
856 | 0.359375,0.421875,1,1
857 | 0.390625,0.421875,1,1
858 | 0.390625,0.421875,1,1
859 | 0.421875,0.421875,1,1
860 | 0.421875,0.421875,1,1
861 | 0.453125,0.421875,1,1
862 | 0.453125,0.421875,1,1
863 | 0.484375,0.421875,1,1
864 | 0.484375,0.421875,1,1
865 | 0.515625,0.421875,1,1
866 | 0.515625,0.421875,1,1
867 | 0.546875,0.421875,1,1
868 | 0.546875,0.421875,1,1
869 | 0.578125,0.421875,1,1
870 | 0.578125,0.421875,1,1
871 | 0.609375,0.421875,1,1
872 | 0.609375,0.421875,1,1
873 | 0.640625,0.421875,1,1
874 | 0.640625,0.421875,1,1
875 | 0.671875,0.421875,1,1
876 | 0.671875,0.421875,1,1
877 | 0.703125,0.421875,1,1
878 | 0.703125,0.421875,1,1
879 | 0.734375,0.421875,1,1
880 | 0.734375,0.421875,1,1
881 | 0.765625,0.421875,1,1
882 | 0.765625,0.421875,1,1
883 | 0.796875,0.421875,1,1
884 | 0.796875,0.421875,1,1
885 | 0.828125,0.421875,1,1
886 | 0.828125,0.421875,1,1
887 | 0.859375,0.421875,1,1
888 | 0.859375,0.421875,1,1
889 | 0.890625,0.421875,1,1
890 | 0.890625,0.421875,1,1
891 | 0.921875,0.421875,1,1
892 | 0.921875,0.421875,1,1
893 | 0.953125,0.421875,1,1
894 | 0.953125,0.421875,1,1
895 | 0.984375,0.421875,1,1
896 | 0.984375,0.421875,1,1
897 | 0.015625,0.453125,1,1
898 | 0.015625,0.453125,1,1
899 | 0.046875,0.453125,1,1
900 | 0.046875,0.453125,1,1
901 | 0.078125,0.453125,1,1
902 | 0.078125,0.453125,1,1
903 | 0.109375,0.453125,1,1
904 | 0.109375,0.453125,1,1
905 | 0.140625,0.453125,1,1
906 | 0.140625,0.453125,1,1
907 | 0.171875,0.453125,1,1
908 | 0.171875,0.453125,1,1
909 | 0.203125,0.453125,1,1
910 | 0.203125,0.453125,1,1
911 | 0.234375,0.453125,1,1
912 | 0.234375,0.453125,1,1
913 | 0.265625,0.453125,1,1
914 | 0.265625,0.453125,1,1
915 | 0.296875,0.453125,1,1
916 | 0.296875,0.453125,1,1
917 | 0.328125,0.453125,1,1
918 | 0.328125,0.453125,1,1
919 | 0.359375,0.453125,1,1
920 | 0.359375,0.453125,1,1
921 | 0.390625,0.453125,1,1
922 | 0.390625,0.453125,1,1
923 | 0.421875,0.453125,1,1
924 | 0.421875,0.453125,1,1
925 | 0.453125,0.453125,1,1
926 | 0.453125,0.453125,1,1
927 | 0.484375,0.453125,1,1
928 | 0.484375,0.453125,1,1
929 | 0.515625,0.453125,1,1
930 | 0.515625,0.453125,1,1
931 | 0.546875,0.453125,1,1
932 | 0.546875,0.453125,1,1
933 | 0.578125,0.453125,1,1
934 | 0.578125,0.453125,1,1
935 | 0.609375,0.453125,1,1
936 | 0.609375,0.453125,1,1
937 | 0.640625,0.453125,1,1
938 | 0.640625,0.453125,1,1
939 | 0.671875,0.453125,1,1
940 | 0.671875,0.453125,1,1
941 | 0.703125,0.453125,1,1
942 | 0.703125,0.453125,1,1
943 | 0.734375,0.453125,1,1
944 | 0.734375,0.453125,1,1
945 | 0.765625,0.453125,1,1
946 | 0.765625,0.453125,1,1
947 | 0.796875,0.453125,1,1
948 | 0.796875,0.453125,1,1
949 | 0.828125,0.453125,1,1
950 | 0.828125,0.453125,1,1
951 | 0.859375,0.453125,1,1
952 | 0.859375,0.453125,1,1
953 | 0.890625,0.453125,1,1
954 | 0.890625,0.453125,1,1
955 | 0.921875,0.453125,1,1
956 | 0.921875,0.453125,1,1
957 | 0.953125,0.453125,1,1
958 | 0.953125,0.453125,1,1
959 | 0.984375,0.453125,1,1
960 | 0.984375,0.453125,1,1
961 | 0.015625,0.484375,1,1
962 | 0.015625,0.484375,1,1
963 | 0.046875,0.484375,1,1
964 | 0.046875,0.484375,1,1
965 | 0.078125,0.484375,1,1
966 | 0.078125,0.484375,1,1
967 | 0.109375,0.484375,1,1
968 | 0.109375,0.484375,1,1
969 | 0.140625,0.484375,1,1
970 | 0.140625,0.484375,1,1
971 | 0.171875,0.484375,1,1
972 | 0.171875,0.484375,1,1
973 | 0.203125,0.484375,1,1
974 | 0.203125,0.484375,1,1
975 | 0.234375,0.484375,1,1
976 | 0.234375,0.484375,1,1
977 | 0.265625,0.484375,1,1
978 | 0.265625,0.484375,1,1
979 | 0.296875,0.484375,1,1
980 | 0.296875,0.484375,1,1
981 | 0.328125,0.484375,1,1
982 | 0.328125,0.484375,1,1
983 | 0.359375,0.484375,1,1
984 | 0.359375,0.484375,1,1
985 | 0.390625,0.484375,1,1
986 | 0.390625,0.484375,1,1
987 | 0.421875,0.484375,1,1
988 | 0.421875,0.484375,1,1
989 | 0.453125,0.484375,1,1
990 | 0.453125,0.484375,1,1
991 | 0.484375,0.484375,1,1
992 | 0.484375,0.484375,1,1
993 | 0.515625,0.484375,1,1
994 | 0.515625,0.484375,1,1
995 | 0.546875,0.484375,1,1
996 | 0.546875,0.484375,1,1
997 | 0.578125,0.484375,1,1
998 | 0.578125,0.484375,1,1
999 | 0.609375,0.484375,1,1
1000 | 0.609375,0.484375,1,1
1001 | 0.640625,0.484375,1,1
1002 | 0.640625,0.484375,1,1
1003 | 0.671875,0.484375,1,1
1004 | 0.671875,0.484375,1,1
1005 | 0.703125,0.484375,1,1
1006 | 0.703125,0.484375,1,1
1007 | 0.734375,0.484375,1,1
1008 | 0.734375,0.484375,1,1
1009 | 0.765625,0.484375,1,1
1010 | 0.765625,0.484375,1,1
1011 | 0.796875,0.484375,1,1
1012 | 0.796875,0.484375,1,1
1013 | 0.828125,0.484375,1,1
1014 | 0.828125,0.484375,1,1
1015 | 0.859375,0.484375,1,1
1016 | 0.859375,0.484375,1,1
1017 | 0.890625,0.484375,1,1
1018 | 0.890625,0.484375,1,1
1019 | 0.921875,0.484375,1,1
1020 | 0.921875,0.484375,1,1
1021 | 0.953125,0.484375,1,1
1022 | 0.953125,0.484375,1,1
1023 | 0.984375,0.484375,1,1
1024 | 0.984375,0.484375,1,1
1025 | 0.015625,0.515625,1,1
1026 | 0.015625,0.515625,1,1
1027 | 0.046875,0.515625,1,1
1028 | 0.046875,0.515625,1,1
1029 | 0.078125,0.515625,1,1
1030 | 0.078125,0.515625,1,1
1031 | 0.109375,0.515625,1,1
1032 | 0.109375,0.515625,1,1
1033 | 0.140625,0.515625,1,1
1034 | 0.140625,0.515625,1,1
1035 | 0.171875,0.515625,1,1
1036 | 0.171875,0.515625,1,1
1037 | 0.203125,0.515625,1,1
1038 | 0.203125,0.515625,1,1
1039 | 0.234375,0.515625,1,1
1040 | 0.234375,0.515625,1,1
1041 | 0.265625,0.515625,1,1
1042 | 0.265625,0.515625,1,1
1043 | 0.296875,0.515625,1,1
1044 | 0.296875,0.515625,1,1
1045 | 0.328125,0.515625,1,1
1046 | 0.328125,0.515625,1,1
1047 | 0.359375,0.515625,1,1
1048 | 0.359375,0.515625,1,1
1049 | 0.390625,0.515625,1,1
1050 | 0.390625,0.515625,1,1
1051 | 0.421875,0.515625,1,1
1052 | 0.421875,0.515625,1,1
1053 | 0.453125,0.515625,1,1
1054 | 0.453125,0.515625,1,1
1055 | 0.484375,0.515625,1,1
1056 | 0.484375,0.515625,1,1
1057 | 0.515625,0.515625,1,1
1058 | 0.515625,0.515625,1,1
1059 | 0.546875,0.515625,1,1
1060 | 0.546875,0.515625,1,1
1061 | 0.578125,0.515625,1,1
1062 | 0.578125,0.515625,1,1
1063 | 0.609375,0.515625,1,1
1064 | 0.609375,0.515625,1,1
1065 | 0.640625,0.515625,1,1
1066 | 0.640625,0.515625,1,1
1067 | 0.671875,0.515625,1,1
1068 | 0.671875,0.515625,1,1
1069 | 0.703125,0.515625,1,1
1070 | 0.703125,0.515625,1,1
1071 | 0.734375,0.515625,1,1
1072 | 0.734375,0.515625,1,1
1073 | 0.765625,0.515625,1,1
1074 | 0.765625,0.515625,1,1
1075 | 0.796875,0.515625,1,1
1076 | 0.796875,0.515625,1,1
1077 | 0.828125,0.515625,1,1
1078 | 0.828125,0.515625,1,1
1079 | 0.859375,0.515625,1,1
1080 | 0.859375,0.515625,1,1
1081 | 0.890625,0.515625,1,1
1082 | 0.890625,0.515625,1,1
1083 | 0.921875,0.515625,1,1
1084 | 0.921875,0.515625,1,1
1085 | 0.953125,0.515625,1,1
1086 | 0.953125,0.515625,1,1
1087 | 0.984375,0.515625,1,1
1088 | 0.984375,0.515625,1,1
1089 | 0.015625,0.546875,1,1
1090 | 0.015625,0.546875,1,1
1091 | 0.046875,0.546875,1,1
1092 | 0.046875,0.546875,1,1
1093 | 0.078125,0.546875,1,1
1094 | 0.078125,0.546875,1,1
1095 | 0.109375,0.546875,1,1
1096 | 0.109375,0.546875,1,1
1097 | 0.140625,0.546875,1,1
1098 | 0.140625,0.546875,1,1
1099 | 0.171875,0.546875,1,1
1100 | 0.171875,0.546875,1,1
1101 | 0.203125,0.546875,1,1
1102 | 0.203125,0.546875,1,1
1103 | 0.234375,0.546875,1,1
1104 | 0.234375,0.546875,1,1
1105 | 0.265625,0.546875,1,1
1106 | 0.265625,0.546875,1,1
1107 | 0.296875,0.546875,1,1
1108 | 0.296875,0.546875,1,1
1109 | 0.328125,0.546875,1,1
1110 | 0.328125,0.546875,1,1
1111 | 0.359375,0.546875,1,1
1112 | 0.359375,0.546875,1,1
1113 | 0.390625,0.546875,1,1
1114 | 0.390625,0.546875,1,1
1115 | 0.421875,0.546875,1,1
1116 | 0.421875,0.546875,1,1
1117 | 0.453125,0.546875,1,1
1118 | 0.453125,0.546875,1,1
1119 | 0.484375,0.546875,1,1
1120 | 0.484375,0.546875,1,1
1121 | 0.515625,0.546875,1,1
1122 | 0.515625,0.546875,1,1
1123 | 0.546875,0.546875,1,1
1124 | 0.546875,0.546875,1,1
1125 | 0.578125,0.546875,1,1
1126 | 0.578125,0.546875,1,1
1127 | 0.609375,0.546875,1,1
1128 | 0.609375,0.546875,1,1
1129 | 0.640625,0.546875,1,1
1130 | 0.640625,0.546875,1,1
1131 | 0.671875,0.546875,1,1
1132 | 0.671875,0.546875,1,1
1133 | 0.703125,0.546875,1,1
1134 | 0.703125,0.546875,1,1
1135 | 0.734375,0.546875,1,1
1136 | 0.734375,0.546875,1,1
1137 | 0.765625,0.546875,1,1
1138 | 0.765625,0.546875,1,1
1139 | 0.796875,0.546875,1,1
1140 | 0.796875,0.546875,1,1
1141 | 0.828125,0.546875,1,1
1142 | 0.828125,0.546875,1,1
1143 | 0.859375,0.546875,1,1
1144 | 0.859375,0.546875,1,1
1145 | 0.890625,0.546875,1,1
1146 | 0.890625,0.546875,1,1
1147 | 0.921875,0.546875,1,1
1148 | 0.921875,0.546875,1,1
1149 | 0.953125,0.546875,1,1
1150 | 0.953125,0.546875,1,1
1151 | 0.984375,0.546875,1,1
1152 | 0.984375,0.546875,1,1
1153 | 0.015625,0.578125,1,1
1154 | 0.015625,0.578125,1,1
1155 | 0.046875,0.578125,1,1
1156 | 0.046875,0.578125,1,1
1157 | 0.078125,0.578125,1,1
1158 | 0.078125,0.578125,1,1
1159 | 0.109375,0.578125,1,1
1160 | 0.109375,0.578125,1,1
1161 | 0.140625,0.578125,1,1
1162 | 0.140625,0.578125,1,1
1163 | 0.171875,0.578125,1,1
1164 | 0.171875,0.578125,1,1
1165 | 0.203125,0.578125,1,1
1166 | 0.203125,0.578125,1,1
1167 | 0.234375,0.578125,1,1
1168 | 0.234375,0.578125,1,1
1169 | 0.265625,0.578125,1,1
1170 | 0.265625,0.578125,1,1
1171 | 0.296875,0.578125,1,1
1172 | 0.296875,0.578125,1,1
1173 | 0.328125,0.578125,1,1
1174 | 0.328125,0.578125,1,1
1175 | 0.359375,0.578125,1,1
1176 | 0.359375,0.578125,1,1
1177 | 0.390625,0.578125,1,1
1178 | 0.390625,0.578125,1,1
1179 | 0.421875,0.578125,1,1
1180 | 0.421875,0.578125,1,1
1181 | 0.453125,0.578125,1,1
1182 | 0.453125,0.578125,1,1
1183 | 0.484375,0.578125,1,1
1184 | 0.484375,0.578125,1,1
1185 | 0.515625,0.578125,1,1
1186 | 0.515625,0.578125,1,1
1187 | 0.546875,0.578125,1,1
1188 | 0.546875,0.578125,1,1
1189 | 0.578125,0.578125,1,1
1190 | 0.578125,0.578125,1,1
1191 | 0.609375,0.578125,1,1
1192 | 0.609375,0.578125,1,1
1193 | 0.640625,0.578125,1,1
1194 | 0.640625,0.578125,1,1
1195 | 0.671875,0.578125,1,1
1196 | 0.671875,0.578125,1,1
1197 | 0.703125,0.578125,1,1
1198 | 0.703125,0.578125,1,1
1199 | 0.734375,0.578125,1,1
1200 | 0.734375,0.578125,1,1
1201 | 0.765625,0.578125,1,1
1202 | 0.765625,0.578125,1,1
1203 | 0.796875,0.578125,1,1
1204 | 0.796875,0.578125,1,1
1205 | 0.828125,0.578125,1,1
1206 | 0.828125,0.578125,1,1
1207 | 0.859375,0.578125,1,1
1208 | 0.859375,0.578125,1,1
1209 | 0.890625,0.578125,1,1
1210 | 0.890625,0.578125,1,1
1211 | 0.921875,0.578125,1,1
1212 | 0.921875,0.578125,1,1
1213 | 0.953125,0.578125,1,1
1214 | 0.953125,0.578125,1,1
1215 | 0.984375,0.578125,1,1
1216 | 0.984375,0.578125,1,1
1217 | 0.015625,0.609375,1,1
1218 | 0.015625,0.609375,1,1
1219 | 0.046875,0.609375,1,1
1220 | 0.046875,0.609375,1,1
1221 | 0.078125,0.609375,1,1
1222 | 0.078125,0.609375,1,1
1223 | 0.109375,0.609375,1,1
1224 | 0.109375,0.609375,1,1
1225 | 0.140625,0.609375,1,1
1226 | 0.140625,0.609375,1,1
1227 | 0.171875,0.609375,1,1
1228 | 0.171875,0.609375,1,1
1229 | 0.203125,0.609375,1,1
1230 | 0.203125,0.609375,1,1
1231 | 0.234375,0.609375,1,1
1232 | 0.234375,0.609375,1,1
1233 | 0.265625,0.609375,1,1
1234 | 0.265625,0.609375,1,1
1235 | 0.296875,0.609375,1,1
1236 | 0.296875,0.609375,1,1
1237 | 0.328125,0.609375,1,1
1238 | 0.328125,0.609375,1,1
1239 | 0.359375,0.609375,1,1
1240 | 0.359375,0.609375,1,1
1241 | 0.390625,0.609375,1,1
1242 | 0.390625,0.609375,1,1
1243 | 0.421875,0.609375,1,1
1244 | 0.421875,0.609375,1,1
1245 | 0.453125,0.609375,1,1
1246 | 0.453125,0.609375,1,1
1247 | 0.484375,0.609375,1,1
1248 | 0.484375,0.609375,1,1
1249 | 0.515625,0.609375,1,1
1250 | 0.515625,0.609375,1,1
1251 | 0.546875,0.609375,1,1
1252 | 0.546875,0.609375,1,1
1253 | 0.578125,0.609375,1,1
1254 | 0.578125,0.609375,1,1
1255 | 0.609375,0.609375,1,1
1256 | 0.609375,0.609375,1,1
1257 | 0.640625,0.609375,1,1
1258 | 0.640625,0.609375,1,1
1259 | 0.671875,0.609375,1,1
1260 | 0.671875,0.609375,1,1
1261 | 0.703125,0.609375,1,1
1262 | 0.703125,0.609375,1,1
1263 | 0.734375,0.609375,1,1
1264 | 0.734375,0.609375,1,1
1265 | 0.765625,0.609375,1,1
1266 | 0.765625,0.609375,1,1
1267 | 0.796875,0.609375,1,1
1268 | 0.796875,0.609375,1,1
1269 | 0.828125,0.609375,1,1
1270 | 0.828125,0.609375,1,1
1271 | 0.859375,0.609375,1,1
1272 | 0.859375,0.609375,1,1
1273 | 0.890625,0.609375,1,1
1274 | 0.890625,0.609375,1,1
1275 | 0.921875,0.609375,1,1
1276 | 0.921875,0.609375,1,1
1277 | 0.953125,0.609375,1,1
1278 | 0.953125,0.609375,1,1
1279 | 0.984375,0.609375,1,1
1280 | 0.984375,0.609375,1,1
1281 | 0.015625,0.640625,1,1
1282 | 0.015625,0.640625,1,1
1283 | 0.046875,0.640625,1,1
1284 | 0.046875,0.640625,1,1
1285 | 0.078125,0.640625,1,1
1286 | 0.078125,0.640625,1,1
1287 | 0.109375,0.640625,1,1
1288 | 0.109375,0.640625,1,1
1289 | 0.140625,0.640625,1,1
1290 | 0.140625,0.640625,1,1
1291 | 0.171875,0.640625,1,1
1292 | 0.171875,0.640625,1,1
1293 | 0.203125,0.640625,1,1
1294 | 0.203125,0.640625,1,1
1295 | 0.234375,0.640625,1,1
1296 | 0.234375,0.640625,1,1
1297 | 0.265625,0.640625,1,1
1298 | 0.265625,0.640625,1,1
1299 | 0.296875,0.640625,1,1
1300 | 0.296875,0.640625,1,1
1301 | 0.328125,0.640625,1,1
1302 | 0.328125,0.640625,1,1
1303 | 0.359375,0.640625,1,1
1304 | 0.359375,0.640625,1,1
1305 | 0.390625,0.640625,1,1
1306 | 0.390625,0.640625,1,1
1307 | 0.421875,0.640625,1,1
1308 | 0.421875,0.640625,1,1
1309 | 0.453125,0.640625,1,1
1310 | 0.453125,0.640625,1,1
1311 | 0.484375,0.640625,1,1
1312 | 0.484375,0.640625,1,1
1313 | 0.515625,0.640625,1,1
1314 | 0.515625,0.640625,1,1
1315 | 0.546875,0.640625,1,1
1316 | 0.546875,0.640625,1,1
1317 | 0.578125,0.640625,1,1
1318 | 0.578125,0.640625,1,1
1319 | 0.609375,0.640625,1,1
1320 | 0.609375,0.640625,1,1
1321 | 0.640625,0.640625,1,1
1322 | 0.640625,0.640625,1,1
1323 | 0.671875,0.640625,1,1
1324 | 0.671875,0.640625,1,1
1325 | 0.703125,0.640625,1,1
1326 | 0.703125,0.640625,1,1
1327 | 0.734375,0.640625,1,1
1328 | 0.734375,0.640625,1,1
1329 | 0.765625,0.640625,1,1
1330 | 0.765625,0.640625,1,1
1331 | 0.796875,0.640625,1,1
1332 | 0.796875,0.640625,1,1
1333 | 0.828125,0.640625,1,1
1334 | 0.828125,0.640625,1,1
1335 | 0.859375,0.640625,1,1
1336 | 0.859375,0.640625,1,1
1337 | 0.890625,0.640625,1,1
1338 | 0.890625,0.640625,1,1
1339 | 0.921875,0.640625,1,1
1340 | 0.921875,0.640625,1,1
1341 | 0.953125,0.640625,1,1
1342 | 0.953125,0.640625,1,1
1343 | 0.984375,0.640625,1,1
1344 | 0.984375,0.640625,1,1
1345 | 0.015625,0.671875,1,1
1346 | 0.015625,0.671875,1,1
1347 | 0.046875,0.671875,1,1
1348 | 0.046875,0.671875,1,1
1349 | 0.078125,0.671875,1,1
1350 | 0.078125,0.671875,1,1
1351 | 0.109375,0.671875,1,1
1352 | 0.109375,0.671875,1,1
1353 | 0.140625,0.671875,1,1
1354 | 0.140625,0.671875,1,1
1355 | 0.171875,0.671875,1,1
1356 | 0.171875,0.671875,1,1
1357 | 0.203125,0.671875,1,1
1358 | 0.203125,0.671875,1,1
1359 | 0.234375,0.671875,1,1
1360 | 0.234375,0.671875,1,1
1361 | 0.265625,0.671875,1,1
1362 | 0.265625,0.671875,1,1
1363 | 0.296875,0.671875,1,1
1364 | 0.296875,0.671875,1,1
1365 | 0.328125,0.671875,1,1
1366 | 0.328125,0.671875,1,1
1367 | 0.359375,0.671875,1,1
1368 | 0.359375,0.671875,1,1
1369 | 0.390625,0.671875,1,1
1370 | 0.390625,0.671875,1,1
1371 | 0.421875,0.671875,1,1
1372 | 0.421875,0.671875,1,1
1373 | 0.453125,0.671875,1,1
1374 | 0.453125,0.671875,1,1
1375 | 0.484375,0.671875,1,1
1376 | 0.484375,0.671875,1,1
1377 | 0.515625,0.671875,1,1
1378 | 0.515625,0.671875,1,1
1379 | 0.546875,0.671875,1,1
1380 | 0.546875,0.671875,1,1
1381 | 0.578125,0.671875,1,1
1382 | 0.578125,0.671875,1,1
1383 | 0.609375,0.671875,1,1
1384 | 0.609375,0.671875,1,1
1385 | 0.640625,0.671875,1,1
1386 | 0.640625,0.671875,1,1
1387 | 0.671875,0.671875,1,1
1388 | 0.671875,0.671875,1,1
1389 | 0.703125,0.671875,1,1
1390 | 0.703125,0.671875,1,1
1391 | 0.734375,0.671875,1,1
1392 | 0.734375,0.671875,1,1
1393 | 0.765625,0.671875,1,1
1394 | 0.765625,0.671875,1,1
1395 | 0.796875,0.671875,1,1
1396 | 0.796875,0.671875,1,1
1397 | 0.828125,0.671875,1,1
1398 | 0.828125,0.671875,1,1
1399 | 0.859375,0.671875,1,1
1400 | 0.859375,0.671875,1,1
1401 | 0.890625,0.671875,1,1
1402 | 0.890625,0.671875,1,1
1403 | 0.921875,0.671875,1,1
1404 | 0.921875,0.671875,1,1
1405 | 0.953125,0.671875,1,1
1406 | 0.953125,0.671875,1,1
1407 | 0.984375,0.671875,1,1
1408 | 0.984375,0.671875,1,1
1409 | 0.015625,0.703125,1,1
1410 | 0.015625,0.703125,1,1
1411 | 0.046875,0.703125,1,1
1412 | 0.046875,0.703125,1,1
1413 | 0.078125,0.703125,1,1
1414 | 0.078125,0.703125,1,1
1415 | 0.109375,0.703125,1,1
1416 | 0.109375,0.703125,1,1
1417 | 0.140625,0.703125,1,1
1418 | 0.140625,0.703125,1,1
1419 | 0.171875,0.703125,1,1
1420 | 0.171875,0.703125,1,1
1421 | 0.203125,0.703125,1,1
1422 | 0.203125,0.703125,1,1
1423 | 0.234375,0.703125,1,1
1424 | 0.234375,0.703125,1,1
1425 | 0.265625,0.703125,1,1
1426 | 0.265625,0.703125,1,1
1427 | 0.296875,0.703125,1,1
1428 | 0.296875,0.703125,1,1
1429 | 0.328125,0.703125,1,1
1430 | 0.328125,0.703125,1,1
1431 | 0.359375,0.703125,1,1
1432 | 0.359375,0.703125,1,1
1433 | 0.390625,0.703125,1,1
1434 | 0.390625,0.703125,1,1
1435 | 0.421875,0.703125,1,1
1436 | 0.421875,0.703125,1,1
1437 | 0.453125,0.703125,1,1
1438 | 0.453125,0.703125,1,1
1439 | 0.484375,0.703125,1,1
1440 | 0.484375,0.703125,1,1
1441 | 0.515625,0.703125,1,1
1442 | 0.515625,0.703125,1,1
1443 | 0.546875,0.703125,1,1
1444 | 0.546875,0.703125,1,1
1445 | 0.578125,0.703125,1,1
1446 | 0.578125,0.703125,1,1
1447 | 0.609375,0.703125,1,1
1448 | 0.609375,0.703125,1,1
1449 | 0.640625,0.703125,1,1
1450 | 0.640625,0.703125,1,1
1451 | 0.671875,0.703125,1,1
1452 | 0.671875,0.703125,1,1
1453 | 0.703125,0.703125,1,1
1454 | 0.703125,0.703125,1,1
1455 | 0.734375,0.703125,1,1
1456 | 0.734375,0.703125,1,1
1457 | 0.765625,0.703125,1,1
1458 | 0.765625,0.703125,1,1
1459 | 0.796875,0.703125,1,1
1460 | 0.796875,0.703125,1,1
1461 | 0.828125,0.703125,1,1
1462 | 0.828125,0.703125,1,1
1463 | 0.859375,0.703125,1,1
1464 | 0.859375,0.703125,1,1
1465 | 0.890625,0.703125,1,1
1466 | 0.890625,0.703125,1,1
1467 | 0.921875,0.703125,1,1
1468 | 0.921875,0.703125,1,1
1469 | 0.953125,0.703125,1,1
1470 | 0.953125,0.703125,1,1
1471 | 0.984375,0.703125,1,1
1472 | 0.984375,0.703125,1,1
1473 | 0.015625,0.734375,1,1
1474 | 0.015625,0.734375,1,1
1475 | 0.046875,0.734375,1,1
1476 | 0.046875,0.734375,1,1
1477 | 0.078125,0.734375,1,1
1478 | 0.078125,0.734375,1,1
1479 | 0.109375,0.734375,1,1
1480 | 0.109375,0.734375,1,1
1481 | 0.140625,0.734375,1,1
1482 | 0.140625,0.734375,1,1
1483 | 0.171875,0.734375,1,1
1484 | 0.171875,0.734375,1,1
1485 | 0.203125,0.734375,1,1
1486 | 0.203125,0.734375,1,1
1487 | 0.234375,0.734375,1,1
1488 | 0.234375,0.734375,1,1
1489 | 0.265625,0.734375,1,1
1490 | 0.265625,0.734375,1,1
1491 | 0.296875,0.734375,1,1
1492 | 0.296875,0.734375,1,1
1493 | 0.328125,0.734375,1,1
1494 | 0.328125,0.734375,1,1
1495 | 0.359375,0.734375,1,1
1496 | 0.359375,0.734375,1,1
1497 | 0.390625,0.734375,1,1
1498 | 0.390625,0.734375,1,1
1499 | 0.421875,0.734375,1,1
1500 | 0.421875,0.734375,1,1
1501 | 0.453125,0.734375,1,1
1502 | 0.453125,0.734375,1,1
1503 | 0.484375,0.734375,1,1
1504 | 0.484375,0.734375,1,1
1505 | 0.515625,0.734375,1,1
1506 | 0.515625,0.734375,1,1
1507 | 0.546875,0.734375,1,1
1508 | 0.546875,0.734375,1,1
1509 | 0.578125,0.734375,1,1
1510 | 0.578125,0.734375,1,1
1511 | 0.609375,0.734375,1,1
1512 | 0.609375,0.734375,1,1
1513 | 0.640625,0.734375,1,1
1514 | 0.640625,0.734375,1,1
1515 | 0.671875,0.734375,1,1
1516 | 0.671875,0.734375,1,1
1517 | 0.703125,0.734375,1,1
1518 | 0.703125,0.734375,1,1
1519 | 0.734375,0.734375,1,1
1520 | 0.734375,0.734375,1,1
1521 | 0.765625,0.734375,1,1
1522 | 0.765625,0.734375,1,1
1523 | 0.796875,0.734375,1,1
1524 | 0.796875,0.734375,1,1
1525 | 0.828125,0.734375,1,1
1526 | 0.828125,0.734375,1,1
1527 | 0.859375,0.734375,1,1
1528 | 0.859375,0.734375,1,1
1529 | 0.890625,0.734375,1,1
1530 | 0.890625,0.734375,1,1
1531 | 0.921875,0.734375,1,1
1532 | 0.921875,0.734375,1,1
1533 | 0.953125,0.734375,1,1
1534 | 0.953125,0.734375,1,1
1535 | 0.984375,0.734375,1,1
1536 | 0.984375,0.734375,1,1
1537 | 0.015625,0.765625,1,1
1538 | 0.015625,0.765625,1,1
1539 | 0.046875,0.765625,1,1
1540 | 0.046875,0.765625,1,1
1541 | 0.078125,0.765625,1,1
1542 | 0.078125,0.765625,1,1
1543 | 0.109375,0.765625,1,1
1544 | 0.109375,0.765625,1,1
1545 | 0.140625,0.765625,1,1
1546 | 0.140625,0.765625,1,1
1547 | 0.171875,0.765625,1,1
1548 | 0.171875,0.765625,1,1
1549 | 0.203125,0.765625,1,1
1550 | 0.203125,0.765625,1,1
1551 | 0.234375,0.765625,1,1
1552 | 0.234375,0.765625,1,1
1553 | 0.265625,0.765625,1,1
1554 | 0.265625,0.765625,1,1
1555 | 0.296875,0.765625,1,1
1556 | 0.296875,0.765625,1,1
1557 | 0.328125,0.765625,1,1
1558 | 0.328125,0.765625,1,1
1559 | 0.359375,0.765625,1,1
1560 | 0.359375,0.765625,1,1
1561 | 0.390625,0.765625,1,1
1562 | 0.390625,0.765625,1,1
1563 | 0.421875,0.765625,1,1
1564 | 0.421875,0.765625,1,1
1565 | 0.453125,0.765625,1,1
1566 | 0.453125,0.765625,1,1
1567 | 0.484375,0.765625,1,1
1568 | 0.484375,0.765625,1,1
1569 | 0.515625,0.765625,1,1
1570 | 0.515625,0.765625,1,1
1571 | 0.546875,0.765625,1,1
1572 | 0.546875,0.765625,1,1
1573 | 0.578125,0.765625,1,1
1574 | 0.578125,0.765625,1,1
1575 | 0.609375,0.765625,1,1
1576 | 0.609375,0.765625,1,1
1577 | 0.640625,0.765625,1,1
1578 | 0.640625,0.765625,1,1
1579 | 0.671875,0.765625,1,1
1580 | 0.671875,0.765625,1,1
1581 | 0.703125,0.765625,1,1
1582 | 0.703125,0.765625,1,1
1583 | 0.734375,0.765625,1,1
1584 | 0.734375,0.765625,1,1
1585 | 0.765625,0.765625,1,1
1586 | 0.765625,0.765625,1,1
1587 | 0.796875,0.765625,1,1
1588 | 0.796875,0.765625,1,1
1589 | 0.828125,0.765625,1,1
1590 | 0.828125,0.765625,1,1
1591 | 0.859375,0.765625,1,1
1592 | 0.859375,0.765625,1,1
1593 | 0.890625,0.765625,1,1
1594 | 0.890625,0.765625,1,1
1595 | 0.921875,0.765625,1,1
1596 | 0.921875,0.765625,1,1
1597 | 0.953125,0.765625,1,1
1598 | 0.953125,0.765625,1,1
1599 | 0.984375,0.765625,1,1
1600 | 0.984375,0.765625,1,1
1601 | 0.015625,0.796875,1,1
1602 | 0.015625,0.796875,1,1
1603 | 0.046875,0.796875,1,1
1604 | 0.046875,0.796875,1,1
1605 | 0.078125,0.796875,1,1
1606 | 0.078125,0.796875,1,1
1607 | 0.109375,0.796875,1,1
1608 | 0.109375,0.796875,1,1
1609 | 0.140625,0.796875,1,1
1610 | 0.140625,0.796875,1,1
1611 | 0.171875,0.796875,1,1
1612 | 0.171875,0.796875,1,1
1613 | 0.203125,0.796875,1,1
1614 | 0.203125,0.796875,1,1
1615 | 0.234375,0.796875,1,1
1616 | 0.234375,0.796875,1,1
1617 | 0.265625,0.796875,1,1
1618 | 0.265625,0.796875,1,1
1619 | 0.296875,0.796875,1,1
1620 | 0.296875,0.796875,1,1
1621 | 0.328125,0.796875,1,1
1622 | 0.328125,0.796875,1,1
1623 | 0.359375,0.796875,1,1
1624 | 0.359375,0.796875,1,1
1625 | 0.390625,0.796875,1,1
1626 | 0.390625,0.796875,1,1
1627 | 0.421875,0.796875,1,1
1628 | 0.421875,0.796875,1,1
1629 | 0.453125,0.796875,1,1
1630 | 0.453125,0.796875,1,1
1631 | 0.484375,0.796875,1,1
1632 | 0.484375,0.796875,1,1
1633 | 0.515625,0.796875,1,1
1634 | 0.515625,0.796875,1,1
1635 | 0.546875,0.796875,1,1
1636 | 0.546875,0.796875,1,1
1637 | 0.578125,0.796875,1,1
1638 | 0.578125,0.796875,1,1
1639 | 0.609375,0.796875,1,1
1640 | 0.609375,0.796875,1,1
1641 | 0.640625,0.796875,1,1
1642 | 0.640625,0.796875,1,1
1643 | 0.671875,0.796875,1,1
1644 | 0.671875,0.796875,1,1
1645 | 0.703125,0.796875,1,1
1646 | 0.703125,0.796875,1,1
1647 | 0.734375,0.796875,1,1
1648 | 0.734375,0.796875,1,1
1649 | 0.765625,0.796875,1,1
1650 | 0.765625,0.796875,1,1
1651 | 0.796875,0.796875,1,1
1652 | 0.796875,0.796875,1,1
1653 | 0.828125,0.796875,1,1
1654 | 0.828125,0.796875,1,1
1655 | 0.859375,0.796875,1,1
1656 | 0.859375,0.796875,1,1
1657 | 0.890625,0.796875,1,1
1658 | 0.890625,0.796875,1,1
1659 | 0.921875,0.796875,1,1
1660 | 0.921875,0.796875,1,1
1661 | 0.953125,0.796875,1,1
1662 | 0.953125,0.796875,1,1
1663 | 0.984375,0.796875,1,1
1664 | 0.984375,0.796875,1,1
1665 | 0.015625,0.828125,1,1
1666 | 0.015625,0.828125,1,1
1667 | 0.046875,0.828125,1,1
1668 | 0.046875,0.828125,1,1
1669 | 0.078125,0.828125,1,1
1670 | 0.078125,0.828125,1,1
1671 | 0.109375,0.828125,1,1
1672 | 0.109375,0.828125,1,1
1673 | 0.140625,0.828125,1,1
1674 | 0.140625,0.828125,1,1
1675 | 0.171875,0.828125,1,1
1676 | 0.171875,0.828125,1,1
1677 | 0.203125,0.828125,1,1
1678 | 0.203125,0.828125,1,1
1679 | 0.234375,0.828125,1,1
1680 | 0.234375,0.828125,1,1
1681 | 0.265625,0.828125,1,1
1682 | 0.265625,0.828125,1,1
1683 | 0.296875,0.828125,1,1
1684 | 0.296875,0.828125,1,1
1685 | 0.328125,0.828125,1,1
1686 | 0.328125,0.828125,1,1
1687 | 0.359375,0.828125,1,1
1688 | 0.359375,0.828125,1,1
1689 | 0.390625,0.828125,1,1
1690 | 0.390625,0.828125,1,1
1691 | 0.421875,0.828125,1,1
1692 | 0.421875,0.828125,1,1
1693 | 0.453125,0.828125,1,1
1694 | 0.453125,0.828125,1,1
1695 | 0.484375,0.828125,1,1
1696 | 0.484375,0.828125,1,1
1697 | 0.515625,0.828125,1,1
1698 | 0.515625,0.828125,1,1
1699 | 0.546875,0.828125,1,1
1700 | 0.546875,0.828125,1,1
1701 | 0.578125,0.828125,1,1
1702 | 0.578125,0.828125,1,1
1703 | 0.609375,0.828125,1,1
1704 | 0.609375,0.828125,1,1
1705 | 0.640625,0.828125,1,1
1706 | 0.640625,0.828125,1,1
1707 | 0.671875,0.828125,1,1
1708 | 0.671875,0.828125,1,1
1709 | 0.703125,0.828125,1,1
1710 | 0.703125,0.828125,1,1
1711 | 0.734375,0.828125,1,1
1712 | 0.734375,0.828125,1,1
1713 | 0.765625,0.828125,1,1
1714 | 0.765625,0.828125,1,1
1715 | 0.796875,0.828125,1,1
1716 | 0.796875,0.828125,1,1
1717 | 0.828125,0.828125,1,1
1718 | 0.828125,0.828125,1,1
1719 | 0.859375,0.828125,1,1
1720 | 0.859375,0.828125,1,1
1721 | 0.890625,0.828125,1,1
1722 | 0.890625,0.828125,1,1
1723 | 0.921875,0.828125,1,1
1724 | 0.921875,0.828125,1,1
1725 | 0.953125,0.828125,1,1
1726 | 0.953125,0.828125,1,1
1727 | 0.984375,0.828125,1,1
1728 | 0.984375,0.828125,1,1
1729 | 0.015625,0.859375,1,1
1730 | 0.015625,0.859375,1,1
1731 | 0.046875,0.859375,1,1
1732 | 0.046875,0.859375,1,1
1733 | 0.078125,0.859375,1,1
1734 | 0.078125,0.859375,1,1
1735 | 0.109375,0.859375,1,1
1736 | 0.109375,0.859375,1,1
1737 | 0.140625,0.859375,1,1
1738 | 0.140625,0.859375,1,1
1739 | 0.171875,0.859375,1,1
1740 | 0.171875,0.859375,1,1
1741 | 0.203125,0.859375,1,1
1742 | 0.203125,0.859375,1,1
1743 | 0.234375,0.859375,1,1
1744 | 0.234375,0.859375,1,1
1745 | 0.265625,0.859375,1,1
1746 | 0.265625,0.859375,1,1
1747 | 0.296875,0.859375,1,1
1748 | 0.296875,0.859375,1,1
1749 | 0.328125,0.859375,1,1
1750 | 0.328125,0.859375,1,1
1751 | 0.359375,0.859375,1,1
1752 | 0.359375,0.859375,1,1
1753 | 0.390625,0.859375,1,1
1754 | 0.390625,0.859375,1,1
1755 | 0.421875,0.859375,1,1
1756 | 0.421875,0.859375,1,1
1757 | 0.453125,0.859375,1,1
1758 | 0.453125,0.859375,1,1
1759 | 0.484375,0.859375,1,1
1760 | 0.484375,0.859375,1,1
1761 | 0.515625,0.859375,1,1
1762 | 0.515625,0.859375,1,1
1763 | 0.546875,0.859375,1,1
1764 | 0.546875,0.859375,1,1
1765 | 0.578125,0.859375,1,1
1766 | 0.578125,0.859375,1,1
1767 | 0.609375,0.859375,1,1
1768 | 0.609375,0.859375,1,1
1769 | 0.640625,0.859375,1,1
1770 | 0.640625,0.859375,1,1
1771 | 0.671875,0.859375,1,1
1772 | 0.671875,0.859375,1,1
1773 | 0.703125,0.859375,1,1
1774 | 0.703125,0.859375,1,1
1775 | 0.734375,0.859375,1,1
1776 | 0.734375,0.859375,1,1
1777 | 0.765625,0.859375,1,1
1778 | 0.765625,0.859375,1,1
1779 | 0.796875,0.859375,1,1
1780 | 0.796875,0.859375,1,1
1781 | 0.828125,0.859375,1,1
1782 | 0.828125,0.859375,1,1
1783 | 0.859375,0.859375,1,1
1784 | 0.859375,0.859375,1,1
1785 | 0.890625,0.859375,1,1
1786 | 0.890625,0.859375,1,1
1787 | 0.921875,0.859375,1,1
1788 | 0.921875,0.859375,1,1
1789 | 0.953125,0.859375,1,1
1790 | 0.953125,0.859375,1,1
1791 | 0.984375,0.859375,1,1
1792 | 0.984375,0.859375,1,1
1793 | 0.015625,0.890625,1,1
1794 | 0.015625,0.890625,1,1
1795 | 0.046875,0.890625,1,1
1796 | 0.046875,0.890625,1,1
1797 | 0.078125,0.890625,1,1
1798 | 0.078125,0.890625,1,1
1799 | 0.109375,0.890625,1,1
1800 | 0.109375,0.890625,1,1
1801 | 0.140625,0.890625,1,1
1802 | 0.140625,0.890625,1,1
1803 | 0.171875,0.890625,1,1
1804 | 0.171875,0.890625,1,1
1805 | 0.203125,0.890625,1,1
1806 | 0.203125,0.890625,1,1
1807 | 0.234375,0.890625,1,1
1808 | 0.234375,0.890625,1,1
1809 | 0.265625,0.890625,1,1
1810 | 0.265625,0.890625,1,1
1811 | 0.296875,0.890625,1,1
1812 | 0.296875,0.890625,1,1
1813 | 0.328125,0.890625,1,1
1814 | 0.328125,0.890625,1,1
1815 | 0.359375,0.890625,1,1
1816 | 0.359375,0.890625,1,1
1817 | 0.390625,0.890625,1,1
1818 | 0.390625,0.890625,1,1
1819 | 0.421875,0.890625,1,1
1820 | 0.421875,0.890625,1,1
1821 | 0.453125,0.890625,1,1
1822 | 0.453125,0.890625,1,1
1823 | 0.484375,0.890625,1,1
1824 | 0.484375,0.890625,1,1
1825 | 0.515625,0.890625,1,1
1826 | 0.515625,0.890625,1,1
1827 | 0.546875,0.890625,1,1
1828 | 0.546875,0.890625,1,1
1829 | 0.578125,0.890625,1,1
1830 | 0.578125,0.890625,1,1
1831 | 0.609375,0.890625,1,1
1832 | 0.609375,0.890625,1,1
1833 | 0.640625,0.890625,1,1
1834 | 0.640625,0.890625,1,1
1835 | 0.671875,0.890625,1,1
1836 | 0.671875,0.890625,1,1
1837 | 0.703125,0.890625,1,1
1838 | 0.703125,0.890625,1,1
1839 | 0.734375,0.890625,1,1
1840 | 0.734375,0.890625,1,1
1841 | 0.765625,0.890625,1,1
1842 | 0.765625,0.890625,1,1
1843 | 0.796875,0.890625,1,1
1844 | 0.796875,0.890625,1,1
1845 | 0.828125,0.890625,1,1
1846 | 0.828125,0.890625,1,1
1847 | 0.859375,0.890625,1,1
1848 | 0.859375,0.890625,1,1
1849 | 0.890625,0.890625,1,1
1850 | 0.890625,0.890625,1,1
1851 | 0.921875,0.890625,1,1
1852 | 0.921875,0.890625,1,1
1853 | 0.953125,0.890625,1,1
1854 | 0.953125,0.890625,1,1
1855 | 0.984375,0.890625,1,1
1856 | 0.984375,0.890625,1,1
1857 | 0.015625,0.921875,1,1
1858 | 0.015625,0.921875,1,1
1859 | 0.046875,0.921875,1,1
1860 | 0.046875,0.921875,1,1
1861 | 0.078125,0.921875,1,1
1862 | 0.078125,0.921875,1,1
1863 | 0.109375,0.921875,1,1
1864 | 0.109375,0.921875,1,1
1865 | 0.140625,0.921875,1,1
1866 | 0.140625,0.921875,1,1
1867 | 0.171875,0.921875,1,1
1868 | 0.171875,0.921875,1,1
1869 | 0.203125,0.921875,1,1
1870 | 0.203125,0.921875,1,1
1871 | 0.234375,0.921875,1,1
1872 | 0.234375,0.921875,1,1
1873 | 0.265625,0.921875,1,1
1874 | 0.265625,0.921875,1,1
1875 | 0.296875,0.921875,1,1
1876 | 0.296875,0.921875,1,1
1877 | 0.328125,0.921875,1,1
1878 | 0.328125,0.921875,1,1
1879 | 0.359375,0.921875,1,1
1880 | 0.359375,0.921875,1,1
1881 | 0.390625,0.921875,1,1
1882 | 0.390625,0.921875,1,1
1883 | 0.421875,0.921875,1,1
1884 | 0.421875,0.921875,1,1
1885 | 0.453125,0.921875,1,1
1886 | 0.453125,0.921875,1,1
1887 | 0.484375,0.921875,1,1
1888 | 0.484375,0.921875,1,1
1889 | 0.515625,0.921875,1,1
1890 | 0.515625,0.921875,1,1
1891 | 0.546875,0.921875,1,1
1892 | 0.546875,0.921875,1,1
1893 | 0.578125,0.921875,1,1
1894 | 0.578125,0.921875,1,1
1895 | 0.609375,0.921875,1,1
1896 | 0.609375,0.921875,1,1
1897 | 0.640625,0.921875,1,1
1898 | 0.640625,0.921875,1,1
1899 | 0.671875,0.921875,1,1
1900 | 0.671875,0.921875,1,1
1901 | 0.703125,0.921875,1,1
1902 | 0.703125,0.921875,1,1
1903 | 0.734375,0.921875,1,1
1904 | 0.734375,0.921875,1,1
1905 | 0.765625,0.921875,1,1
1906 | 0.765625,0.921875,1,1
1907 | 0.796875,0.921875,1,1
1908 | 0.796875,0.921875,1,1
1909 | 0.828125,0.921875,1,1
1910 | 0.828125,0.921875,1,1
1911 | 0.859375,0.921875,1,1
1912 | 0.859375,0.921875,1,1
1913 | 0.890625,0.921875,1,1
1914 | 0.890625,0.921875,1,1
1915 | 0.921875,0.921875,1,1
1916 | 0.921875,0.921875,1,1
1917 | 0.953125,0.921875,1,1
1918 | 0.953125,0.921875,1,1
1919 | 0.984375,0.921875,1,1
1920 | 0.984375,0.921875,1,1
1921 | 0.015625,0.953125,1,1
1922 | 0.015625,0.953125,1,1
1923 | 0.046875,0.953125,1,1
1924 | 0.046875,0.953125,1,1
1925 | 0.078125,0.953125,1,1
1926 | 0.078125,0.953125,1,1
1927 | 0.109375,0.953125,1,1
1928 | 0.109375,0.953125,1,1
1929 | 0.140625,0.953125,1,1
1930 | 0.140625,0.953125,1,1
1931 | 0.171875,0.953125,1,1
1932 | 0.171875,0.953125,1,1
1933 | 0.203125,0.953125,1,1
1934 | 0.203125,0.953125,1,1
1935 | 0.234375,0.953125,1,1
1936 | 0.234375,0.953125,1,1
1937 | 0.265625,0.953125,1,1
1938 | 0.265625,0.953125,1,1
1939 | 0.296875,0.953125,1,1
1940 | 0.296875,0.953125,1,1
1941 | 0.328125,0.953125,1,1
1942 | 0.328125,0.953125,1,1
1943 | 0.359375,0.953125,1,1
1944 | 0.359375,0.953125,1,1
1945 | 0.390625,0.953125,1,1
1946 | 0.390625,0.953125,1,1
1947 | 0.421875,0.953125,1,1
1948 | 0.421875,0.953125,1,1
1949 | 0.453125,0.953125,1,1
1950 | 0.453125,0.953125,1,1
1951 | 0.484375,0.953125,1,1
1952 | 0.484375,0.953125,1,1
1953 | 0.515625,0.953125,1,1
1954 | 0.515625,0.953125,1,1
1955 | 0.546875,0.953125,1,1
1956 | 0.546875,0.953125,1,1
1957 | 0.578125,0.953125,1,1
1958 | 0.578125,0.953125,1,1
1959 | 0.609375,0.953125,1,1
1960 | 0.609375,0.953125,1,1
1961 | 0.640625,0.953125,1,1
1962 | 0.640625,0.953125,1,1
1963 | 0.671875,0.953125,1,1
1964 | 0.671875,0.953125,1,1
1965 | 0.703125,0.953125,1,1
1966 | 0.703125,0.953125,1,1
1967 | 0.734375,0.953125,1,1
1968 | 0.734375,0.953125,1,1
1969 | 0.765625,0.953125,1,1
1970 | 0.765625,0.953125,1,1
1971 | 0.796875,0.953125,1,1
1972 | 0.796875,0.953125,1,1
1973 | 0.828125,0.953125,1,1
1974 | 0.828125,0.953125,1,1
1975 | 0.859375,0.953125,1,1
1976 | 0.859375,0.953125,1,1
1977 | 0.890625,0.953125,1,1
1978 | 0.890625,0.953125,1,1
1979 | 0.921875,0.953125,1,1
1980 | 0.921875,0.953125,1,1
1981 | 0.953125,0.953125,1,1
1982 | 0.953125,0.953125,1,1
1983 | 0.984375,0.953125,1,1
1984 | 0.984375,0.953125,1,1
1985 | 0.015625,0.984375,1,1
1986 | 0.015625,0.984375,1,1
1987 | 0.046875,0.984375,1,1
1988 | 0.046875,0.984375,1,1
1989 | 0.078125,0.984375,1,1
1990 | 0.078125,0.984375,1,1
1991 | 0.109375,0.984375,1,1
1992 | 0.109375,0.984375,1,1
1993 | 0.140625,0.984375,1,1
1994 | 0.140625,0.984375,1,1
1995 | 0.171875,0.984375,1,1
1996 | 0.171875,0.984375,1,1
1997 | 0.203125,0.984375,1,1
1998 | 0.203125,0.984375,1,1
1999 | 0.234375,0.984375,1,1
2000 | 0.234375,0.984375,1,1
2001 | 0.265625,0.984375,1,1
2002 | 0.265625,0.984375,1,1
2003 | 0.296875,0.984375,1,1
2004 | 0.296875,0.984375,1,1
2005 | 0.328125,0.984375,1,1
2006 | 0.328125,0.984375,1,1
2007 | 0.359375,0.984375,1,1
2008 | 0.359375,0.984375,1,1
2009 | 0.390625,0.984375,1,1
2010 | 0.390625,0.984375,1,1
2011 | 0.421875,0.984375,1,1
2012 | 0.421875,0.984375,1,1
2013 | 0.453125,0.984375,1,1
2014 | 0.453125,0.984375,1,1
2015 | 0.484375,0.984375,1,1
2016 | 0.484375,0.984375,1,1
2017 | 0.515625,0.984375,1,1
2018 | 0.515625,0.984375,1,1
2019 | 0.546875,0.984375,1,1
2020 | 0.546875,0.984375,1,1
2021 | 0.578125,0.984375,1,1
2022 | 0.578125,0.984375,1,1
2023 | 0.609375,0.984375,1,1
2024 | 0.609375,0.984375,1,1
2025 | 0.640625,0.984375,1,1
2026 | 0.640625,0.984375,1,1
2027 | 0.671875,0.984375,1,1
2028 | 0.671875,0.984375,1,1
2029 | 0.703125,0.984375,1,1
2030 | 0.703125,0.984375,1,1
2031 | 0.734375,0.984375,1,1
2032 | 0.734375,0.984375,1,1
2033 | 0.765625,0.984375,1,1
2034 | 0.765625,0.984375,1,1
2035 | 0.796875,0.984375,1,1
2036 | 0.796875,0.984375,1,1
2037 | 0.828125,0.984375,1,1
2038 | 0.828125,0.984375,1,1
2039 | 0.859375,0.984375,1,1
2040 | 0.859375,0.984375,1,1
2041 | 0.890625,0.984375,1,1
2042 | 0.890625,0.984375,1,1
2043 | 0.921875,0.984375,1,1
2044 | 0.921875,0.984375,1,1
2045 | 0.953125,0.984375,1,1
2046 | 0.953125,0.984375,1,1
2047 | 0.984375,0.984375,1,1
2048 | 0.984375,0.984375,1,1
2049 | 0.03125,0.03125,1,1
2050 | 0.03125,0.03125,1,1
2051 | 0.09375,0.03125,1,1
2052 | 0.09375,0.03125,1,1
2053 | 0.15625,0.03125,1,1
2054 | 0.15625,0.03125,1,1
2055 | 0.21875,0.03125,1,1
2056 | 0.21875,0.03125,1,1
2057 | 0.28125,0.03125,1,1
2058 | 0.28125,0.03125,1,1
2059 | 0.34375,0.03125,1,1
2060 | 0.34375,0.03125,1,1
2061 | 0.40625,0.03125,1,1
2062 | 0.40625,0.03125,1,1
2063 | 0.46875,0.03125,1,1
2064 | 0.46875,0.03125,1,1
2065 | 0.53125,0.03125,1,1
2066 | 0.53125,0.03125,1,1
2067 | 0.59375,0.03125,1,1
2068 | 0.59375,0.03125,1,1
2069 | 0.65625,0.03125,1,1
2070 | 0.65625,0.03125,1,1
2071 | 0.71875,0.03125,1,1
2072 | 0.71875,0.03125,1,1
2073 | 0.78125,0.03125,1,1
2074 | 0.78125,0.03125,1,1
2075 | 0.84375,0.03125,1,1
2076 | 0.84375,0.03125,1,1
2077 | 0.90625,0.03125,1,1
2078 | 0.90625,0.03125,1,1
2079 | 0.96875,0.03125,1,1
2080 | 0.96875,0.03125,1,1
2081 | 0.03125,0.09375,1,1
2082 | 0.03125,0.09375,1,1
2083 | 0.09375,0.09375,1,1
2084 | 0.09375,0.09375,1,1
2085 | 0.15625,0.09375,1,1
2086 | 0.15625,0.09375,1,1
2087 | 0.21875,0.09375,1,1
2088 | 0.21875,0.09375,1,1
2089 | 0.28125,0.09375,1,1
2090 | 0.28125,0.09375,1,1
2091 | 0.34375,0.09375,1,1
2092 | 0.34375,0.09375,1,1
2093 | 0.40625,0.09375,1,1
2094 | 0.40625,0.09375,1,1
2095 | 0.46875,0.09375,1,1
2096 | 0.46875,0.09375,1,1
2097 | 0.53125,0.09375,1,1
2098 | 0.53125,0.09375,1,1
2099 | 0.59375,0.09375,1,1
2100 | 0.59375,0.09375,1,1
2101 | 0.65625,0.09375,1,1
2102 | 0.65625,0.09375,1,1
2103 | 0.71875,0.09375,1,1
2104 | 0.71875,0.09375,1,1
2105 | 0.78125,0.09375,1,1
2106 | 0.78125,0.09375,1,1
2107 | 0.84375,0.09375,1,1
2108 | 0.84375,0.09375,1,1
2109 | 0.90625,0.09375,1,1
2110 | 0.90625,0.09375,1,1
2111 | 0.96875,0.09375,1,1
2112 | 0.96875,0.09375,1,1
2113 | 0.03125,0.15625,1,1
2114 | 0.03125,0.15625,1,1
2115 | 0.09375,0.15625,1,1
2116 | 0.09375,0.15625,1,1
2117 | 0.15625,0.15625,1,1
2118 | 0.15625,0.15625,1,1
2119 | 0.21875,0.15625,1,1
2120 | 0.21875,0.15625,1,1
2121 | 0.28125,0.15625,1,1
2122 | 0.28125,0.15625,1,1
2123 | 0.34375,0.15625,1,1
2124 | 0.34375,0.15625,1,1
2125 | 0.40625,0.15625,1,1
2126 | 0.40625,0.15625,1,1
2127 | 0.46875,0.15625,1,1
2128 | 0.46875,0.15625,1,1
2129 | 0.53125,0.15625,1,1
2130 | 0.53125,0.15625,1,1
2131 | 0.59375,0.15625,1,1
2132 | 0.59375,0.15625,1,1
2133 | 0.65625,0.15625,1,1
2134 | 0.65625,0.15625,1,1
2135 | 0.71875,0.15625,1,1
2136 | 0.71875,0.15625,1,1
2137 | 0.78125,0.15625,1,1
2138 | 0.78125,0.15625,1,1
2139 | 0.84375,0.15625,1,1
2140 | 0.84375,0.15625,1,1
2141 | 0.90625,0.15625,1,1
2142 | 0.90625,0.15625,1,1
2143 | 0.96875,0.15625,1,1
2144 | 0.96875,0.15625,1,1
2145 | 0.03125,0.21875,1,1
2146 | 0.03125,0.21875,1,1
2147 | 0.09375,0.21875,1,1
2148 | 0.09375,0.21875,1,1
2149 | 0.15625,0.21875,1,1
2150 | 0.15625,0.21875,1,1
2151 | 0.21875,0.21875,1,1
2152 | 0.21875,0.21875,1,1
2153 | 0.28125,0.21875,1,1
2154 | 0.28125,0.21875,1,1
2155 | 0.34375,0.21875,1,1
2156 | 0.34375,0.21875,1,1
2157 | 0.40625,0.21875,1,1
2158 | 0.40625,0.21875,1,1
2159 | 0.46875,0.21875,1,1
2160 | 0.46875,0.21875,1,1
2161 | 0.53125,0.21875,1,1
2162 | 0.53125,0.21875,1,1
2163 | 0.59375,0.21875,1,1
2164 | 0.59375,0.21875,1,1
2165 | 0.65625,0.21875,1,1
2166 | 0.65625,0.21875,1,1
2167 | 0.71875,0.21875,1,1
2168 | 0.71875,0.21875,1,1
2169 | 0.78125,0.21875,1,1
2170 | 0.78125,0.21875,1,1
2171 | 0.84375,0.21875,1,1
2172 | 0.84375,0.21875,1,1
2173 | 0.90625,0.21875,1,1
2174 | 0.90625,0.21875,1,1
2175 | 0.96875,0.21875,1,1
2176 | 0.96875,0.21875,1,1
2177 | 0.03125,0.28125,1,1
2178 | 0.03125,0.28125,1,1
2179 | 0.09375,0.28125,1,1
2180 | 0.09375,0.28125,1,1
2181 | 0.15625,0.28125,1,1
2182 | 0.15625,0.28125,1,1
2183 | 0.21875,0.28125,1,1
2184 | 0.21875,0.28125,1,1
2185 | 0.28125,0.28125,1,1
2186 | 0.28125,0.28125,1,1
2187 | 0.34375,0.28125,1,1
2188 | 0.34375,0.28125,1,1
2189 | 0.40625,0.28125,1,1
2190 | 0.40625,0.28125,1,1
2191 | 0.46875,0.28125,1,1
2192 | 0.46875,0.28125,1,1
2193 | 0.53125,0.28125,1,1
2194 | 0.53125,0.28125,1,1
2195 | 0.59375,0.28125,1,1
2196 | 0.59375,0.28125,1,1
2197 | 0.65625,0.28125,1,1
2198 | 0.65625,0.28125,1,1
2199 | 0.71875,0.28125,1,1
2200 | 0.71875,0.28125,1,1
2201 | 0.78125,0.28125,1,1
2202 | 0.78125,0.28125,1,1
2203 | 0.84375,0.28125,1,1
2204 | 0.84375,0.28125,1,1
2205 | 0.90625,0.28125,1,1
2206 | 0.90625,0.28125,1,1
2207 | 0.96875,0.28125,1,1
2208 | 0.96875,0.28125,1,1
2209 | 0.03125,0.34375,1,1
2210 | 0.03125,0.34375,1,1
2211 | 0.09375,0.34375,1,1
2212 | 0.09375,0.34375,1,1
2213 | 0.15625,0.34375,1,1
2214 | 0.15625,0.34375,1,1
2215 | 0.21875,0.34375,1,1
2216 | 0.21875,0.34375,1,1
2217 | 0.28125,0.34375,1,1
2218 | 0.28125,0.34375,1,1
2219 | 0.34375,0.34375,1,1
2220 | 0.34375,0.34375,1,1
2221 | 0.40625,0.34375,1,1
2222 | 0.40625,0.34375,1,1
2223 | 0.46875,0.34375,1,1
2224 | 0.46875,0.34375,1,1
2225 | 0.53125,0.34375,1,1
2226 | 0.53125,0.34375,1,1
2227 | 0.59375,0.34375,1,1
2228 | 0.59375,0.34375,1,1
2229 | 0.65625,0.34375,1,1
2230 | 0.65625,0.34375,1,1
2231 | 0.71875,0.34375,1,1
2232 | 0.71875,0.34375,1,1
2233 | 0.78125,0.34375,1,1
2234 | 0.78125,0.34375,1,1
2235 | 0.84375,0.34375,1,1
2236 | 0.84375,0.34375,1,1
2237 | 0.90625,0.34375,1,1
2238 | 0.90625,0.34375,1,1
2239 | 0.96875,0.34375,1,1
2240 | 0.96875,0.34375,1,1
2241 | 0.03125,0.40625,1,1
2242 | 0.03125,0.40625,1,1
2243 | 0.09375,0.40625,1,1
2244 | 0.09375,0.40625,1,1
2245 | 0.15625,0.40625,1,1
2246 | 0.15625,0.40625,1,1
2247 | 0.21875,0.40625,1,1
2248 | 0.21875,0.40625,1,1
2249 | 0.28125,0.40625,1,1
2250 | 0.28125,0.40625,1,1
2251 | 0.34375,0.40625,1,1
2252 | 0.34375,0.40625,1,1
2253 | 0.40625,0.40625,1,1
2254 | 0.40625,0.40625,1,1
2255 | 0.46875,0.40625,1,1
2256 | 0.46875,0.40625,1,1
2257 | 0.53125,0.40625,1,1
2258 | 0.53125,0.40625,1,1
2259 | 0.59375,0.40625,1,1
2260 | 0.59375,0.40625,1,1
2261 | 0.65625,0.40625,1,1
2262 | 0.65625,0.40625,1,1
2263 | 0.71875,0.40625,1,1
2264 | 0.71875,0.40625,1,1
2265 | 0.78125,0.40625,1,1
2266 | 0.78125,0.40625,1,1
2267 | 0.84375,0.40625,1,1
2268 | 0.84375,0.40625,1,1
2269 | 0.90625,0.40625,1,1
2270 | 0.90625,0.40625,1,1
2271 | 0.96875,0.40625,1,1
2272 | 0.96875,0.40625,1,1
2273 | 0.03125,0.46875,1,1
2274 | 0.03125,0.46875,1,1
2275 | 0.09375,0.46875,1,1
2276 | 0.09375,0.46875,1,1
2277 | 0.15625,0.46875,1,1
2278 | 0.15625,0.46875,1,1
2279 | 0.21875,0.46875,1,1
2280 | 0.21875,0.46875,1,1
2281 | 0.28125,0.46875,1,1
2282 | 0.28125,0.46875,1,1
2283 | 0.34375,0.46875,1,1
2284 | 0.34375,0.46875,1,1
2285 | 0.40625,0.46875,1,1
2286 | 0.40625,0.46875,1,1
2287 | 0.46875,0.46875,1,1
2288 | 0.46875,0.46875,1,1
2289 | 0.53125,0.46875,1,1
2290 | 0.53125,0.46875,1,1
2291 | 0.59375,0.46875,1,1
2292 | 0.59375,0.46875,1,1
2293 | 0.65625,0.46875,1,1
2294 | 0.65625,0.46875,1,1
2295 | 0.71875,0.46875,1,1
2296 | 0.71875,0.46875,1,1
2297 | 0.78125,0.46875,1,1
2298 | 0.78125,0.46875,1,1
2299 | 0.84375,0.46875,1,1
2300 | 0.84375,0.46875,1,1
2301 | 0.90625,0.46875,1,1
2302 | 0.90625,0.46875,1,1
2303 | 0.96875,0.46875,1,1
2304 | 0.96875,0.46875,1,1
2305 | 0.03125,0.53125,1,1
2306 | 0.03125,0.53125,1,1
2307 | 0.09375,0.53125,1,1
2308 | 0.09375,0.53125,1,1
2309 | 0.15625,0.53125,1,1
2310 | 0.15625,0.53125,1,1
2311 | 0.21875,0.53125,1,1
2312 | 0.21875,0.53125,1,1
2313 | 0.28125,0.53125,1,1
2314 | 0.28125,0.53125,1,1
2315 | 0.34375,0.53125,1,1
2316 | 0.34375,0.53125,1,1
2317 | 0.40625,0.53125,1,1
2318 | 0.40625,0.53125,1,1
2319 | 0.46875,0.53125,1,1
2320 | 0.46875,0.53125,1,1
2321 | 0.53125,0.53125,1,1
2322 | 0.53125,0.53125,1,1
2323 | 0.59375,0.53125,1,1
2324 | 0.59375,0.53125,1,1
2325 | 0.65625,0.53125,1,1
2326 | 0.65625,0.53125,1,1
2327 | 0.71875,0.53125,1,1
2328 | 0.71875,0.53125,1,1
2329 | 0.78125,0.53125,1,1
2330 | 0.78125,0.53125,1,1
2331 | 0.84375,0.53125,1,1
2332 | 0.84375,0.53125,1,1
2333 | 0.90625,0.53125,1,1
2334 | 0.90625,0.53125,1,1
2335 | 0.96875,0.53125,1,1
2336 | 0.96875,0.53125,1,1
2337 | 0.03125,0.59375,1,1
2338 | 0.03125,0.59375,1,1
2339 | 0.09375,0.59375,1,1
2340 | 0.09375,0.59375,1,1
2341 | 0.15625,0.59375,1,1
2342 | 0.15625,0.59375,1,1
2343 | 0.21875,0.59375,1,1
2344 | 0.21875,0.59375,1,1
2345 | 0.28125,0.59375,1,1
2346 | 0.28125,0.59375,1,1
2347 | 0.34375,0.59375,1,1
2348 | 0.34375,0.59375,1,1
2349 | 0.40625,0.59375,1,1
2350 | 0.40625,0.59375,1,1
2351 | 0.46875,0.59375,1,1
2352 | 0.46875,0.59375,1,1
2353 | 0.53125,0.59375,1,1
2354 | 0.53125,0.59375,1,1
2355 | 0.59375,0.59375,1,1
2356 | 0.59375,0.59375,1,1
2357 | 0.65625,0.59375,1,1
2358 | 0.65625,0.59375,1,1
2359 | 0.71875,0.59375,1,1
2360 | 0.71875,0.59375,1,1
2361 | 0.78125,0.59375,1,1
2362 | 0.78125,0.59375,1,1
2363 | 0.84375,0.59375,1,1
2364 | 0.84375,0.59375,1,1
2365 | 0.90625,0.59375,1,1
2366 | 0.90625,0.59375,1,1
2367 | 0.96875,0.59375,1,1
2368 | 0.96875,0.59375,1,1
2369 | 0.03125,0.65625,1,1
2370 | 0.03125,0.65625,1,1
2371 | 0.09375,0.65625,1,1
2372 | 0.09375,0.65625,1,1
2373 | 0.15625,0.65625,1,1
2374 | 0.15625,0.65625,1,1
2375 | 0.21875,0.65625,1,1
2376 | 0.21875,0.65625,1,1
2377 | 0.28125,0.65625,1,1
2378 | 0.28125,0.65625,1,1
2379 | 0.34375,0.65625,1,1
2380 | 0.34375,0.65625,1,1
2381 | 0.40625,0.65625,1,1
2382 | 0.40625,0.65625,1,1
2383 | 0.46875,0.65625,1,1
2384 | 0.46875,0.65625,1,1
2385 | 0.53125,0.65625,1,1
2386 | 0.53125,0.65625,1,1
2387 | 0.59375,0.65625,1,1
2388 | 0.59375,0.65625,1,1
2389 | 0.65625,0.65625,1,1
2390 | 0.65625,0.65625,1,1
2391 | 0.71875,0.65625,1,1
2392 | 0.71875,0.65625,1,1
2393 | 0.78125,0.65625,1,1
2394 | 0.78125,0.65625,1,1
2395 | 0.84375,0.65625,1,1
2396 | 0.84375,0.65625,1,1
2397 | 0.90625,0.65625,1,1
2398 | 0.90625,0.65625,1,1
2399 | 0.96875,0.65625,1,1
2400 | 0.96875,0.65625,1,1
2401 | 0.03125,0.71875,1,1
2402 | 0.03125,0.71875,1,1
2403 | 0.09375,0.71875,1,1
2404 | 0.09375,0.71875,1,1
2405 | 0.15625,0.71875,1,1
2406 | 0.15625,0.71875,1,1
2407 | 0.21875,0.71875,1,1
2408 | 0.21875,0.71875,1,1
2409 | 0.28125,0.71875,1,1
2410 | 0.28125,0.71875,1,1
2411 | 0.34375,0.71875,1,1
2412 | 0.34375,0.71875,1,1
2413 | 0.40625,0.71875,1,1
2414 | 0.40625,0.71875,1,1
2415 | 0.46875,0.71875,1,1
2416 | 0.46875,0.71875,1,1
2417 | 0.53125,0.71875,1,1
2418 | 0.53125,0.71875,1,1
2419 | 0.59375,0.71875,1,1
2420 | 0.59375,0.71875,1,1
2421 | 0.65625,0.71875,1,1
2422 | 0.65625,0.71875,1,1
2423 | 0.71875,0.71875,1,1
2424 | 0.71875,0.71875,1,1
2425 | 0.78125,0.71875,1,1
2426 | 0.78125,0.71875,1,1
2427 | 0.84375,0.71875,1,1
2428 | 0.84375,0.71875,1,1
2429 | 0.90625,0.71875,1,1
2430 | 0.90625,0.71875,1,1
2431 | 0.96875,0.71875,1,1
2432 | 0.96875,0.71875,1,1
2433 | 0.03125,0.78125,1,1
2434 | 0.03125,0.78125,1,1
2435 | 0.09375,0.78125,1,1
2436 | 0.09375,0.78125,1,1
2437 | 0.15625,0.78125,1,1
2438 | 0.15625,0.78125,1,1
2439 | 0.21875,0.78125,1,1
2440 | 0.21875,0.78125,1,1
2441 | 0.28125,0.78125,1,1
2442 | 0.28125,0.78125,1,1
2443 | 0.34375,0.78125,1,1
2444 | 0.34375,0.78125,1,1
2445 | 0.40625,0.78125,1,1
2446 | 0.40625,0.78125,1,1
2447 | 0.46875,0.78125,1,1
2448 | 0.46875,0.78125,1,1
2449 | 0.53125,0.78125,1,1
2450 | 0.53125,0.78125,1,1
2451 | 0.59375,0.78125,1,1
2452 | 0.59375,0.78125,1,1
2453 | 0.65625,0.78125,1,1
2454 | 0.65625,0.78125,1,1
2455 | 0.71875,0.78125,1,1
2456 | 0.71875,0.78125,1,1
2457 | 0.78125,0.78125,1,1
2458 | 0.78125,0.78125,1,1
2459 | 0.84375,0.78125,1,1
2460 | 0.84375,0.78125,1,1
2461 | 0.90625,0.78125,1,1
2462 | 0.90625,0.78125,1,1
2463 | 0.96875,0.78125,1,1
2464 | 0.96875,0.78125,1,1
2465 | 0.03125,0.84375,1,1
2466 | 0.03125,0.84375,1,1
2467 | 0.09375,0.84375,1,1
2468 | 0.09375,0.84375,1,1
2469 | 0.15625,0.84375,1,1
2470 | 0.15625,0.84375,1,1
2471 | 0.21875,0.84375,1,1
2472 | 0.21875,0.84375,1,1
2473 | 0.28125,0.84375,1,1
2474 | 0.28125,0.84375,1,1
2475 | 0.34375,0.84375,1,1
2476 | 0.34375,0.84375,1,1
2477 | 0.40625,0.84375,1,1
2478 | 0.40625,0.84375,1,1
2479 | 0.46875,0.84375,1,1
2480 | 0.46875,0.84375,1,1
2481 | 0.53125,0.84375,1,1
2482 | 0.53125,0.84375,1,1
2483 | 0.59375,0.84375,1,1
2484 | 0.59375,0.84375,1,1
2485 | 0.65625,0.84375,1,1
2486 | 0.65625,0.84375,1,1
2487 | 0.71875,0.84375,1,1
2488 | 0.71875,0.84375,1,1
2489 | 0.78125,0.84375,1,1
2490 | 0.78125,0.84375,1,1
2491 | 0.84375,0.84375,1,1
2492 | 0.84375,0.84375,1,1
2493 | 0.90625,0.84375,1,1
2494 | 0.90625,0.84375,1,1
2495 | 0.96875,0.84375,1,1
2496 | 0.96875,0.84375,1,1
2497 | 0.03125,0.90625,1,1
2498 | 0.03125,0.90625,1,1
2499 | 0.09375,0.90625,1,1
2500 | 0.09375,0.90625,1,1
2501 | 0.15625,0.90625,1,1
2502 | 0.15625,0.90625,1,1
2503 | 0.21875,0.90625,1,1
2504 | 0.21875,0.90625,1,1
2505 | 0.28125,0.90625,1,1
2506 | 0.28125,0.90625,1,1
2507 | 0.34375,0.90625,1,1
2508 | 0.34375,0.90625,1,1
2509 | 0.40625,0.90625,1,1
2510 | 0.40625,0.90625,1,1
2511 | 0.46875,0.90625,1,1
2512 | 0.46875,0.90625,1,1
2513 | 0.53125,0.90625,1,1
2514 | 0.53125,0.90625,1,1
2515 | 0.59375,0.90625,1,1
2516 | 0.59375,0.90625,1,1
2517 | 0.65625,0.90625,1,1
2518 | 0.65625,0.90625,1,1
2519 | 0.71875,0.90625,1,1
2520 | 0.71875,0.90625,1,1
2521 | 0.78125,0.90625,1,1
2522 | 0.78125,0.90625,1,1
2523 | 0.84375,0.90625,1,1
2524 | 0.84375,0.90625,1,1
2525 | 0.90625,0.90625,1,1
2526 | 0.90625,0.90625,1,1
2527 | 0.96875,0.90625,1,1
2528 | 0.96875,0.90625,1,1
2529 | 0.03125,0.96875,1,1
2530 | 0.03125,0.96875,1,1
2531 | 0.09375,0.96875,1,1
2532 | 0.09375,0.96875,1,1
2533 | 0.15625,0.96875,1,1
2534 | 0.15625,0.96875,1,1
2535 | 0.21875,0.96875,1,1
2536 | 0.21875,0.96875,1,1
2537 | 0.28125,0.96875,1,1
2538 | 0.28125,0.96875,1,1
2539 | 0.34375,0.96875,1,1
2540 | 0.34375,0.96875,1,1
2541 | 0.40625,0.96875,1,1
2542 | 0.40625,0.96875,1,1
2543 | 0.46875,0.96875,1,1
2544 | 0.46875,0.96875,1,1
2545 | 0.53125,0.96875,1,1
2546 | 0.53125,0.96875,1,1
2547 | 0.59375,0.96875,1,1
2548 | 0.59375,0.96875,1,1
2549 | 0.65625,0.96875,1,1
2550 | 0.65625,0.96875,1,1
2551 | 0.71875,0.96875,1,1
2552 | 0.71875,0.96875,1,1
2553 | 0.78125,0.96875,1,1
2554 | 0.78125,0.96875,1,1
2555 | 0.84375,0.96875,1,1
2556 | 0.84375,0.96875,1,1
2557 | 0.90625,0.96875,1,1
2558 | 0.90625,0.96875,1,1
2559 | 0.96875,0.96875,1,1
2560 | 0.96875,0.96875,1,1
2561 | 0.0625,0.0625,1,1
2562 | 0.0625,0.0625,1,1
2563 | 0.0625,0.0625,1,1
2564 | 0.0625,0.0625,1,1
2565 | 0.0625,0.0625,1,1
2566 | 0.0625,0.0625,1,1
2567 | 0.1875,0.0625,1,1
2568 | 0.1875,0.0625,1,1
2569 | 0.1875,0.0625,1,1
2570 | 0.1875,0.0625,1,1
2571 | 0.1875,0.0625,1,1
2572 | 0.1875,0.0625,1,1
2573 | 0.3125,0.0625,1,1
2574 | 0.3125,0.0625,1,1
2575 | 0.3125,0.0625,1,1
2576 | 0.3125,0.0625,1,1
2577 | 0.3125,0.0625,1,1
2578 | 0.3125,0.0625,1,1
2579 | 0.4375,0.0625,1,1
2580 | 0.4375,0.0625,1,1
2581 | 0.4375,0.0625,1,1
2582 | 0.4375,0.0625,1,1
2583 | 0.4375,0.0625,1,1
2584 | 0.4375,0.0625,1,1
2585 | 0.5625,0.0625,1,1
2586 | 0.5625,0.0625,1,1
2587 | 0.5625,0.0625,1,1
2588 | 0.5625,0.0625,1,1
2589 | 0.5625,0.0625,1,1
2590 | 0.5625,0.0625,1,1
2591 | 0.6875,0.0625,1,1
2592 | 0.6875,0.0625,1,1
2593 | 0.6875,0.0625,1,1
2594 | 0.6875,0.0625,1,1
2595 | 0.6875,0.0625,1,1
2596 | 0.6875,0.0625,1,1
2597 | 0.8125,0.0625,1,1
2598 | 0.8125,0.0625,1,1
2599 | 0.8125,0.0625,1,1
2600 | 0.8125,0.0625,1,1
2601 | 0.8125,0.0625,1,1
2602 | 0.8125,0.0625,1,1
2603 | 0.9375,0.0625,1,1
2604 | 0.9375,0.0625,1,1
2605 | 0.9375,0.0625,1,1
2606 | 0.9375,0.0625,1,1
2607 | 0.9375,0.0625,1,1
2608 | 0.9375,0.0625,1,1
2609 | 0.0625,0.1875,1,1
2610 | 0.0625,0.1875,1,1
2611 | 0.0625,0.1875,1,1
2612 | 0.0625,0.1875,1,1
2613 | 0.0625,0.1875,1,1
2614 | 0.0625,0.1875,1,1
2615 | 0.1875,0.1875,1,1
2616 | 0.1875,0.1875,1,1
2617 | 0.1875,0.1875,1,1
2618 | 0.1875,0.1875,1,1
2619 | 0.1875,0.1875,1,1
2620 | 0.1875,0.1875,1,1
2621 | 0.3125,0.1875,1,1
2622 | 0.3125,0.1875,1,1
2623 | 0.3125,0.1875,1,1
2624 | 0.3125,0.1875,1,1
2625 | 0.3125,0.1875,1,1
2626 | 0.3125,0.1875,1,1
2627 | 0.4375,0.1875,1,1
2628 | 0.4375,0.1875,1,1
2629 | 0.4375,0.1875,1,1
2630 | 0.4375,0.1875,1,1
2631 | 0.4375,0.1875,1,1
2632 | 0.4375,0.1875,1,1
2633 | 0.5625,0.1875,1,1
2634 | 0.5625,0.1875,1,1
2635 | 0.5625,0.1875,1,1
2636 | 0.5625,0.1875,1,1
2637 | 0.5625,0.1875,1,1
2638 | 0.5625,0.1875,1,1
2639 | 0.6875,0.1875,1,1
2640 | 0.6875,0.1875,1,1
2641 | 0.6875,0.1875,1,1
2642 | 0.6875,0.1875,1,1
2643 | 0.6875,0.1875,1,1
2644 | 0.6875,0.1875,1,1
2645 | 0.8125,0.1875,1,1
2646 | 0.8125,0.1875,1,1
2647 | 0.8125,0.1875,1,1
2648 | 0.8125,0.1875,1,1
2649 | 0.8125,0.1875,1,1
2650 | 0.8125,0.1875,1,1
2651 | 0.9375,0.1875,1,1
2652 | 0.9375,0.1875,1,1
2653 | 0.9375,0.1875,1,1
2654 | 0.9375,0.1875,1,1
2655 | 0.9375,0.1875,1,1
2656 | 0.9375,0.1875,1,1
2657 | 0.0625,0.3125,1,1
2658 | 0.0625,0.3125,1,1
2659 | 0.0625,0.3125,1,1
2660 | 0.0625,0.3125,1,1
2661 | 0.0625,0.3125,1,1
2662 | 0.0625,0.3125,1,1
2663 | 0.1875,0.3125,1,1
2664 | 0.1875,0.3125,1,1
2665 | 0.1875,0.3125,1,1
2666 | 0.1875,0.3125,1,1
2667 | 0.1875,0.3125,1,1
2668 | 0.1875,0.3125,1,1
2669 | 0.3125,0.3125,1,1
2670 | 0.3125,0.3125,1,1
2671 | 0.3125,0.3125,1,1
2672 | 0.3125,0.3125,1,1
2673 | 0.3125,0.3125,1,1
2674 | 0.3125,0.3125,1,1
2675 | 0.4375,0.3125,1,1
2676 | 0.4375,0.3125,1,1
2677 | 0.4375,0.3125,1,1
2678 | 0.4375,0.3125,1,1
2679 | 0.4375,0.3125,1,1
2680 | 0.4375,0.3125,1,1
2681 | 0.5625,0.3125,1,1
2682 | 0.5625,0.3125,1,1
2683 | 0.5625,0.3125,1,1
2684 | 0.5625,0.3125,1,1
2685 | 0.5625,0.3125,1,1
2686 | 0.5625,0.3125,1,1
2687 | 0.6875,0.3125,1,1
2688 | 0.6875,0.3125,1,1
2689 | 0.6875,0.3125,1,1
2690 | 0.6875,0.3125,1,1
2691 | 0.6875,0.3125,1,1
2692 | 0.6875,0.3125,1,1
2693 | 0.8125,0.3125,1,1
2694 | 0.8125,0.3125,1,1
2695 | 0.8125,0.3125,1,1
2696 | 0.8125,0.3125,1,1
2697 | 0.8125,0.3125,1,1
2698 | 0.8125,0.3125,1,1
2699 | 0.9375,0.3125,1,1
2700 | 0.9375,0.3125,1,1
2701 | 0.9375,0.3125,1,1
2702 | 0.9375,0.3125,1,1
2703 | 0.9375,0.3125,1,1
2704 | 0.9375,0.3125,1,1
2705 | 0.0625,0.4375,1,1
2706 | 0.0625,0.4375,1,1
2707 | 0.0625,0.4375,1,1
2708 | 0.0625,0.4375,1,1
2709 | 0.0625,0.4375,1,1
2710 | 0.0625,0.4375,1,1
2711 | 0.1875,0.4375,1,1
2712 | 0.1875,0.4375,1,1
2713 | 0.1875,0.4375,1,1
2714 | 0.1875,0.4375,1,1
2715 | 0.1875,0.4375,1,1
2716 | 0.1875,0.4375,1,1
2717 | 0.3125,0.4375,1,1
2718 | 0.3125,0.4375,1,1
2719 | 0.3125,0.4375,1,1
2720 | 0.3125,0.4375,1,1
2721 | 0.3125,0.4375,1,1
2722 | 0.3125,0.4375,1,1
2723 | 0.4375,0.4375,1,1
2724 | 0.4375,0.4375,1,1
2725 | 0.4375,0.4375,1,1
2726 | 0.4375,0.4375,1,1
2727 | 0.4375,0.4375,1,1
2728 | 0.4375,0.4375,1,1
2729 | 0.5625,0.4375,1,1
2730 | 0.5625,0.4375,1,1
2731 | 0.5625,0.4375,1,1
2732 | 0.5625,0.4375,1,1
2733 | 0.5625,0.4375,1,1
2734 | 0.5625,0.4375,1,1
2735 | 0.6875,0.4375,1,1
2736 | 0.6875,0.4375,1,1
2737 | 0.6875,0.4375,1,1
2738 | 0.6875,0.4375,1,1
2739 | 0.6875,0.4375,1,1
2740 | 0.6875,0.4375,1,1
2741 | 0.8125,0.4375,1,1
2742 | 0.8125,0.4375,1,1
2743 | 0.8125,0.4375,1,1
2744 | 0.8125,0.4375,1,1
2745 | 0.8125,0.4375,1,1
2746 | 0.8125,0.4375,1,1
2747 | 0.9375,0.4375,1,1
2748 | 0.9375,0.4375,1,1
2749 | 0.9375,0.4375,1,1
2750 | 0.9375,0.4375,1,1
2751 | 0.9375,0.4375,1,1
2752 | 0.9375,0.4375,1,1
2753 | 0.0625,0.5625,1,1
2754 | 0.0625,0.5625,1,1
2755 | 0.0625,0.5625,1,1
2756 | 0.0625,0.5625,1,1
2757 | 0.0625,0.5625,1,1
2758 | 0.0625,0.5625,1,1
2759 | 0.1875,0.5625,1,1
2760 | 0.1875,0.5625,1,1
2761 | 0.1875,0.5625,1,1
2762 | 0.1875,0.5625,1,1
2763 | 0.1875,0.5625,1,1
2764 | 0.1875,0.5625,1,1
2765 | 0.3125,0.5625,1,1
2766 | 0.3125,0.5625,1,1
2767 | 0.3125,0.5625,1,1
2768 | 0.3125,0.5625,1,1
2769 | 0.3125,0.5625,1,1
2770 | 0.3125,0.5625,1,1
2771 | 0.4375,0.5625,1,1
2772 | 0.4375,0.5625,1,1
2773 | 0.4375,0.5625,1,1
2774 | 0.4375,0.5625,1,1
2775 | 0.4375,0.5625,1,1
2776 | 0.4375,0.5625,1,1
2777 | 0.5625,0.5625,1,1
2778 | 0.5625,0.5625,1,1
2779 | 0.5625,0.5625,1,1
2780 | 0.5625,0.5625,1,1
2781 | 0.5625,0.5625,1,1
2782 | 0.5625,0.5625,1,1
2783 | 0.6875,0.5625,1,1
2784 | 0.6875,0.5625,1,1
2785 | 0.6875,0.5625,1,1
2786 | 0.6875,0.5625,1,1
2787 | 0.6875,0.5625,1,1
2788 | 0.6875,0.5625,1,1
2789 | 0.8125,0.5625,1,1
2790 | 0.8125,0.5625,1,1
2791 | 0.8125,0.5625,1,1
2792 | 0.8125,0.5625,1,1
2793 | 0.8125,0.5625,1,1
2794 | 0.8125,0.5625,1,1
2795 | 0.9375,0.5625,1,1
2796 | 0.9375,0.5625,1,1
2797 | 0.9375,0.5625,1,1
2798 | 0.9375,0.5625,1,1
2799 | 0.9375,0.5625,1,1
2800 | 0.9375,0.5625,1,1
2801 | 0.0625,0.6875,1,1
2802 | 0.0625,0.6875,1,1
2803 | 0.0625,0.6875,1,1
2804 | 0.0625,0.6875,1,1
2805 | 0.0625,0.6875,1,1
2806 | 0.0625,0.6875,1,1
2807 | 0.1875,0.6875,1,1
2808 | 0.1875,0.6875,1,1
2809 | 0.1875,0.6875,1,1
2810 | 0.1875,0.6875,1,1
2811 | 0.1875,0.6875,1,1
2812 | 0.1875,0.6875,1,1
2813 | 0.3125,0.6875,1,1
2814 | 0.3125,0.6875,1,1
2815 | 0.3125,0.6875,1,1
2816 | 0.3125,0.6875,1,1
2817 | 0.3125,0.6875,1,1
2818 | 0.3125,0.6875,1,1
2819 | 0.4375,0.6875,1,1
2820 | 0.4375,0.6875,1,1
2821 | 0.4375,0.6875,1,1
2822 | 0.4375,0.6875,1,1
2823 | 0.4375,0.6875,1,1
2824 | 0.4375,0.6875,1,1
2825 | 0.5625,0.6875,1,1
2826 | 0.5625,0.6875,1,1
2827 | 0.5625,0.6875,1,1
2828 | 0.5625,0.6875,1,1
2829 | 0.5625,0.6875,1,1
2830 | 0.5625,0.6875,1,1
2831 | 0.6875,0.6875,1,1
2832 | 0.6875,0.6875,1,1
2833 | 0.6875,0.6875,1,1
2834 | 0.6875,0.6875,1,1
2835 | 0.6875,0.6875,1,1
2836 | 0.6875,0.6875,1,1
2837 | 0.8125,0.6875,1,1
2838 | 0.8125,0.6875,1,1
2839 | 0.8125,0.6875,1,1
2840 | 0.8125,0.6875,1,1
2841 | 0.8125,0.6875,1,1
2842 | 0.8125,0.6875,1,1
2843 | 0.9375,0.6875,1,1
2844 | 0.9375,0.6875,1,1
2845 | 0.9375,0.6875,1,1
2846 | 0.9375,0.6875,1,1
2847 | 0.9375,0.6875,1,1
2848 | 0.9375,0.6875,1,1
2849 | 0.0625,0.8125,1,1
2850 | 0.0625,0.8125,1,1
2851 | 0.0625,0.8125,1,1
2852 | 0.0625,0.8125,1,1
2853 | 0.0625,0.8125,1,1
2854 | 0.0625,0.8125,1,1
2855 | 0.1875,0.8125,1,1
2856 | 0.1875,0.8125,1,1
2857 | 0.1875,0.8125,1,1
2858 | 0.1875,0.8125,1,1
2859 | 0.1875,0.8125,1,1
2860 | 0.1875,0.8125,1,1
2861 | 0.3125,0.8125,1,1
2862 | 0.3125,0.8125,1,1
2863 | 0.3125,0.8125,1,1
2864 | 0.3125,0.8125,1,1
2865 | 0.3125,0.8125,1,1
2866 | 0.3125,0.8125,1,1
2867 | 0.4375,0.8125,1,1
2868 | 0.4375,0.8125,1,1
2869 | 0.4375,0.8125,1,1
2870 | 0.4375,0.8125,1,1
2871 | 0.4375,0.8125,1,1
2872 | 0.4375,0.8125,1,1
2873 | 0.5625,0.8125,1,1
2874 | 0.5625,0.8125,1,1
2875 | 0.5625,0.8125,1,1
2876 | 0.5625,0.8125,1,1
2877 | 0.5625,0.8125,1,1
2878 | 0.5625,0.8125,1,1
2879 | 0.6875,0.8125,1,1
2880 | 0.6875,0.8125,1,1
2881 | 0.6875,0.8125,1,1
2882 | 0.6875,0.8125,1,1
2883 | 0.6875,0.8125,1,1
2884 | 0.6875,0.8125,1,1
2885 | 0.8125,0.8125,1,1
2886 | 0.8125,0.8125,1,1
2887 | 0.8125,0.8125,1,1
2888 | 0.8125,0.8125,1,1
2889 | 0.8125,0.8125,1,1
2890 | 0.8125,0.8125,1,1
2891 | 0.9375,0.8125,1,1
2892 | 0.9375,0.8125,1,1
2893 | 0.9375,0.8125,1,1
2894 | 0.9375,0.8125,1,1
2895 | 0.9375,0.8125,1,1
2896 | 0.9375,0.8125,1,1
2897 | 0.0625,0.9375,1,1
2898 | 0.0625,0.9375,1,1
2899 | 0.0625,0.9375,1,1
2900 | 0.0625,0.9375,1,1
2901 | 0.0625,0.9375,1,1
2902 | 0.0625,0.9375,1,1
2903 | 0.1875,0.9375,1,1
2904 | 0.1875,0.9375,1,1
2905 | 0.1875,0.9375,1,1
2906 | 0.1875,0.9375,1,1
2907 | 0.1875,0.9375,1,1
2908 | 0.1875,0.9375,1,1
2909 | 0.3125,0.9375,1,1
2910 | 0.3125,0.9375,1,1
2911 | 0.3125,0.9375,1,1
2912 | 0.3125,0.9375,1,1
2913 | 0.3125,0.9375,1,1
2914 | 0.3125,0.9375,1,1
2915 | 0.4375,0.9375,1,1
2916 | 0.4375,0.9375,1,1
2917 | 0.4375,0.9375,1,1
2918 | 0.4375,0.9375,1,1
2919 | 0.4375,0.9375,1,1
2920 | 0.4375,0.9375,1,1
2921 | 0.5625,0.9375,1,1
2922 | 0.5625,0.9375,1,1
2923 | 0.5625,0.9375,1,1
2924 | 0.5625,0.9375,1,1
2925 | 0.5625,0.9375,1,1
2926 | 0.5625,0.9375,1,1
2927 | 0.6875,0.9375,1,1
2928 | 0.6875,0.9375,1,1
2929 | 0.6875,0.9375,1,1
2930 | 0.6875,0.9375,1,1
2931 | 0.6875,0.9375,1,1
2932 | 0.6875,0.9375,1,1
2933 | 0.8125,0.9375,1,1
2934 | 0.8125,0.9375,1,1
2935 | 0.8125,0.9375,1,1
2936 | 0.8125,0.9375,1,1
2937 | 0.8125,0.9375,1,1
2938 | 0.8125,0.9375,1,1
2939 | 0.9375,0.9375,1,1
2940 | 0.9375,0.9375,1,1
2941 | 0.9375,0.9375,1,1
2942 | 0.9375,0.9375,1,1
2943 | 0.9375,0.9375,1,1
2944 | 0.9375,0.9375,1,1
2945 |
--------------------------------------------------------------------------------
/config.py:
--------------------------------------------------------------------------------
1 | WINDOW = "Hand Tracking"
2 | mode = "tflite"
3 | #mode = "pb"
4 | if mode == "tflite":
5 | PALM_MODEL_PATH = "./palm_detection_without_custom_op.tflite"
6 | LANDMARK_MODEL_PATH = "./hand_landmark_small.tflite"
7 | else:
8 | # PALM_MODEL_PATH = "./palm_detection_without_custom_op.pb"
9 | # LANDMARK_MODEL_PATH = "./hand_landmark.pb"
10 | PALM_MODEL_PATH = "./saved_model_hand_landmark/saved_model.pb"
11 | LANDMARK_MODEL_PATH = "./saved_model_palm_detection_builtin/saved_model.pb"
12 | ANCHORS_PATH = "./anchors.csv"
13 | VIDEO = 0
14 | #VIDEO = 'http://192.168.29.172:4747/mjpegfeed'
15 | #VIDEO = 'http://192.168.29.172:8080/video'
16 | GET_IPWEBCAM = False
17 | #IMAGE = 'http://192.168.29.172:8080/shot.jpg'
18 |
19 | POINT_COLOR = (0, 255, 0)
20 | CONNECTION_COLOR = (255, 0, 0)
21 | THICKNESS = 2
22 |
23 | # 8 12 16 20
24 | # | | | |
25 | # 7 11 15 19
26 | # 4 | | | |
27 | # | 6 10 14 18
28 | # 3 | | | |
29 | # | 5---9---13--17
30 | # 2 \ /
31 | # \ \ /
32 | # 1 \ /
33 | # \ \ /
34 | # ------0-
35 | connections = [
36 | (0, 1), (1, 2), (2, 3), (3, 4),
37 | (5, 6), (6, 7), (7, 8),
38 | (9, 10), (10, 11), (11, 12),
39 | (13, 14), (14, 15), (15, 16),
40 | (17, 18), (18, 19), (19, 20),
41 | (0, 5), (5, 9), (9, 13), (13, 17), (0, 17)
42 | ]
43 |
44 | FILTER_COEFFS = [-0.17857, -0.07143, 0.03571, 0.14286, 0.25, 0.35714, 0.46429]
45 | #FILTER_COEFFS = [-0.12088, -0.08791, -0.05495, -0.02198, 0.01099, 0.04396, 0.07692, 0.10989, 0.14286, 0.17582, 0.20879, 0.24176, 0.27473]
46 | NATIVE_RES_X = 1920
47 | NATIVE_RES_Y = 1080
48 | WEBCAM_X = 640
49 | WEBCAM_Y = 480
50 | CAM_RES_X = WEBCAM_X // 2#320#640
51 | CAM_RES_Y = WEBCAM_Y // 2 #240#480
52 | SCALE = 1
53 | FLIP_X = False
54 | FLIP_Y = False
55 |
56 | LOG = False
57 |
58 | SAVE_FILE = "DATASET/train.pkl"
59 | TRAIN_GESTURE = "CLICK"
60 | LABELS = ["RELEASE", "HOLD", "CLICK", "ROTATE", "POINT"]
61 | MODEL_TYPE = 'svm'
62 | SKIP_THUMB = True
--------------------------------------------------------------------------------
/control.py:
--------------------------------------------------------------------------------
1 | import win32api, win32con
2 | from config import *
3 | import pyautogui, sys
4 |
5 | pyautogui.FAILSAFE = False
6 |
7 | class Control:
8 | def __init__(self):
9 | self.W = NATIVE_RES_X
10 | self.H = NATIVE_RES_Y
11 | self.camW = CAM_RES_X
12 | self.camH = CAM_RES_Y
13 | self.flipx = FLIP_X
14 | self.flipy = FLIP_Y
15 | self.scale = SCALE
16 |
17 | self.state = "START"
18 | self.prev_gesture = "None"
19 | self.STATE_MACHINE = {
20 | "CLICK" : {"START":"move", "move":"move", "RELEASE":"END"},
21 | "HOLD" : {"START":"move", "move":"move", "RELEASE":"END"}
22 | }
23 |
24 | def command(self, gesture):
25 |
26 | if gesture == "CLICK":
27 | self.click_down(self.position)
28 | elif gesture == "RELEASE":
29 | self.click_up(self.position)
30 | elif gesture == "POINT":
31 | self.scroll(10)
32 | else:
33 | pass
34 |
35 | def update_position(self, input_position):
36 | position = [input_position[0], input_position[1]]
37 | position[0] = min(position[0] - (640 - self.camW) // 2, self.camW)
38 | position[0] = min(position[0] * self.W / self.camW , self.W)
39 | if self.flipx:
40 | position[0] = self.W - position[0]
41 | position[1] = min(position[1] - (480 - self.camH) // 2, self.camH)
42 | position[1] = min(position[1] * self.H / self.camH , self.H)
43 | if self.flipy:
44 | position[1] = self.H - position[1]
45 | self.position = [int(position[0]), int(position[1])]
46 | #print(self.position)
47 | self.move(self.position)
48 |
49 | def move(self, position):
50 | #win32api.SetCursorPos((position[0],position[1]))
51 | pyautogui.moveTo(position[0], position[1])
52 |
53 | def click_down(self, position):
54 | x,y = position[0],position[1]
55 | # win32api.SetCursorPos((x,y))
56 | # win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,x,y,0,0)
57 | #
58 | pyautogui.mouseDown(button='left');
59 | #win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,x,y,0,0)
60 | def click_up(self, position):
61 | x,y = position[0],position[1]
62 | # win32api.SetCursorPos((x,y))
63 | # win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,x,y,0,0)
64 | pyautogui.mouseUp(button='left');
65 |
66 | def click(self, position):
67 | x,y = position[0],position[1]
68 | # win32api.SetCursorPos((x,y))
69 | # win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,x,y,0,0)
70 | # win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,x,y,0,0)
71 | pyautogui.click(button='left')
72 |
73 | def scroll(self, amount=10):
74 | pyautogui.scroll(amount)
--------------------------------------------------------------------------------
/convert_hand3d_tflite_pb.py:
--------------------------------------------------------------------------------
1 | ### tensorflow-gpu==1.15.2
2 |
3 | ### https://stackoverflow.com/questions/39975676/how-to-implement-prelu-activation-in-tensorflow
4 | ### https://www.tensorflow.org/lite/guide/ops_compatibility
5 |
6 | #!/usr/bin/env python
7 | # coding: utf-8
8 |
9 | import os
10 | import numpy as np
11 | import json
12 | import tensorflow as tf
13 | import shutil
14 | from pathlib import Path
15 | home = str(Path.home())
16 |
17 | os.environ['CUDA_VISIBLE_DEVICES'] = '0'
18 | schema = "schema.fbs"
19 | binary = "flatc"
20 | model_path = "hand_landmark_small.tflite"
21 | output_pb_path = "hand_landmark_small.pb"
22 | output_savedmodel_path = "saved_model_hand_landmark_small"
23 | model_json_path = "hand_landmark_small.json"
24 | num_tensors = 575
25 | output_node_names = ['output_handflag', 'ld_21_3d', 'output_handedness']
26 |
27 | def gen_model_json():
28 | if not os.path.exists(model_json_path):
29 | cmd = (binary + " -t --strict-json --defaults-json -o . {schema} -- {input}".format(input=model_path, schema=schema))
30 | print("output json command =", cmd)
31 | os.system(cmd)
32 |
33 |
34 | def parse_json():
35 | j = json.load(open(model_json_path))
36 | op_types = [v['builtin_code'] for v in j['operator_codes']]
37 | print('op types:', op_types)
38 | ops = j['subgraphs'][0]['operators']
39 | print('num of ops:', len(ops))
40 | return ops, op_types
41 |
42 |
43 | def make_graph(ops, op_types, interpreter):
44 | tensors = {}
45 | input_details = interpreter.get_input_details()
46 | output_details = interpreter.get_output_details()
47 | print(input_details)
48 | for input_detail in input_details:
49 | tensors[input_detail['index']] = tf.compat.v1.placeholder(
50 | dtype=input_detail['dtype'],
51 | shape=input_detail['shape'],
52 | name=input_detail['name'])
53 | # for i in range(num_tensors):
54 | # detail = interpreter._get_tensor_details(i)
55 | # tensors[detail['index']] = tf.compat.v1.placeholder(
56 | # dtype=detail['dtype'],
57 | # shape=detail['shape'],
58 | # name=detail['name'])
59 | #print(detail)
60 | for index, op in enumerate(ops):
61 | print(op)
62 | op_type = op_types[op['opcode_index']]
63 | if op_type == "DEQUANTIZE":
64 | input_details = interpreter._get_tensor_details(op['inputs'][0])
65 | output_detail = interpreter._get_tensor_details(op['outputs'][0])
66 |
67 | input_tensor = interpreter.get_tensor(op['inputs'][0])
68 | #print(type(input_tensor))
69 | output_np = input_tensor.astype(np.float32)
70 | #output_tensor = tf.cast(input_tensor, tf.float32)
71 | output_tensor = tf.constant(
72 | output_np, dtype=tf.float32, name=output_detail['name'])
73 | #print(output_tensor)
74 |
75 |
76 | interpreter.set_tensor(output_detail["index"], output_np)
77 | tensors[output_detail['index']] = output_tensor
78 |
79 | def compute_op(op, index):
80 | op_type = op_types[op['opcode_index']]
81 | if op_type == 'CONV_2D':
82 |
83 | input_tensor = tensors[op['inputs'][0]]
84 | weights_detail = interpreter._get_tensor_details(op['inputs'][1])
85 | bias_detail = interpreter._get_tensor_details(op['inputs'][2])
86 | output_detail = interpreter._get_tensor_details(op['outputs'][0])
87 | # print('weights_detail: ', weights_detail)
88 | # print('bias_detail: ', bias_detail)
89 | # print('output_detail: ', output_detail)
90 | weights_array = interpreter.get_tensor(weights_detail['index'])
91 | weights_array = np.transpose(weights_array, (1, 2, 3, 0))
92 | bias_array = interpreter.get_tensor(bias_detail['index'])
93 | weights = tf.Variable(weights_array, name=weights_detail['name'])
94 | bias = tf.Variable(bias_array, name=bias_detail['name'])
95 | options = op['builtin_options']
96 | output_tensor = tf.nn.conv2d(
97 | input_tensor,
98 | weights,
99 | strides=[1, options['stride_h'], options['stride_w'], 1],
100 | padding=options['padding'],
101 | dilations=[
102 | 1, options['dilation_h_factor'],
103 | options['dilation_w_factor'], 1
104 | ],
105 | name=output_detail['name'] + '/conv2d')
106 | output_tensor = tf.add(
107 | output_tensor, bias, name=output_detail['name'])
108 | tensors[output_detail['index']] = output_tensor
109 |
110 | elif op_type == 'DEPTHWISE_CONV_2D':
111 |
112 | input_tensor = tensors[op['inputs'][0]]
113 | weights_detail = interpreter._get_tensor_details(op['inputs'][1])
114 | bias_detail = interpreter._get_tensor_details(op['inputs'][2])
115 | output_detail = interpreter._get_tensor_details(op['outputs'][0])
116 | # print('weights_detail: ', weights_detail)
117 | # print('bias_detail: ', bias_detail)
118 | # print('output_detail: ', output_detail)
119 | weights_array = interpreter.get_tensor(weights_detail['index'])
120 | weights_array = np.transpose(weights_array, (1, 2, 3, 0))
121 | bias_array = interpreter.get_tensor(bias_detail['index'])
122 | weights = tf.Variable(weights_array, name=weights_detail['name'])
123 | bias = tf.Variable(bias_array, name=bias_detail['name'])
124 | options = op['builtin_options']
125 | output_tensor = tf.nn.depthwise_conv2d(
126 | input_tensor,
127 | weights,
128 | strides=[1, options['stride_h'], options['stride_w'], 1],
129 | padding=options['padding'],
130 | # dilations=[
131 | # 1, options['dilation_h_factor'],
132 | # options['dilation_w_factor'], 1
133 | # ],
134 | name=output_detail['name'] + '/depthwise_conv2d')
135 | output_tensor = tf.add(
136 | output_tensor, bias, name=output_detail['name'])
137 | tensors[output_detail['index']] = output_tensor
138 |
139 | elif op_type == 'MAX_POOL_2D':
140 |
141 | input_tensor = tensors[op['inputs'][0]]
142 | output_detail = interpreter._get_tensor_details(op['outputs'][0])
143 | options = op['builtin_options']
144 | output_tensor = tf.nn.max_pool(
145 | input_tensor,
146 | ksize=[
147 | 1, options['filter_height'], options['filter_width'], 1
148 | ],
149 | strides=[1, options['stride_h'], options['stride_w'], 1],
150 | padding=options['padding'],
151 | name=output_detail['name'])
152 | tensors[output_detail['index']] = output_tensor
153 |
154 | elif op_type == 'PAD':
155 |
156 | input_tensor = tensors[op['inputs'][0]]
157 | output_detail = interpreter._get_tensor_details(op['outputs'][0])
158 | paddings_detail = interpreter._get_tensor_details(op['inputs'][1])
159 | #print('input_tensor: ', input_tensor)
160 | #print('output_detail:', output_detail)
161 | #print('paddings_detail:', paddings_detail)
162 | paddings_array = interpreter.get_tensor(paddings_detail['index'])
163 | # paddings = tf.Variable(
164 | # paddings_array, name=paddings_detail['name'])
165 | paddings = tf.constant(
166 | paddings_array, dtype=tf.int32)
167 |
168 | output_tensor = tf.pad(
169 | input_tensor, paddings, name=output_detail['name'])
170 | tensors[output_detail['index']] = output_tensor
171 |
172 | elif op_type == 'RELU':
173 |
174 | output_detail = interpreter._get_tensor_details(op['outputs'][0])
175 | input_tensor = tensors[op['inputs'][0]]
176 | output_tensor = tf.nn.relu(
177 | input_tensor, name=output_detail['name'])
178 | tensors[output_detail['index']] = output_tensor
179 |
180 | elif op_type == 'PRELU':
181 |
182 | output_detail = interpreter._get_tensor_details(op['outputs'][0])
183 | input_tensor = tensors[op['inputs'][0]]
184 | alpha_detail = interpreter._get_tensor_details(op['inputs'][1])
185 | alpha_array = interpreter.get_tensor(alpha_detail['index'])
186 | with tf.compat.v1.variable_scope(name_or_scope=output_detail['name']):
187 | alphas = tf.Variable(alpha_array, name=alpha_detail['name'])
188 | output_tensor = tf.maximum(alphas * input_tensor, input_tensor)
189 | #print("PRELU.output_tensor=", output_tensor)
190 | tensors[output_detail['index']] = output_tensor
191 |
192 | elif op_type == 'RESHAPE':
193 |
194 | input_tensor = tensors[op['inputs'][0]]
195 | output_detail = interpreter._get_tensor_details(op['outputs'][0])
196 | options = op['builtin_options']
197 | output_tensor = tf.reshape(
198 | input_tensor, options['new_shape'], name=output_detail['name'])
199 | tensors[output_detail['index']] = output_tensor
200 |
201 | elif op_type == 'ADD':
202 |
203 | output_detail = interpreter._get_tensor_details(op['outputs'][0])
204 | input_tensor_0 = tensors[op['inputs'][0]]
205 | input_tensor_1 = tensors[op['inputs'][1]]
206 | output_tensor = tf.add(input_tensor_0, input_tensor_1, name=output_detail['name'])
207 | tensors[output_detail['index']] = output_tensor
208 |
209 | elif op_type == 'CONCATENATION':
210 |
211 | output_detail = interpreter._get_tensor_details(op['outputs'][0])
212 | input_tensor_0 = tensors[op['inputs'][0]]
213 | input_tensor_1 = tensors[op['inputs'][1]]
214 | options = op['builtin_options']
215 | output_tensor = tf.concat([input_tensor_0, input_tensor_1],
216 | options['axis'],
217 | name=output_detail['name'])
218 | tensors[output_detail['index']] = output_tensor
219 |
220 | elif op_type == 'LOGISTIC':
221 | output_detail = interpreter._get_tensor_details(op['outputs'][0])
222 | input_tensor = tensors[op['inputs'][0]]
223 | #print('LOGISTIC op', op)
224 | #print('LOGISTIC output_detail:', output_detail)
225 | #print('LOGISTIC input_tensor:', input_tensor)
226 | output_tensor = tf.math.sigmoid(input_tensor, name=output_detail['name'])
227 | tensors[output_detail['index']] = output_tensor
228 |
229 | elif op_type == "RESIZE_BILINEAR":
230 | output_detail = interpreter._get_tensor_details(op['outputs'][0])
231 | input_tensor_0 = tensors[op['inputs'][0]]
232 | input_tensor_1 = interpreter.get_tensor(op['inputs'][1])
233 | options = op['builtin_options']
234 | output_tensor = tf.compat.v1.image.resize_bilinear(
235 | input_tensor_0, input_tensor_1, align_corners=options['align_corners'], name=output_detail['name'], half_pixel_centers=options['half_pixel_centers']
236 | )
237 | tensors[output_detail['index']] = output_tensor
238 | elif op_type == "DEQUANTIZE":
239 | pass
240 | else:
241 | raise ValueError(op_type)
242 |
243 |
244 |
245 | # for index, op in enumerate(ops):
246 | # for q in queue:
247 | # if q[0] in tensors.keys():
248 | # print('opq: ', op)
249 | # compute_op(ops[q[1]], q[1])
250 | # queue.remove(q)
251 | # #print('op: ', op)
252 | # compute_op(op, index)
253 | # # print(queue)
254 | # print(tensors.keys())
255 | # while len(queue)!=0:
256 | # print(len(queue))
257 | # for q in queue:
258 | # #print('opq: ', ops[q[1]])
259 | # compute_op(ops[q[1]], q[1])
260 | # queue.remove(q)
261 |
262 | # print(queue)
263 | for index, op in enumerate(ops):
264 | print(op)
265 | compute_op(op, index)
266 |
267 |
268 |
269 |
270 | def main():
271 |
272 | tf.compat.v1.disable_eager_execution()
273 |
274 | gen_model_json()
275 | ops, op_types = parse_json()
276 |
277 | interpreter = tf.lite.Interpreter(model_path)
278 | interpreter.allocate_tensors()
279 | input_details = interpreter.get_input_details()
280 | output_details = interpreter.get_output_details()
281 | print(input_details)
282 | print(output_details)
283 | for i in range(num_tensors):
284 | detail = interpreter._get_tensor_details(i)
285 | print(detail)
286 | # for i in range(1000):
287 | # detail = interpreter._get_tensor_details(i)
288 | # print(detail)
289 | print("MAKING GRAPH")
290 | make_graph(ops, op_types, interpreter)
291 |
292 | config = tf.compat.v1.ConfigProto()
293 | config.gpu_options.allow_growth = True
294 | graph = tf.compat.v1.get_default_graph()
295 | # writer = tf.summary.FileWriter(os.path.splitext(output_pb_path)[0])
296 | # writer.add_graph(graph)
297 | # writer.flush()
298 | # writer.close()
299 | with tf.compat.v1.Session(config=config, graph=graph) as sess:
300 | sess.run(tf.compat.v1.global_variables_initializer())
301 |
302 | # for op in graph.get_operations():
303 | # print(op.name)
304 |
305 | graph_def = tf.compat.v1.graph_util.convert_variables_to_constants(
306 | sess=sess,
307 | input_graph_def=graph.as_graph_def(),
308 | output_node_names=output_node_names)
309 |
310 | with tf.io.gfile.GFile(output_pb_path, 'wb') as f:
311 | f.write(graph_def.SerializeToString())
312 |
313 |
314 |
315 | shutil.rmtree('saved_model_hand_landmark_small', ignore_errors=True)
316 | tf.compat.v1.saved_model.simple_save(
317 | sess,
318 | output_savedmodel_path,
319 | inputs={'input': graph.get_tensor_by_name('input_1:0')},
320 | outputs={
321 | 'output_handedness':graph.get_tensor_by_name('output_handedness:0'),
322 | 'output_handflag': graph.get_tensor_by_name('output_handflag:0'),
323 | 'ld_21_3d': graph.get_tensor_by_name('ld_21_3d:0')
324 | })
325 |
326 | if __name__ == '__main__':
327 | main()
328 |
329 | """
330 | $ saved_model_cli show --dir saved_model_hand_landmark_3d --all
331 | MetaGraphDef with tag-set: 'serve' contains the following SignatureDefs:
332 | signature_def['serving_default']:
333 | The given SavedModel SignatureDef contains the following input(s):
334 | inputs['input'] tensor_info:
335 | dtype: DT_FLOAT
336 | shape: (1, 256, 256, 3)
337 | name: input_1:0
338 | The given SavedModel SignatureDef contains the following output(s):
339 | outputs['ld_21_3d'] tensor_info:
340 | dtype: DT_FLOAT
341 | shape: (1, -1)
342 | name: ld_21_3d:0
343 | outputs['output_handflag'] tensor_info:
344 | dtype: DT_FLOAT
345 | shape: (1, -1)
346 | name: output_handflag:0
347 | Method name is: tensorflow/serving/predict
348 | """
--------------------------------------------------------------------------------
/drawing_helpers.py:
--------------------------------------------------------------------------------
1 | from config import *
2 | import cv2
3 | import numpy as np
4 |
5 | def draw_box(frame, box):
6 | box = box.astype(int)
7 | cv2.circle(frame, (int(box.mean(axis=0)[0]), int(box.mean(axis=0)[1])), 1 * 2, (0, 0, 255), 2)
8 | cv2.drawContours(frame, [box.astype(int)], 0, (0, 0, 255), 2)
9 |
10 | def draw_keypoints(frame, keypoints):
11 | for point in keypoints:
12 | x, y = point
13 | cv2.circle(frame, (int(x), int(y)), THICKNESS * 2, POINT_COLOR, THICKNESS)
14 |
15 | def draw_connections(frame, points):
16 | for connection in connections:
17 | x0, y0 = points[connection[0]]
18 | x1, y1 = points[connection[1]]
19 | cv2.line(frame, (int(x0), int(y0)), (int(x1), int(y1)), CONNECTION_COLOR, THICKNESS)
20 |
21 | def draw_text(frame, ges_predict, ges_avg):
22 | cv2.putText(frame,LABELS[ges_predict[0]],(400,20),cv2.FONT_HERSHEY_COMPLEX,1,(0,0,0),1)
23 | cv2.putText(frame,ges_avg,(400,60),cv2.FONT_HERSHEY_COMPLEX,1,(0,0,0),1)
--------------------------------------------------------------------------------
/flatc.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TviNet/Multi-HandTrackingGPU/db4fab504073f11b9c14fef8ebd9fdcfc2c3db0f/flatc.exe
--------------------------------------------------------------------------------
/gesture.py:
--------------------------------------------------------------------------------
1 | # 8 12 16 20
2 | # | | | |
3 | # 7 11 15 19
4 | # 4 | | | |
5 | # | 6 10 14 18
6 | # 3 | | | |
7 | # | 5---9---13--17
8 | # 2 \ /
9 | # \ \ /
10 | # 1 \ /
11 | # \ \ /
12 | # ------0-
13 | import numpy as np
14 | from collections import Counter
15 | from config import *
16 | from gesture_rules import GestureRules
17 |
18 | class Gestures:
19 | def __init__(self):
20 |
21 | self.cur_gesture = None
22 | self.num_hands = 1
23 |
24 | self.enum = {"THUMB":0, "INDEX":1, "MIDDLE":2, "RING":3, "LITTLE":4}
25 | self.inv_enum = {v: k for k, v in self.enum.items()}
26 |
27 | self.pointing_finger = "MIDDLE"
28 | self.predefined_gestures = ["CLICK", "HOLD", "RELEASE", "ROTATE"]
29 |
30 | self.position = None
31 | self.orientation = None
32 | self.gesture = None
33 | self.gesture_rules = GestureRules()
34 |
35 | self.NUM_GESTURES_TO_STORE = 5
36 | self.GESTURE_THRESHOLD = 0.8
37 | self.gesture_list = []
38 |
39 | def add_to_list(self, gesture):
40 | self.gesture_list.append(gesture)
41 | if len(self.gesture_list) > self.NUM_GESTURES_TO_STORE:
42 | self.gesture_list = self.gesture_list[1:]
43 |
44 | def current_detected_gesture(self, ges_predict):
45 | self.add_to_list(LABELS[ges_predict[0]])
46 | counts = Counter(self.gesture_list)
47 | for key, val in counts.items():
48 | if val >= self.GESTURE_THRESHOLD * self.NUM_GESTURES_TO_STORE:
49 | return key
50 | return "None"
51 |
52 | def empty(self):
53 | self.position = None
54 | self.orientation = None
55 | self.gesture = None
56 | self.gesture_rules.empty()
57 |
58 | def set_position(self, keypoints):
59 | self.position = keypoints[self.enum[self.pointing_finger]*4 + 3 + 1, :2]
60 | return self.position
61 |
62 | def set_orientation(self, angle):
63 | self.orientation = angle
64 | return self.orientation
65 |
66 | def theta(self, v, w):
67 | ang = v.dot(w)/(np.linalg.norm(v)*np.linalg.norm(w))
68 | return np.arccos(np.clip(ang, -1, 1))
69 |
70 |
71 | def calculate_angles(self, keypoints):
72 | angles = np.zeros((5, 3))
73 | mcps = [1,5,9,13,17]
74 | pips = [2,6,10,14,18]
75 | dips = [3,7,11,15,19]
76 | tips = [4,8,12,16,20]
77 | v0 = keypoints[tips]-keypoints[dips]
78 | v1 = keypoints[dips]-keypoints[pips]
79 | v2 = keypoints[pips]-keypoints[mcps]
80 | v3 = keypoints[mcps]
81 |
82 | for i in range(5):
83 | angles[i, 0] = self.theta(v3[i], v2[i])
84 | angles[i, 1] = self.theta(v2[i], v1[i])
85 | angles[i, 2] = self.theta(v1[i], v0[i])
86 |
87 | return angles
88 |
89 | def estimate_gesture(self, keypoints):
90 | angles = self.calculate_angles(keypoints)
91 | self.gesture = None#self.gesture_rules.get_matching_gesture(angles)
92 |
93 | return self.gesture, self.gesture_rules.gesture_read, angles
94 |
95 |
--------------------------------------------------------------------------------
/gesture_rules.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | from collections import Counter
3 |
4 | class GestureRules:
5 | def __init__(self):
6 | self.angle_types = ["STRAIGHT", "BENT", "RIGHT"]
7 | self.predefined_gestures = ["CLICK", "HOLD", "RELEASE", "ROTATE"]
8 | self.gesture_definition = {"CLICK": {},
9 | "HOLD": {},
10 | "RELEASE": {},
11 | "ROTATE": {},
12 |
13 | }
14 | self.ANGLE_THESHOLD = 20
15 | self.enum = {"THUMB":0, "INDEX":1, "MIDDLE":2, "RING":3, "LITTLE":4}
16 | self.inv_enum = {v: k for k, v in self.enum.items()}
17 | self.gesture_read = {"THUMB":[],
18 | "INDEX":[],
19 | "MIDDLE":[],
20 | "RING":[],
21 | "LITTLE":[]
22 | }
23 | self.gesture_angles = None
24 |
25 | def empty(self):
26 | self.gesture_angles = None
27 | self.gesture_read = {"THUMB":[],
28 | "INDEX":[],
29 | "MIDDLE":[],
30 | "RING":[],
31 | "LITTLE":[]
32 | }
33 |
34 | def angle_to_type(self, angle):
35 | if abs(angle * 180 / np.pi - 0) < 20:
36 | return "STRAIGHT"
37 | elif abs(angle * 180 / np.pi - 90) < 20:
38 | return "RIGHT"
39 | else:
40 | return "BENT"
41 |
42 | def read_gesture(self, angles):
43 | for i in range(5):
44 | for j in range(3):
45 | self.gesture_read[self.inv_enum[i]].append(self.angle_to_type(angles[i,j]))
46 |
47 | def compare_definition(self, definition, angles):
48 | for i in range(5):
49 | for j in range(3):
50 | if definition[self.inv_enum[i]][j] != "ANY" and definition[self.inv_enum[i]][j] != self.angle_to_type(angles[i,j]) :
51 | return False
52 | return True
53 |
54 | def get_matching_gesture(self, angles):
55 | self.read_gesture(angles)
56 | self.gesture_angles = angles
57 | for gesture_name, gesture_definition in self.gesture_definition.items():
58 | if self.compare_definition(gesture_definition, angles):
59 | return gesture_name
60 | return None
61 |
--------------------------------------------------------------------------------
/hand_landmark_small.pb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TviNet/Multi-HandTrackingGPU/db4fab504073f11b9c14fef8ebd9fdcfc2c3db0f/hand_landmark_small.pb
--------------------------------------------------------------------------------
/hand_landmark_small.tflite:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TviNet/Multi-HandTrackingGPU/db4fab504073f11b9c14fef8ebd9fdcfc2c3db0f/hand_landmark_small.tflite
--------------------------------------------------------------------------------
/hand_tracker_multi.py:
--------------------------------------------------------------------------------
1 | import csv
2 | import cv2
3 | import numpy as np
4 | #import tensorflow as tf
5 | import tensorflow.compat.v1 as tf
6 | from nms import non_max_suppression_fast
7 |
8 | class HandTracker():
9 | r"""
10 | Class to use Google's Mediapipe HandTracking pipeline from Python.
11 | So far only detection of a single hand is supported.
12 | Any image size and aspect ratio supported.
13 | """
14 |
15 | def __init__(self, palm_model, joint_model, anchors_path):
16 | self.sess_palm = tf.Session(graph=self.load_pb("./palm_detection_builtin.pb"))
17 | self.sess_hand = tf.Session(graph=self.load_pb("./hand_landmark_small.pb"))
18 | # reading the SSD anchors
19 | with open(anchors_path, "r") as csv_f:
20 | self.anchors = np.r_[
21 | [x for x in csv.reader(csv_f, quoting=csv.QUOTE_NONNUMERIC)]
22 | ]
23 |
24 | self.left_hand = {"joints":None, "palm":None, "box":None}
25 | self.right_hand = {"joints":None, "palm":None, "box":None}
26 |
27 | self.calculate_palm = True
28 |
29 |
30 | def load_pb(self, path_to_pb):
31 | with tf.gfile.GFile(path_to_pb, "rb") as f:
32 | graph_def = tf.GraphDef()
33 | graph_def.ParseFromString(f.read())
34 | with tf.Graph().as_default() as graph:
35 | tf.import_graph_def(graph_def, name='')
36 | return graph
37 |
38 | @staticmethod
39 | def _im_normalize(img):
40 | return np.ascontiguousarray(
41 | 2 * ((img / 255) - 0.5
42 | ).astype('float32'))
43 |
44 | @staticmethod
45 | def _sigm(x):
46 | return 1 / (1 + np.exp(-x) )
47 |
48 | @staticmethod
49 | def _pad1(x):
50 | return np.pad(x, ((0,0),(0,1)), constant_values=1, mode='constant')
51 |
52 |
53 | def predict_joints(self, img_norm):
54 | joints, flag, handedness = self.sess_hand.run(['ld_21_3d:0','output_handflag:0','output_handedness:0'], feed_dict={'input_1:0':img_norm.reshape(1,256,256,3)})
55 | joints = joints.reshape(-1,3)
56 | if handedness[0,0] < 0.5:
57 | hand = "right"
58 | # joints = self.sess_hand.run(['ld_21_3d:0'], feed_dict={'input_1:0':cv2.flip(img_norm, 1).reshape(1,256,256,3)})
59 | # joints = joints[0].reshape(-1,3)
60 | # joints[:,0] = 256-joints[:,0]
61 | else:
62 | hand = "left"
63 | return joints, flag, hand
64 |
65 |
66 | def detect_hand(self, img_norm):
67 | assert -1 <= img_norm.min() and img_norm.max() <= 1,\
68 | "img_norm should be in range [-1, 1]"
69 | assert img_norm.shape == (256, 256, 3),\
70 | "img_norm shape must be (256, 256, 3)"
71 |
72 | out_reg, out_clf = self.sess_palm.run(['regressors:0', 'classificators:0'], feed_dict={'input:0':img_norm.reshape(1,256,256,3)})
73 | out_reg = out_reg[0]
74 | out_clf = out_clf[0,:,0]
75 |
76 | # finding the best prediction
77 | out_clf = np.clip(out_clf, -20, 20)
78 | probabilities = self._sigm(out_clf)
79 | detecion_mask = probabilities > 0.3
80 | candidate_detect = out_reg[detecion_mask]
81 | candidate_anchors = self.anchors[detecion_mask]
82 | probabilities = probabilities[detecion_mask]
83 |
84 | if candidate_detect.shape[0] == 0:
85 | print("No hands found")
86 | return None, None
87 |
88 | # Pick the best bounding box with non maximum suppression
89 | # the boxes must be moved by the corresponding anchor first
90 | moved_candidate_detect = candidate_detect.copy()
91 | moved_candidate_detect[:, :2] = candidate_detect[:, :2] + (candidate_anchors[:, :2] * 256)
92 | box_ids = non_max_suppression_fast(moved_candidate_detect[:, :4], probabilities)
93 |
94 | keypoints_list = []
95 | side_list = []
96 |
97 | for max_idx in box_ids:
98 | # bounding box offsets, width and height
99 | dx,dy,w,h = candidate_detect[max_idx, :4]
100 | center_wo_offst = candidate_anchors[max_idx,:2] * 256
101 |
102 | # 7 initial keypoints
103 | keypoints = center_wo_offst + candidate_detect[max_idx,4:].reshape(-1,2)
104 | side = max(w,h) * self.box_enlarge
105 |
106 | keypoints_list.append(keypoints)
107 | side_list.append(side)
108 |
109 |
110 | return keypoints_list, side_list
111 | #return keypoints, side
112 |
113 | def preprocess_img(self, img):
114 | # fit the image into a 256x256 square
115 | shape = np.r_[img.shape]
116 | pad = (shape.max() - shape[:2]).astype('uint32') // 2
117 | img_pad = np.pad(
118 | img,
119 | ((pad[0],pad[0]), (pad[1],pad[1]), (0,0)),
120 | mode='constant')
121 | img_small = cv2.resize(img_pad, (256, 256))
122 | img_small = np.ascontiguousarray(img_small)
123 |
124 | img_norm = self._im_normalize(img_small)
125 | return img_pad, img_norm, pad
126 |
127 | def get_cropped_image(self, img, box, angle):
128 | # x1, y1, x2, y2
129 | # if abs(angle) > 90:
130 | # #self.box_shift *= -1
131 | # self.box_enlarge *= 1.1
132 | centre = ((box[0]+box[2])/2, (box[1]+box[3])/2)
133 | box_points = np.array([[box[0], box[3]],
134 | [box[0], box[1]],
135 | [box[2], box[1]],
136 | [box[2], box[3]]], dtype="float32")
137 | rot_M = cv2.getRotationMatrix2D(centre, angle, self.box_enlarge)
138 | rotated_box = cv2.transform(np.array([box_points]), rot_M)[0]
139 |
140 | width = (box[2]-box[0])
141 |
142 | x_shift = +np.sin(np.deg2rad(angle)) * width * self.box_shift
143 | y_shift = +np.cos(np.deg2rad(angle)) * width * self.box_shift
144 |
145 | trans_M = np.float32([ [1,0,x_shift], [0,1,y_shift] ])
146 | # print(rotated_box.shape)
147 | # print(trans_M.shape)
148 | rot_trans_box = cv2.transform(np.array([rotated_box]), trans_M)[0]
149 |
150 | new_width = int(width * self.box_enlarge)
151 | src_pts = rot_trans_box.astype("float32")
152 |
153 | dst_pts = np.array([[0, 255],
154 | [0, 0],
155 | [255, 0],
156 | [255, 255]], dtype="float32")
157 |
158 | # the perspective transformation matrix
159 | crop_M = cv2.getPerspectiveTransform(src_pts, dst_pts)
160 | # directly warp the rotated rectangle to get the straightened rectangle
161 | cropped_image = cv2.warpPerspective(img, crop_M, (256, 256))
162 | return cropped_image, [src_pts, dst_pts], rot_trans_box
163 |
164 | def inv_crop_transform(self, trans_pts, crop_keypoints):
165 | src_pts = trans_pts[1]
166 | dst_pts = trans_pts[0]
167 | trans_M = cv2.getPerspectiveTransform(src_pts, dst_pts)
168 | #print(trans_M.shape)
169 | img_keypoints = cv2.transform(np.array([crop_keypoints]), trans_M)[0]
170 |
171 | #print(img_keypoints.shape)
172 | return img_keypoints[:,:2]
173 |
174 | def get_box_rotation(self, keypoints, shape):
175 | if self.calculate_palm:
176 | middle_direction = (keypoints[2]-keypoints[0])
177 | else:
178 | middle_direction = (((keypoints[5]+keypoints[13])*0.5+keypoints[9])*0.5-keypoints[0])
179 |
180 | angle = np.arctan2(-middle_direction[1], middle_direction[0]) * 180 / np.pi - 90
181 |
182 | if self.calculate_palm:
183 | palm_idxs = [i for i in range(7)]
184 | else:
185 | palm_idxs = [0,1,2,3,5,6,9,10,13,14,17,18] # [i for i in range(21)]#
186 | #palm_idxs = [0,1,2,3,5,6,9,10,13,14,17,18]
187 |
188 | xmax, xmin = keypoints[palm_idxs,0].max(), keypoints[palm_idxs,0].min()
189 | ymax, ymin = keypoints[palm_idxs,1].max(), keypoints[palm_idxs,1].min()
190 |
191 | centre = ((xmax+xmin)/2, (ymax+ymin)/2)
192 | side = max((xmax-xmin), (ymax-ymin))
193 |
194 | # side = max(side, 240/640 *256 / self.box_enlarge)
195 | # side = min(side, 300/640 *256 / self.box_enlarge)
196 | # side = max(side, 120/640 *256 / self.box_enlarge)
197 | # side = min(side, 240/640 *256 / self.box_enlarge)
198 |
199 | self.side_length = side
200 | self.angle = angle
201 | x1,y1 = max(int(centre[0]-side/2),0), max(int(centre[1]-side/2),0)
202 | x2,y2 = min(int(centre[0]+side/2),shape[1]), min(int(centre[1]+side/2),shape[0])
203 |
204 | box = [x1, y1, x2, y2]
205 |
206 | return box, angle, keypoints[palm_idxs]
207 |
208 |
209 | def __call__(self, img):
210 |
211 | self.left_hand = {"joints":None, "palm":None, "box":None}
212 | self.right_hand = {"joints":None, "palm":None, "box":None}
213 |
214 | img_pad, img_norm, pad = self.preprocess_img(img)
215 |
216 | self.box_enlarge = 2.6
217 | self.box_shift = -0.5
218 |
219 | palm_keypoints_list, side_list = self.detect_hand(img_norm)
220 | #palm_keypoints, side = self.detect_hand(img_norm)
221 | if palm_keypoints_list is None:
222 | return None, None, None
223 |
224 | for palm_keypoints in palm_keypoints_list:
225 |
226 | box, angle, kp_considered = self.get_box_rotation(palm_keypoints, img_norm.shape)
227 | cropped, trans_pts, box_considered = self.get_cropped_image(img_norm, box, angle)
228 | img_landmark = cropped #hand_square
229 |
230 | # calculate joints
231 | joints_3d, flag, handedness = self.predict_joints(img_landmark)
232 | joints = joints_3d.copy()[:,:2]
233 | rotated_joints = self.inv_crop_transform(trans_pts, joints)
234 |
235 | kp_orig = rotated_joints
236 | kp_palm = kp_considered
237 | box = box_considered.astype(float)
238 | box *= max(img.shape[0], img.shape[1])/256
239 | kp_orig *= max(img.shape[0], img.shape[1])/256
240 | kp_palm *= max(img.shape[0], img.shape[1])/256
241 |
242 | kp_orig -= pad[::-1]
243 | box -= pad[::-1]
244 | kp_palm -= pad[::-1]
245 |
246 | if handedness == "left":
247 | self.left_hand["joints"] = joints_3d
248 | self.left_hand["joints"][:,:2] = kp_orig
249 | self.left_hand["box"] = box
250 | self.left_hand["palm"] = kp_palm
251 | self.left_hand["angle"] = angle
252 |
253 | else:
254 | self.right_hand["joints"] = joints_3d
255 | self.right_hand["joints"][:,:2] = kp_orig
256 | self.right_hand["box"] = box
257 | self.right_hand["palm"] = kp_palm
258 | self.right_hand["angle"] = angle
259 |
260 | # self.joint_3d_coords[:,:2] = kp_orig
261 | # self.box_hand = box
262 |
263 | # if kp_palm.shape[0] == 7:
264 | # self.palm_keypoints = kp_palm
265 | # else:
266 | # self.palm_keypoints = kp_palm[[0,1,4,6,8,10],:]
--------------------------------------------------------------------------------
/nms.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 |
3 |
4 | def non_max_suppression_fast(boxes, probabilities=None, overlap_threshold=0.3):
5 | """
6 | Algorithm to filter bounding box proposals by removing the ones with a too low confidence score
7 | and with too much overlap.
8 | Source: https://www.pyimagesearch.com/2015/02/16/faster-non-maximum-suppression-python/
9 | :param boxes: List of proposed bounding boxes
10 | :param overlap_threshold: the maximum overlap that is allowed
11 | :return: filtered boxes
12 | """
13 | # if there are no boxes, return an empty list
14 | if boxes.shape[1] == 0:
15 | return []
16 | # if the bounding boxes integers, convert them to floats --
17 | # this is important since we'll be doing a bunch of divisions
18 | if boxes.dtype.kind == "i":
19 | boxes = boxes.astype("float")
20 | # initialize the list of picked indexes
21 | pick = []
22 | # grab the coordinates of the bounding boxes
23 | x1 = boxes[:, 0] - (boxes[:, 2] / [2]) # center x - width/2
24 | y1 = boxes[:, 1] - (boxes[:, 3] / [2]) # center y - height/2
25 | x2 = boxes[:, 0] + (boxes[:, 2] / [2]) # center x + width/2
26 | y2 = boxes[:, 1] + (boxes[:, 3] / [2]) # center y + height/2
27 |
28 | # compute the area of the bounding boxes and grab the indexes to sort
29 | # (in the case that no probabilities are provided, simply sort on the
30 | # bottom-left y-coordinate)
31 | area = boxes[:, 2] * boxes[:, 3] # width * height
32 | idxs = y2
33 |
34 |
35 | # if probabilities are provided, sort on them instead
36 | if probabilities is not None:
37 | idxs = probabilities
38 |
39 | # sort the indexes
40 | idxs = np.argsort(idxs)
41 | # keep looping while some indexes still remain in the indexes
42 | # list
43 | while len(idxs) > 0:
44 | # grab the last index in the indexes list and add the
45 | # index value to the list of picked indexes
46 | last = len(idxs) - 1
47 | i = idxs[last]
48 | pick.append(i)
49 | # find the largest (x, y) coordinates for the start of
50 | # the bounding box and the smallest (x, y) coordinates
51 | # for the end of the bounding box
52 | xx1 = np.maximum(x1[i], x1[idxs[:last]])
53 | yy1 = np.maximum(y1[i], y1[idxs[:last]])
54 | xx2 = np.minimum(x2[i], x2[idxs[:last]])
55 | yy2 = np.minimum(y2[i], y2[idxs[:last]])
56 | # compute the width and height of the bounding box
57 | w = np.maximum(0, xx2 - xx1 + 1)
58 | h = np.maximum(0, yy2 - yy1 + 1)
59 | # compute the ratio of overlap
60 | overlap = (w * h) / area[idxs[:last]]
61 | # delete all indexes from the index list that have
62 | idxs = np.delete(idxs, np.concatenate(([last],
63 | np.where(overlap > overlap_threshold)[0])))
64 | # return only the bounding boxes that were picked
65 | return pick
--------------------------------------------------------------------------------
/out.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TviNet/Multi-HandTrackingGPU/db4fab504073f11b9c14fef8ebd9fdcfc2c3db0f/out.gif
--------------------------------------------------------------------------------
/palm_detection_builtin.pb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TviNet/Multi-HandTrackingGPU/db4fab504073f11b9c14fef8ebd9fdcfc2c3db0f/palm_detection_builtin.pb
--------------------------------------------------------------------------------
/palm_detection_without_custom_op.tflite:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TviNet/Multi-HandTrackingGPU/db4fab504073f11b9c14fef8ebd9fdcfc2c3db0f/palm_detection_without_custom_op.tflite
--------------------------------------------------------------------------------
/process_keypoints.py:
--------------------------------------------------------------------------------
1 | import cv2
2 | import numpy as np
3 | import matplotlib.pyplot as plt
4 | from mpl_toolkits.mplot3d import Axes3D
5 | import open3d
6 | from config import *
7 |
8 | # 8 12 16 20
9 | # | | | |
10 | # 7 11 15 19
11 | # 4 | | | |
12 | # | 6 10 14 18
13 | # 3 | | | |
14 | # | 5---9---13--17
15 | # 2 \ /
16 | # \ \ /
17 | # 1 \ /
18 | # \ \ /
19 | # ------0-
20 |
21 | def rotation_matrix_from_vectors(vec1, vec2):
22 | """ Find the rotation matrix that aligns vec1 to vec2
23 | :param vec1: A 3d "source" vector
24 | :param vec2: A 3d "destination" vector
25 | :return mat: A transform matrix (3x3) which when applied to vec1, aligns it with vec2.
26 | """
27 | a, b = (vec1 / np.linalg.norm(vec1)).reshape(3), (vec2 / np.linalg.norm(vec2)).reshape(3)
28 | v = np.cross(a, b)
29 | c = np.dot(a, b)
30 | s = np.linalg.norm(v)
31 | kmat = np.array([[0, -v[2], v[1]], [v[2], 0, -v[0]], [-v[1], v[0], 0]])
32 | rotation_matrix = np.eye(3) + kmat + kmat.dot(kmat) * ((1 - c) / (s ** 2))
33 | return rotation_matrix
34 |
35 | def find_finger_lengths(keypoints):
36 | fingers = [[i*4 + j +1 for j in range(4)] for i in range(5)]
37 | lengths = []
38 | for finger in fingers:
39 | f = finger[1:]
40 | f_shifted = finger[:-1]
41 | lengths.append(np.sqrt(((keypoints[f] - keypoints[f_shifted])**2).sum(1)).sum(0))
42 | return lengths
43 |
44 | def normalize_keypoints(keypoints):
45 | palm_len = np.sqrt(((keypoints[9]-keypoints[0])**2).sum())
46 | norm_keypoints = (keypoints-keypoints[0]) / palm_len
47 |
48 | rot_mat = rotation_matrix_from_vectors(keypoints[9], np.array([0,-1,0]))
49 | rot_keypoints = norm_keypoints @ rot_mat
50 | return rot_keypoints, norm_keypoints
51 |
52 | def orientation_keypoints(keypoints):
53 | middle_direction = (keypoints[2]-keypoints[0])[:2]
54 | angle = np.arctan2(-middle_direction[1], middle_direction[0]) * 180 / np.pi
55 | return angle
56 |
57 | def plot_keypoints(keypoints):
58 | #o3.PointCloud = o3.geometry.PointCloud
59 | point_cloud = open3d.geometry.PointCloud()
60 | point_cloud.points = open3d.utility.Vector3dVector(keypoints)
61 | open3d.visualization.draw_geometries([point_cloud])
62 |
63 | def smooth_keypoints(keypoints_list):
64 | # smooth_points = np.zeros_like(keypoints_list[0])
65 | # for i in range(len(FILTER_COEFFS)):
66 | # smooth_points += FILTER_COEFFS[i] * keypoints_list[i]
67 | smooth_points = (np.array(FILTER_COEFFS)[:,None] * np.array(keypoints_list)).sum(0)
68 | return smooth_points
69 |
--------------------------------------------------------------------------------
/run.py:
--------------------------------------------------------------------------------
1 | import cv2
2 | import numpy as np
3 | from PIL import Image
4 |
5 | from hand_tracker_multi import HandTracker
6 | from process_keypoints import *
7 | from gesture import Gestures
8 | from trainer import TrainData, Model
9 | from control import Control
10 | from drawing_helpers import *
11 | import time
12 | from config import *
13 | import os
14 | import requests
15 |
16 | cv2.namedWindow(WINDOW)
17 |
18 | if not GET_IPWEBCAM:
19 | capture = cv2.VideoCapture(VIDEO)
20 | result = cv2.VideoWriter('output.avi',
21 | cv2.VideoWriter_fourcc(*'MJPG'),
22 | 10, (640, 480))
23 | images = []
24 | # capture.set(cv2.CAP_PROP_AUTO_EXPOSURE,0)
25 | # capture.set(cv2.CAP_PROP_EXPOSURE,-6)
26 |
27 | if capture.isOpened():
28 | hasFrame, frame = capture.read()
29 | else:
30 | hasFrame = False
31 | else:
32 | img_req = requests.get(IMAGE)
33 | img_arr = np.array(bytearray(img_req.content), dtype=np.uint8)
34 | frame = cv2.imdecode(img_arr, -1)
35 | hasFrame =True
36 |
37 | print(frame.shape)
38 | detector = HandTracker(
39 | PALM_MODEL_PATH,
40 | LANDMARK_MODEL_PATH,
41 | ANCHORS_PATH,
42 | )
43 |
44 | #gesture = Gestures()
45 | #control = Control()
46 | #control.update_position([NATIVE_RES_X//2 , NATIVE_RES_Y//2])
47 | #trainer = TrainData()
48 | #model = Model(MODEL_TYPE)
49 | #trainer.read_data(SAVE_FILE)
50 |
51 | def hist_eq(frame):
52 | lab = cv2.cvtColor(frame, cv2.COLOR_BGR2LAB)
53 | clahe = cv2.createCLAHE(clipLimit=4)
54 | lab[...,0] = clahe.apply(lab[...,0])
55 | frame = cv2.cvtColor(lab, cv2.COLOR_LAB2BGR)
56 | return frame
57 |
58 | def gamma_correc(frame, gamma = 1.0):
59 | invGamma = 1 / gamma
60 | table = np.array([ ( (i/255)**invGamma ) * 255 for i in range(0,256)]).astype(np.uint8)
61 | return cv2.LUT(frame, table)
62 |
63 | def process_hand(frame, hand_data, hand_name, hand_history):
64 |
65 | box = hand_data["box"]
66 | palm_points = hand_data["palm"]
67 | angle = hand_data["angle"]
68 | points = hand_data["joints"][:,:2]
69 |
70 | if box is not None:
71 | draw_box(frame, box)
72 |
73 | if palm_points is not None:
74 | pass
75 | #draw_keypoints(frame, palm_points)
76 |
77 | if points is not None:
78 |
79 | rot_keypoints, norm_keypoints = normalize_keypoints(hand_data["joints"])
80 | orientation = orientation_keypoints(hand_data["joints"])
81 |
82 | #control.update_position(detector.joint_3d_coords[8,:2].tolist())
83 | if hand_name == "left":
84 | box_centre = hand_data["joints"][5,:2]#detector.palm_keypoints.astype(float).mean(0)
85 | #box_centre = np.array(box.mean(axis=0)).astype(float)
86 |
87 | angle = angle - 10 #orientation - 90 - 10
88 | x_shift = 0#+np.sin(np.deg2rad(angle)) * 30 * -2
89 | y_shift = 0#+np.cos(np.deg2rad(angle)) * 30 * -2
90 | pointing = box_centre + np.array([x_shift, y_shift])
91 |
92 | hand_history.append(pointing)
93 |
94 | if len(hand_history) > len(FILTER_COEFFS):
95 | #hand_history = hand_history[1:]
96 | hand_history.pop(0)
97 | smoothed_keypoints = smooth_keypoints(hand_history)
98 | else:
99 | smoothed_keypoints = hand_history[-1]
100 | #control.update_position(smoothed_keypoints)
101 | # cv2.circle(frame, (int(smoothed_keypoints[0]), int(smoothed_keypoints[1])), 10, (255, 255, 255), -1)
102 | else:
103 | # ges, ges_desc, ges_ang = gesture.estimate_gesture(rot_keypoints)
104 | # ges_predict = model.predict([ges_ang])
105 | # ges_avg = gesture.current_detected_gesture(ges_predict)
106 | # #control.command(ges_avg)
107 | # # draw_text(frame, ges_predict, ges_avg)
108 | # gesture.empty()
109 | pass
110 |
111 | draw_keypoints(frame, points)
112 | draw_connections(frame, points)
113 |
114 | if LOG:
115 | print(pos, end=", ")
116 | print(ang, end=", ")
117 | print(ges_ang * 180 / np.pi, end=", ")
118 |
119 | left_history = []
120 | right_history = []
121 | # for key in trainer.train_data.keys():
122 | # print(f"{key}-{len(trainer.train_data[key])}")
123 |
124 | while hasFrame:
125 | frame = cv2.flip(frame, 1)
126 | #frame = gamma_correc(frame, 2)
127 | image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
128 | # cv2.rectangle(frame, ((WEBCAM_X-CAM_RES_X)//2, (WEBCAM_Y-CAM_RES_Y)//2), (WEBCAM_X - (WEBCAM_X-CAM_RES_X)//2, WEBCAM_Y - (WEBCAM_Y-CAM_RES_Y)//2), (0, 0, 255), 2)
129 | ts = time.time()
130 |
131 | detector(image)
132 |
133 | frame_time = time.time()-ts
134 | frame_rate = 1 / frame_time
135 |
136 | if LOG:
137 | print(detector.calculate_palm, end=", ")
138 | print(round(frame_time, 4), end=", ")
139 |
140 | if detector.left_hand["joints"] is not None:
141 | process_hand(frame, detector.left_hand, "left", left_history)
142 | else:
143 | left_history = []
144 |
145 | #print(len(right_history))
146 | if detector.right_hand["joints"] is not None:
147 | process_hand(frame, detector.right_hand, "right", right_history)
148 | else:
149 | right_history = []
150 |
151 | cv2.imshow(WINDOW, frame)
152 | #result.write(frame)
153 | #images.append(Image.fromarray(frame[:,:,::-1]))
154 |
155 | if not GET_IPWEBCAM:
156 | hasFrame, frame = capture.read()
157 | else:
158 | img_req = requests.get(IMAGE)
159 | img_arr = np.array(bytearray(img_req.content), dtype=np.uint8)
160 | frame = cv2.imdecode(img_arr, -1)
161 | hasFrame = True
162 |
163 | total_time = time.time()-ts
164 | total_rate = 1 / total_time
165 | if LOG:
166 | print(round(total_time, 4), end=", ")
167 | print()
168 |
169 | key = cv2.waitKey(1)
170 | if key == ord('s'):
171 | #trainer.add_data(TRAIN_GESTURE, ges_ang)
172 | pass
173 | elif key == 32:
174 | pass
175 | elif key == ord('d'):
176 | #trainer.delete_data(TRAIN_GESTURE)
177 | pass
178 | elif key == 27:
179 | break
180 |
181 | # images[0].save('out.gif',
182 | # save_all=True, append_images=images[1:], optimize=False, duration=40, loop=0)
183 | #trainer.save_data(SAVE_FILE)
184 | capture.release()
185 | cv2.destroyAllWindows()
186 |
--------------------------------------------------------------------------------
/trainer.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import cv2
3 | import pickle
4 | import os
5 | from sklearn import tree
6 | from sklearn import svm
7 | from sklearn.pipeline import make_pipeline
8 | from sklearn.preprocessing import StandardScaler
9 | from config import *
10 |
11 | class TrainData:
12 | def __init__(self):
13 | self.train_data = {}
14 |
15 | def read_data(self, filename):
16 | if not os.path.exists(filename):
17 | self.train_data = {}
18 | else:
19 | with open(filename, 'rb') as f:
20 | self.train_data = pickle.load(f)
21 |
22 | def save_data(self, filename):
23 | with open(filename, 'wb') as f:
24 | pickle.dump(self.train_data, f)
25 |
26 | def add_data(self, key, value):
27 | if key not in self.train_data.keys():
28 | self.train_data[key] = []
29 | self.train_data[key].append(value)
30 |
31 | def delete_data(self, key):
32 | self.train_data[key] = self.train_data[key][:-1]
33 |
34 | def delete_key(self, key):
35 | self.train_data.pop(key, None)
36 |
37 | class Train:
38 | def __init__(self):
39 | self.X = []
40 | self.Y = []
41 | self.labels = []
42 | self.tree_graph = None
43 |
44 | def generate_train_data(self, train_data):
45 |
46 | for key in train_data.keys():
47 | if SKIP_THUMB:
48 | x_array = [x[1:, :].flatten() for x in train_data[key]]
49 | else:
50 | x_array = [x.flatten() for x in train_data[key]]
51 | self.X.extend(x_array)
52 | y_array = [len(self.labels) for y in train_data[key]]
53 | self.Y.extend(y_array)
54 | self.labels.append(key)
55 |
56 | self.X = np.array(self.X)
57 | self.Y = np.array(self.Y)
58 |
59 |
60 | def train(self, t):
61 | if t == "tree":
62 | clf = tree.DecisionTreeClassifier()
63 | clf = clf.fit(self.X, self.Y)
64 | self.tree_graph = tree.plot_tree(clf)
65 | model = {}
66 | model['clf'] = clf
67 | model['graph'] = self.tree_graph
68 | with open("Models/decision_tree.pkl", 'wb') as f:
69 | pickle.dump(model, f)
70 | else:
71 | clf = make_pipeline(StandardScaler(), svm.SVC(kernel='rbf'))
72 | clf = clf.fit(self.X, self.Y)
73 | model = {}
74 | model['clf'] = clf
75 | with open("Models/svm.pkl", 'wb') as f:
76 | pickle.dump(model, f)
77 |
78 | def show_graph(self):
79 | with open("Models/decision_tree.pkl", 'rb') as f:
80 | saved = pickle.load(f)
81 | #tree.plot_tree()
82 | from graphviz import Source
83 | graph = Source( tree.export_graphviz(saved['clf'], out_file=None))
84 | png_bytes = graph.pipe(format='png')
85 | with open('dtree_pipe.png','wb') as f:
86 | f.write(png_bytes)
87 |
88 | def load_model(self):
89 | with open("Models/decision_tree.pkl", 'rb') as f:
90 | self.model = pickle.load(f)
91 |
92 | def predict(self, input):
93 | if SKIP_THUMB:
94 | x_array = [x[1:,:].flatten() for x in input]
95 | else:
96 | x_array = [x.flatten() for x in input]
97 | y_array = self.model['clf'].predict(x_array)
98 | return y_array
99 |
100 | class Model:
101 | def __init__(self, t):
102 | if t == "tree":
103 | with open("Models/decision_tree.pkl", 'rb') as f:
104 | self.model = pickle.load(f)
105 | else:
106 | with open("Models/svm.pkl", 'rb') as f:
107 | self.model = pickle.load(f)
108 |
109 |
110 | def predict(self, input):
111 | if SKIP_THUMB:
112 | x_array = [x[1:,:].flatten() for x in input]
113 | else:
114 | x_array = [x.flatten() for x in input]
115 | y_array = self.model['clf'].predict(x_array)
116 | return y_array
117 |
118 | def delete_key(self, key):
119 | self.model.pop(key, None)
120 |
121 |
122 | if __name__ == "__main__":
123 |
124 | trainer = Train()
125 | with open("DATASET/train.pkl", 'rb') as f:
126 | train_data = pickle.load(f)
127 | trainer.generate_train_data(train_data)
128 | trainer.train('svm')
129 |
130 | #trainer.show_graph()
131 |
132 | # model = Model()
133 | # model.delete_key('PINCH')
134 |
135 |
136 | # data = TrainData()
137 | # data.read_data("DATASET/train.pkl")
138 | # print(data.train_data.keys())
139 | # data.delete_key('PINCH')
140 | # data.save_data("DATASET/train.pkl")
141 | # print(data.train_data.keys())
--------------------------------------------------------------------------------