Mercurial > ift6266
comparison transformations/local_elastic_distortions.py @ 52:c89defea1e65
Modification aux déformations élastiques pour mettre en cache 50x10 champs de déformation, selon 10 niveaux de complexité
author | fsavard |
---|---|
date | Thu, 04 Feb 2010 16:53:50 -0500 |
parents | a8ac3402eb45 |
children | b3d76ebf2fac |
comparison
equal
deleted
inserted
replaced
51:81b9567ec4ae | 52:c89defea1e65 |
---|---|
21 import math | 21 import math |
22 import numpy | 22 import numpy |
23 import numpy.random | 23 import numpy.random |
24 import scipy.signal # convolve2d | 24 import scipy.signal # convolve2d |
25 | 25 |
26 _TEST_DIR = "/home/francois/Desktop/dist_tests/" | 26 _TEST_DIR = "/u/savardf/ift6266/debug_images/" |
27 | 27 |
28 def _raw_zeros(size): | 28 def _raw_zeros(size): |
29 return [[0 for i in range(size[1])] for j in range(size[0])] | 29 return [[0 for i in range(size[1])] for j in range(size[0])] |
30 | 30 |
31 class ElasticDistortionParams(): | 31 class ElasticDistortionParams(): |
60 | 60 |
61 class LocalElasticDistorter(): | 61 class LocalElasticDistorter(): |
62 def __init__(self, image_size=(32,32)): | 62 def __init__(self, image_size=(32,32)): |
63 self.image_size = image_size | 63 self.image_size = image_size |
64 | 64 |
65 self.current_complexity = 0.0 | 65 self.current_complexity_10 = 0 |
66 self.current_complexity = 0 | |
66 | 67 |
67 # number of precomputed fields | 68 # number of precomputed fields |
68 # (principle: as complexity doesn't change often, we can | 69 # (principle: as complexity doesn't change often, we can |
69 # precompute a certain number of fields for a given complexity, | 70 # precompute a certain number of fields for a given complexity, |
70 # each with its own parameters. That way, we have good | 71 # each with its own parameters. That way, we have good |
71 # randomization, but we're much faster). | 72 # randomization, but we're much faster). |
72 self.to_precompute = 50 | 73 self.to_precompute_per_complexity = 50 |
73 | 74 |
74 # Both use ElasticDistortionParams | 75 # Both use ElasticDistortionParams |
75 self.current_params = None | 76 self.current_params = None |
76 self.precomputed_params = [] | 77 self.precomputed_params = [[] for i in range(10)] |
77 | 78 |
78 # | 79 # |
79 self.kernel_size = None | 80 self.kernel_size = None |
80 self.kernel = None | 81 self.kernel = None |
81 | 82 |
83 self.regenerate_parameters(0.0) | 84 self.regenerate_parameters(0.0) |
84 | 85 |
85 def get_settings_names(self): | 86 def get_settings_names(self): |
86 return ['alpha', 'sigma'] | 87 return ['alpha', 'sigma'] |
87 | 88 |
89 def _floor_complexity(self, complexity): | |
90 return self._to_complexity_10(complexity) / 10.0 | |
91 | |
92 def _to_complexity_10(self, complexity): | |
93 return min(9, max(0, int(complexity * 10))) | |
94 | |
88 def regenerate_parameters(self, complexity): | 95 def regenerate_parameters(self, complexity): |
89 if abs(complexity - self.current_complexity) > 1e-4: | 96 complexity_10 = self._to_complexity_10(complexity) |
90 self.current_complexity = complexity | 97 |
91 | 98 if complexity_10 != self.current_complexity_10: |
92 # complexity changed, fields must be regenerated | 99 self.current_complexity_10 = complexity_10 |
93 self.precomputed_params = [] | 100 self.current_complexity = self._floor_complexity(complexity) |
94 | 101 |
95 if len(self.precomputed_params) <= self.to_precompute: | 102 if len(self.precomputed_params[complexity_10]) <= self.to_precompute_per_complexity: |
96 # not yet enough params generated, produce one more | 103 # not yet enough params generated, produce one more |
97 # and append to list | 104 # and append to list |
98 new_params = self._initialize_new_params() | 105 new_params = self._initialize_new_params() |
99 new_params = self._generate_fields(new_params) | 106 new_params = self._generate_fields(new_params) |
100 self.current_params = new_params | 107 self.current_params = new_params |
101 self.precomputed_params.append(new_params) | 108 self.precomputed_params[complexity_10].append(new_params) |
102 else: | 109 else: |
103 # if we have enough precomputed fields, just select one | 110 # if we have enough precomputed fields, just select one |
104 # at random and set parameters to match what they were | 111 # at random and set parameters to match what they were |
105 # when the field was generated | 112 # when the field was generated |
106 idx = numpy.random.randint(0, len(self.precomputed_params)) | 113 idx = numpy.random.randint(0, len(self.precomputed_params[complexity_10])) |
107 self.current_params = self.precomputed_params[idx] | 114 self.current_params = self.precomputed_params[complexity_10][idx] |
108 | 115 |
109 # don't return anything, to avoid storing deterministic parameters | 116 # don't return anything, to avoid storing deterministic parameters |
110 return [] # self.current_params.alpha_sigma() | 117 return [] # self.current_params.alpha_sigma() |
111 | 118 |
112 def get_parameters_determined_by_complexity(self, complexity): | 119 def get_parameters_determined_by_complexity(self, complexity): |
113 tmp_params = self._initialize_new_params(complexity) | 120 tmp_params = self._initialize_new_params(_floor_complexity(complexity)) |
114 return tmp_params.alpha_sigma() | 121 return tmp_params.alpha_sigma() |
115 | 122 |
116 # adapted from http://blenderartists.org/forum/showthread.php?t=163361 | 123 # adapted from http://blenderartists.org/forum/showthread.php?t=163361 |
117 def _gen_gaussian_kernel(self, sigma): | 124 def _gen_gaussian_kernel(self, sigma): |
118 # the kernel size can change DRAMATICALLY the time | 125 # the kernel size can change DRAMATICALLY the time |
345 def _complexity_benchmark(): | 352 def _complexity_benchmark(): |
346 imgpath = os.path.join(_TEST_DIR, "d.png") | 353 imgpath = os.path.join(_TEST_DIR, "d.png") |
347 dist = LocalElasticDistorter((32,32)) | 354 dist = LocalElasticDistorter((32,32)) |
348 orig_img = _load_image(imgpath) | 355 orig_img = _load_image(imgpath) |
349 | 356 |
350 # time the first 10 | 357 for cpx in (0.21, 0.35): |
351 t1 = time.time() | 358 # time the first 10 |
352 for i in range(10): | 359 t1 = time.time() |
353 dist.regenerate_parameters(0.2) | 360 for i in range(10): |
354 img = dist.transform_image(orig_img) | 361 dist.regenerate_parameters(cpx) |
355 t2 = time.time() | 362 img = dist.transform_image(orig_img) |
356 | 363 t2 = time.time() |
357 print "first 10, total = ", t2-t1, ", avg=", (t2-t1)/10 | 364 |
358 | 365 print "first 10, total = ", t2-t1, ", avg=", (t2-t1)/10 |
359 # time the next 40 | 366 |
360 t1 = time.time() | 367 # time the next 40 |
361 for i in range(40): | 368 t1 = time.time() |
362 dist.regenerate_parameters(0.2) | 369 for i in range(40): |
363 img = dist.transform_image(orig_img) | 370 dist.regenerate_parameters(cpx) |
364 t2 = time.time() | 371 img = dist.transform_image(orig_img) |
365 | 372 t2 = time.time() |
366 print "next 40, total = ", t2-t1, ", avg=", (t2-t1)/40 | 373 |
367 | 374 print "next 40, total = ", t2-t1, ", avg=", (t2-t1)/40 |
368 # time the next 50 | 375 |
369 t1 = time.time() | 376 # time the next 50 |
370 for i in range(50): | 377 t1 = time.time() |
371 dist.regenerate_parameters(0.2) | 378 for i in range(50): |
372 img = dist.transform_image(orig_img) | 379 dist.regenerate_parameters(cpx) |
373 t2 = time.time() | 380 img = dist.transform_image(orig_img) |
374 | 381 t2 = time.time() |
375 print "next 50, total = ", t2-t1, ", avg=", (t2-t1)/50 | 382 |
376 | 383 print "next 50, total = ", t2-t1, ", avg=", (t2-t1)/50 |
377 # time the next 1000 | 384 |
385 # time the next 1000 | |
386 t1 = time.time() | |
387 for i in range(1000): | |
388 dist.regenerate_parameters(cpx) | |
389 img = dist.transform_image(orig_img) | |
390 t2 = time.time() | |
391 | |
392 print "next 1000, total = ", t2-t1, ", avg=", (t2-t1)/1000 | |
393 | |
394 # time the next 1000 with old complexity | |
378 t1 = time.time() | 395 t1 = time.time() |
379 for i in range(1000): | 396 for i in range(1000): |
380 dist.regenerate_parameters(0.2) | 397 dist.regenerate_parameters(0.21) |
381 img = dist.transform_image(orig_img) | 398 img = dist.transform_image(orig_img) |
382 t2 = time.time() | 399 t2 = time.time() |
383 | 400 |
384 print "next 1000, total = ", t2-t1, ", avg=", (t2-t1)/1000 | 401 print "next 1000, total = ", t2-t1, ", avg=", (t2-t1)/1000 |
402 | |
385 | 403 |
386 | 404 |
387 | 405 |
388 def _save_image(img, path): | 406 def _save_image(img, path): |
389 img2 = Image.fromarray((img * 255).astype('uint8'), "L") | 407 img2 = Image.fromarray((img * 255).astype('uint8'), "L") |
425 import pylab | 443 import pylab |
426 import Image | 444 import Image |
427 import os.path | 445 import os.path |
428 #_distorter_tests() | 446 #_distorter_tests() |
429 #_benchmark() | 447 #_benchmark() |
430 _specific_test() | 448 #_specific_test() |
431 #_complexity_tests() | 449 #_complexity_tests() |
432 #_complexity_benchmark() | 450 _complexity_benchmark() |
433 | 451 |
434 | 452 |
435 | 453 |