├── 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 | ![Output](/out.gif?raw=true "Output") 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()) --------------------------------------------------------------------------------