減色プログラム
Revisión | 95b8d64e57d46db43351d561b189aa89e28c59c8 (tree) |
---|---|
Tiempo | 2011-05-21 03:52:36 |
Autor | berupon <berupon@gmai...> |
Commiter | berupon |
removed signed/unsigned mixed code.
changed temperature variable type from float to double.
@@ -40,16 +40,6 @@ void fill_random(Array3D<float>& a) | ||
40 | 40 | } |
41 | 41 | } |
42 | 42 | |
43 | -float get_initial_temperature() | |
44 | -{ | |
45 | - return 2.0f; // TODO: Figure out what to make this | |
46 | -} | |
47 | - | |
48 | -float get_final_temperature() | |
49 | -{ | |
50 | - return 0.02f; // TODO: Figure out what to make this | |
51 | -} | |
52 | - | |
53 | 43 | void random_permutation( |
54 | 44 | size_t count, |
55 | 45 | vector<size_t>& result |
@@ -91,16 +81,16 @@ void compute_b_array( | ||
91 | 81 | { |
92 | 82 | // Assume that the pixel i is always located at the center of b, |
93 | 83 | // and vary pixel j's location through each location in b. |
94 | - size_t radius_width = (filter_weights.width_ - 1)/2; | |
95 | - size_t radius_height = (filter_weights.height_ - 1)/2; | |
96 | - size_t offset_x = (b.width_ - 1)/2 - radius_width; | |
97 | - size_t offset_y = (b.height_ - 1)/2 - radius_height; | |
84 | + int radius_width = (filter_weights.width_ - 1)/2; | |
85 | + int radius_height = (filter_weights.height_ - 1)/2; | |
86 | + int offset_x = (b.width_ - 1)/2 - radius_width; | |
87 | + int offset_y = (b.height_ - 1)/2 - radius_height; | |
98 | 88 | for (int j_y=0; j_y<b.height_; ++j_y) { |
99 | 89 | for (int j_x=0; j_x<b.width_; ++j_x) { |
100 | 90 | Color4f sum; |
101 | 91 | sum.zero(); |
102 | - for (size_t k_y=0; k_y < filter_weights.height_; ++k_y) { | |
103 | - for (size_t k_x = 0; k_x < filter_weights.width_; ++k_x) { | |
92 | + for (int k_y=0; k_y < filter_weights.height_; ++k_y) { | |
93 | + for (int k_x = 0; k_x < filter_weights.width_; ++k_x) { | |
104 | 94 | if (k_x+offset_x >= j_x - radius_width && |
105 | 95 | k_x+offset_x <= j_x + radius_width && |
106 | 96 | k_y+offset_y >= j_y - radius_width && |
@@ -119,12 +109,12 @@ void compute_b_array( | ||
119 | 109 | } |
120 | 110 | |
121 | 111 | __forceinline |
122 | -Color4f b_value(const Image4f& b, size_t i_x, size_t i_y, size_t j_x, size_t j_y) | |
112 | +Color4f b_value(const Image4f& b, int i_x, int i_y, int j_x, int j_y) | |
123 | 113 | { |
124 | - size_t radius_width = (b.width_ - 1)/2; | |
125 | - size_t radius_height = (b.height_ - 1)/2; | |
126 | - size_t k_x = j_x - i_x + radius_width; | |
127 | - size_t k_y = j_y - i_y + radius_height; | |
114 | + int radius_width = (b.width_ - 1)/2; | |
115 | + int radius_height = (b.height_ - 1)/2; | |
116 | + int k_x = j_x - i_x + radius_width; | |
117 | + int k_y = j_y - i_y + radius_height; | |
128 | 118 | if (k_x >= 0 && k_y >= 0 && k_x < b.width_ && k_y < b.height_) |
129 | 119 | return b[k_y][k_x]; |
130 | 120 | else { |
@@ -280,11 +270,16 @@ void compute_initial_s( | ||
280 | 270 | ) |
281 | 271 | { |
282 | 272 | init_image(s); |
283 | - const size_t palette_size = s.width_; | |
284 | - const size_t coarse_width = coarse_variables.width_; | |
285 | - const size_t coarse_height = coarse_variables.height_; | |
286 | - const size_t center_x = (b.width_-1)/2, center_y = (b.height_-1)/2; | |
287 | - | |
273 | + size_t palette_size = s.width_; | |
274 | + int coarse_width = coarse_variables.width_; | |
275 | + int coarse_height = coarse_variables.height_; | |
276 | + int center_x = (b.width_-1)/2, center_y = (b.height_-1)/2; | |
277 | + | |
278 | + printf( | |
279 | + "%s started %d %d %d\n", | |
280 | + __FUNCTION__, palette_size, coarse_width, coarse_height | |
281 | + ); | |
282 | + | |
288 | 283 | Color4f center_b = b_value(b,0,0,0,0); |
289 | 284 | Color4f zero_vector; |
290 | 285 | zero_vector.zero(); |
@@ -293,19 +288,21 @@ void compute_initial_s( | ||
293 | 288 | s[alpha][v] = zero_vector; |
294 | 289 | } |
295 | 290 | } |
296 | - for (size_t i_y=0; i_y<coarse_height; ++i_y) { | |
297 | - for (size_t i_x=0; i_x<coarse_width; ++i_x) { | |
291 | + for (int i_y=0; i_y<coarse_height; ++i_y) { | |
292 | + for (int i_x=0; i_x<coarse_width; ++i_x) { | |
298 | 293 | const float* p_icv = &coarse_variables(i_x, i_y, 0); |
299 | - const size_t max_j_x = min<int>(coarse_width, i_x - center_x + b.width_); | |
300 | - const size_t max_j_y = min<int>(coarse_height, i_y - center_y + b.height_); | |
294 | + const int max_j_x = min<int>(coarse_width, i_x - center_x + b.width_); | |
295 | + const int max_j_y = min<int>(coarse_height, i_y - center_y + b.height_); | |
301 | 296 | for (size_t j_y=max<int>(0, i_y - center_y); j_y<max_j_y; ++j_y) { |
302 | - for (size_t j_x=max<int>(0, i_x - center_x); j_x<max_j_x; ++j_x) { | |
297 | + for (int j_x=max<int>(0, i_x - center_x); j_x<max_j_x; ++j_x) { | |
303 | 298 | if (i_x == j_x && i_y == j_y) continue; |
304 | 299 | Color4f b_ij = b_value(b,i_x,i_y,j_x,j_y); |
305 | 300 | for (size_t v=0; v<palette_size; ++v) { |
306 | 301 | Color4f b_ij2 = b_ij * p_icv[v]; |
307 | 302 | const float* p_jcv = &coarse_variables(j_x, j_y, v); |
308 | 303 | Color4f* ps = s.pBuff_ + v * palette_size + v; |
304 | +// TODO: 変更画像、縦方向ではなく横方向に操作する。後で転置。 | |
305 | +// TODO: Color4fの全ての要素が同じなので、Array2D<Color4f> ではなく Array2D<float> で処理してみる。 | |
309 | 306 | for (size_t alpha=v; alpha<palette_size; ++alpha) { |
310 | 307 | *ps += (*p_jcv++) * b_ij2; |
311 | 308 | ps += palette_size; |
@@ -327,12 +324,12 @@ void update_s( | ||
327 | 324 | const int j_x, |
328 | 325 | const int j_y, |
329 | 326 | const int alpha, |
330 | - const float delta | |
327 | + const double delta | |
331 | 328 | ) |
332 | 329 | { |
333 | 330 | const size_t palette_size = s.width_; |
334 | - const size_t coarse_width = coarse_variables.width_; | |
335 | - const size_t coarse_height = coarse_variables.height_; | |
331 | + const int coarse_width = coarse_variables.width_; | |
332 | + const int coarse_height = coarse_variables.height_; | |
336 | 333 | const int center_x = (b.width_-1) / 2; |
337 | 334 | const int center_y = (b.height_-1) / 2; |
338 | 335 | const int max_i_x = min<int>(coarse_width, j_x + center_x + 1); |
@@ -431,8 +428,8 @@ void spatial_color_quant( | ||
431 | 428 | Array2D<uint8_t>& quantized_image, |
432 | 429 | Color4f* palette, size_t num_colors, |
433 | 430 | Array3D<float>*& p_coarse_variables, |
434 | - float initial_temperature, | |
435 | - float final_temperature, | |
431 | + double initial_temperature, | |
432 | + double final_temperature, | |
436 | 433 | int temps_per_level, |
437 | 434 | int repeats_per_temp |
438 | 435 | ) |
@@ -446,7 +443,7 @@ void spatial_color_quant( | ||
446 | 443 | Array3D<float>& coarse_variables = *p_coarse_variables; |
447 | 444 | fill_random(coarse_variables); |
448 | 445 | |
449 | - float temperature = initial_temperature; | |
446 | + double temperature = initial_temperature; | |
450 | 447 | |
451 | 448 | // Compute a_i, b_{ij} according to (11) |
452 | 449 | size_t extended_neighborhood_width = filter_weights.width_*2 - 1; |
@@ -494,7 +491,7 @@ void spatial_color_quant( | ||
494 | 491 | // Multiscale annealing |
495 | 492 | coarse_level = max_coarse_level; |
496 | 493 | const size_t iters_per_level = temps_per_level; |
497 | - float temperature_multiplier = pow(final_temperature/initial_temperature, 1.0f/(max<size_t>(3, max_coarse_level*iters_per_level))); | |
494 | + double temperature_multiplier = pow(final_temperature/initial_temperature, 1.0/(max<size_t>(3, max_coarse_level*iters_per_level))); | |
498 | 495 | #if TRACE |
499 | 496 | cout << "Temperature multiplier: " << temperature_multiplier << endl; |
500 | 497 | #endif |
@@ -526,20 +523,20 @@ void spatial_color_quant( | ||
526 | 523 | |
527 | 524 | while (!visit_queue.empty()) { |
528 | 525 | // If we get to 10% above initial size, just revisit them all |
529 | - if ((size_t)visit_queue.size() > coarse_variables.width_*coarse_variables.height_*11/10) { | |
526 | + if (visit_queue.size() > coarse_variables.width_*coarse_variables.height_*11/10) { | |
530 | 527 | visit_queue.clear(); |
531 | 528 | random_permutation_2d(coarse_variables.width_, coarse_variables.height_, visit_queue); |
532 | 529 | } |
533 | 530 | |
534 | - size_t i_x = visit_queue.front().first; | |
535 | - size_t i_y = visit_queue.front().second; | |
531 | + int i_x = visit_queue.front().first; | |
532 | + int i_y = visit_queue.front().second; | |
536 | 533 | visit_queue.pop_front(); |
537 | 534 | |
538 | 535 | // Compute (25) |
539 | 536 | Color4f p_i; |
540 | 537 | p_i.zero(); |
541 | - for (size_t y=0; y<b.height_; ++y) { | |
542 | - for (size_t x=0; x<b.width_; ++x) { | |
538 | + for (int y=0; y<b.height_; ++y) { | |
539 | + for (int x=0; x<b.width_; ++x) { | |
543 | 540 | int j_x = x - center_x + i_x; |
544 | 541 | int j_y = y - center_y + i_y; |
545 | 542 | if (i_x == j_x && i_y == j_y) continue; |
@@ -581,7 +578,7 @@ void spatial_color_quant( | ||
581 | 578 | // Prevent the matrix S from becoming singular |
582 | 579 | if (new_val <= 0) new_val = 1e-10; |
583 | 580 | if (new_val >= 1) new_val = 1 - 1e-10; |
584 | - float delta_m_iv = new_val - coarse_variables(i_x,i_y,v); | |
581 | + double delta_m_iv = new_val - coarse_variables(i_x,i_y,v); | |
585 | 582 | coarse_variables(i_x,i_y,v) = new_val; |
586 | 583 | j_pal += delta_m_iv * palette[v]; |
587 | 584 | if (abs(delta_m_iv) > 0.001 && !skip_palette_maintenance) { |
@@ -597,10 +594,10 @@ void spatial_color_quant( | ||
597 | 594 | // to be visited, it'll probably be added when we visit |
598 | 595 | // neighboring pixels. |
599 | 596 | // The commented out loops are faster but cause a little bit of distortion |
600 | - //for (size_t y=center_y-1; y<center_y+1; y++) { | |
601 | - // for (size_t x=center_x-1; x<center_x+1; x++) { | |
602 | - for (size_t y=min<size_t>(1,center_y-1); y<max<size_t>(b.height_-1,center_y+1); ++y) { | |
603 | - for (size_t x=min<size_t>(1,center_x-1); x<max<size_t>(b.width_-1,center_x+1); ++x) { | |
597 | + //for (int y=center_y-1; y<center_y+1; y++) { | |
598 | + // for (int x=center_x-1; x<center_x+1; x++) { | |
599 | + for (int y=min(1,center_y-1); y<max<int>(b.height_-1,center_y+1); ++y) { | |
600 | + for (int x=min(1,center_x-1); x<max<int>(b.width_-1,center_x+1); ++x) { | |
604 | 601 | int j_x = x - center_x + i_x; |
605 | 602 | int j_y = y - center_y + i_y; |
606 | 603 | if (j_x < 0 || j_y < 0 || j_x >= coarse_variables.width_ || j_y >= coarse_variables.height_) continue; |
@@ -1,14 +1,14 @@ | ||
1 | -#pragma once | |
2 | - | |
1 | +#pragma once | |
2 | + | |
3 | 3 | void spatial_color_quant( |
4 | 4 | Image4f& image, |
5 | 5 | Image4f& filter_weights, |
6 | 6 | Array2D<uint8_t>& quantized_image, |
7 | 7 | Color4f* palette, size_t num_colors, |
8 | 8 | Array3D<float>*& p_coarse_variables, |
9 | - float initial_temperature, | |
10 | - float final_temperature, | |
9 | + double initial_temperature, | |
10 | + double final_temperature, | |
11 | 11 | int temps_per_level, |
12 | 12 | int repeats_per_temp |
13 | -); | |
13 | +); | |
14 | 14 |