change the way that interations are performed at colorize algorithm
authorAndreas Eversberg <jolly@eversberg.eu>
Sat, 10 Oct 2015 15:29:05 +0000 (17:29 +0200)
committerAndreas Eversberg <jolly@eversberg.eu>
Sat, 14 May 2016 10:55:54 +0000 (12:55 +0200)
gui/colorize.c
lib/colorize.c
lib/colorize.h
lib/multigrid.c
lib/multigrid.h
src/colorize.c

index 31d01e6..c6b45de 100644 (file)
@@ -219,7 +219,7 @@ void colorize_image(void)
        cI = NULL;
 
        /* render u and v change */
-       rc = colorize(I, mI, NULL, NULL, 5, 1, 0, 0, feat_names, NULL);
+       rc = colorize(I, mI, NULL, NULL, 5, 10, 0.01, 0, 0, feat_names, NULL);
        if (rc < 0) {
                printerror("No memory! Use smaller image or add more memory.");
                goto error;
@@ -504,7 +504,7 @@ iterative colorization does not work with change_bc and change_alpha, because it
                set_I_ptr(I, mI, width, height, 0, features, change_alpha, change_bc, &ptr_y, &ptr_u, &ptr_v, &ptr_a, &ptr_r, &ptr_b, &ptr_c, &ptr_m);
 
                /* render u and v change */
-               rc = colorize(I, mI, NULL, NULL, 1, 1, 1, 0, feat_names, &col);
+               rc = colorize(I, mI, NULL, NULL, 1, 1, 0.0, 1, 0, feat_names, &col);
                if (rc < 0) {
                        printerror("No memory! Use smaller image or add more memory.");
                        thread_preview = PREVIEW_OFF;
index 6e5db8e..ab2dab9 100644 (file)
@@ -353,25 +353,32 @@ int colorize_solve(struct colorize *col, int quick, char **feat_names)
 #ifndef TEST_NO_RENDER
                /* colorize component */
                if (quick) {
-                       rc = solve_mg(col->max_depth, col->inner_iter, 1, col->values, col->marks, col->init, col->nb_list, col->flows_xy, col->scalexyz);
+                       rc = solve_mg(col->max_depth, col->inner_iter, 1, col->values, col->marks, col->init, col->nb_list, col->flows_xy, col->scalexyz, 0.0);
                        if (rc < 0)
                                goto error;
+               } else /*if (col->target_residual_change)*/ {
+                       rc = solve_mg(col->max_depth, col->inner_iter, col->outer_iter, col->values, col->marks, col->init, col->nb_list, col->flows_xy, col->scalexyz, col->target_residual_change);
+                       if (rc < 0)
+                               goto error;
+#if 0
                } else {
+                       /* original algorithm: handling of outer iteration */
                        int i;
                        for (i = 0; i < col->outer_iter; i++) {
-                               rc = solve_mg(col->max_depth, col->inner_iter, 2, col->values, col->marks, col->init, col->nb_list, col->flows_xy, col->scalexyz);
+                               rc = solve_mg(col->max_depth, col->inner_iter, 2, col->values, col->marks, col->init, col->nb_list, col->flows_xy, col->scalexyz, 0.0);
                                if (rc < 0)
                                        goto error;
-                               rc = solve_mg((col->max_depth+1) / 2, col->inner_iter, 2, col->values, col->marks, col->init, col->nb_list, col->flows_xy, col->scalexyz);
+                               rc = solve_mg((col->max_depth+1) / 2, col->inner_iter, 2, col->values, col->marks, col->init, col->nb_list, col->flows_xy, col->scalexyz, 0.0);
                                if (rc < 0)
                                        goto error;
-                               rc = solve_mg(2, col->inner_iter, 2, col->values, col->marks, col->init, col->nb_list, col->flows_xy, col->scalexyz);
+                               rc = solve_mg(2, col->inner_iter, 2, col->values, col->marks, col->init, col->nb_list, col->flows_xy, col->scalexyz, 0.0);
                                if (rc < 0)
                                        goto error;
-                               rc = solve_mg(1, col->inner_iter, 4, col->values, col->marks, col->init, col->nb_list, col->flows_xy, col->scalexyz);
+                               rc = solve_mg(1, col->inner_iter, 4, col->values, col->marks, col->init, col->nb_list, col->flows_xy, col->scalexyz, 0.0);
                                if (rc < 0)
                                        goto error;
                        }
+#endif
                }
 #endif
 
@@ -499,7 +506,7 @@ void colorize_free(struct colorize *col)
        darrayDestroy(col->init);
 }
 
-int colorize(const darray_t *image, const darray_t *image_mark, const darray_t *flow, const darray_t *flow_i, int inner_iter, int outer_iter, int quick, int scalexyz, char **feat_names, struct colorize **_col)
+int colorize(const darray_t *image, const darray_t *image_mark, const darray_t *flow, const darray_t *flow_i, int inner_iter, int outer_iter, double target_residual_change, int quick, int scalexyz, char **feat_names, struct colorize **_col)
 {
        struct colorize *col;
        int rc = -1;
@@ -514,6 +521,7 @@ int colorize(const darray_t *image, const darray_t *image_mark, const darray_t *
                col->flow_i = flow_i;
                col->inner_iter = inner_iter;
                col->outer_iter = outer_iter;
+               col->target_residual_change = target_residual_change;
                col->scalexyz = scalexyz;
                alloc = 1;
        }
index 22e93c2..c1f4c99 100644 (file)
@@ -9,6 +9,7 @@ struct colorize {
        const darray_t *flow_i;
        int inner_iter;
        int outer_iter;
+       double target_residual_change;
        int scalexyz;
 
        /* internal stuff */
@@ -26,5 +27,5 @@ int colorize_prepare(struct colorize *col, int quick, int alloc);
 int colorize_solve(struct colorize *col, int quick, char **feat_names);
 void colorize_free(struct colorize *col);
 
-int colorize(const darray_t *image, const darray_t *image_mark, const darray_t *flow, const darray_t *flow_i, int inner_iter, int outer_iter, int quick, int scalexyz, char **feat_names, struct colorize **_col);
+int colorize(const darray_t *image, const darray_t *image_mark, const darray_t *flow, const darray_t *flow_i, int inner_iter, int outer_iter, double target_residual_change, int quick, int scalexyz, char **feat_names, struct colorize **_col);
 #endif
index 4c0724b..f3097ee 100644 (file)
@@ -6,8 +6,8 @@
 #include "multigrid.h"
 
 /* if defined, residual is calculated and loop is aborted, if no improvement
- * is reached. this does not seem to work, so it should be undefined */
-//#define RESIDUAL
+ * is reached or the target resudual change is reached. */
+#define RESIDUAL
 
 /* just process, but do not generate neighbor list and do not solve multigrid */
 //#define TEST_NO_RENDER
@@ -1385,7 +1385,7 @@ void draw_flow(darray_t *dst, const darray_t *flow, const darray_t *flow_i)
  * before z)!
  *
  */
-int solve_mg(int nlevel, int iters, int ncycle, darray_t **values, darray_t **marks, const darray_t *init, unsigned char **nb_list, darray_t **flows, int scalexyz)
+int solve_mg(int nlevel, int iters, int ncycle, darray_t **values, darray_t **marks, const darray_t *init, unsigned char **nb_list, darray_t **flows, int scalexyz, double target_residual_change)
 {
 #ifdef RESIDUAL
        double curr_residual, prev_residual = 10000000000000.0;
@@ -1402,7 +1402,8 @@ int solve_mg(int nlevel, int iters, int ncycle, darray_t **values, darray_t **ma
                        for (i = 0; i < iters; i++)
                                smooth(level, values[level], marks[level], init, nb_list[level]);
 #ifdef RESIDUAL
-                       curr_residual += residual(level, values[level], marks[level], init, nb_list[level]);
+                       if (target_residual_change)
+                               curr_residual += residual(level, values[level], marks[level], init, nb_list[level]);
 #endif
                        if (level < scalexyz)
                                rc = restrict(values[level], values[level+1], flows[level]);
@@ -1430,9 +1431,12 @@ int solve_mg(int nlevel, int iters, int ncycle, darray_t **values, darray_t **ma
 
                /* end if residual raises again */
 #ifdef RESIDUAL
-               if (prev_residual < curr_residual)
+//printf("residual %.8f (change=%%%.4f)\n", curr_residual, (prev_residual-curr_residual)/prev_residual*100);
+               if (target_residual_change)
+                       printf(" %.1f%%", (prev_residual-curr_residual)/prev_residual*100); fflush(stdout);
+               if (target_residual_change && (prev_residual-curr_residual)/prev_residual < target_residual_change)
                        break;
-               curr_residual = prev_residual;
+               prev_residual = curr_residual;
 #endif
        }
 
index 1253e64..475d6be 100644 (file)
@@ -14,6 +14,6 @@ void quantize(const darray_t *array, double threshold, double gt, double le);
 void multiply(const darray_t *array, double factor);
 unsigned char *gen_neighbor(int w, int h, int k, const darray_t *flow, const darray_t *flow_i);
 void weighten(const darray_t *luminance, unsigned char *neighbors);
-int solve_mg(int nlevel, int iters, int ncycle, darray_t **values, darray_t **marks, const darray_t *init, unsigned char **nb_list, darray_t **flows, int scalexyz);
+int solve_mg(int nlevel, int iters, int ncycle, darray_t **values, darray_t **marks, const darray_t *init, unsigned char **nb_list, darray_t **flows, int scalexyz, double target_residual_change);
 #endif
 
index fe50913..4ea8616 100644 (file)
@@ -184,7 +184,8 @@ again:
  * options
  */
 
-static int in_itr_num = 5, out_itr_num = 1, quick = 0, optical_flow = 1, bright_contrast = 1, alpha_change = 1;
+static int in_itr_num = 5, out_itr_num = 10, quick = 0, optical_flow = 1, bright_contrast = 1, alpha_change = 1;
+static double target_residual_change = 0.01;
 int scale = 1, scalexyz = 999;
 static char output_prefix[256] = "";
 
@@ -234,6 +235,7 @@ static int handle_options(int argc, char **argv)
                        {"output-prefix", 1, 0, 'O'},
                        {"in-itr-num", 1, 0, 'i'},
                        {"out-itr-num", 1, 0, 'o'},
+                       {"residual-change", 1, 0, 'r'},
                        {"quick", 0, 0, 'q'},
                        {"zscale", 1, 0, 'z'},
                        {"brightness-contrast", 1, 0, 'b'},
@@ -243,7 +245,7 @@ static int handle_options(int argc, char **argv)
                        {0, 0, 0, 0},
                };
 
-               c = getopt_long(argc, argv, "hd:O:i:o:qz:b:f:s:t:", long_options, &option_index);
+               c = getopt_long(argc, argv, "hd:O:i:o:r:qz:b:f:s:t:", long_options, &option_index);
 
                if (c == -1)
                        break;
@@ -268,6 +270,10 @@ static int handle_options(int argc, char **argv)
                        out_itr_num = atoi(optarg);
                        skip_args += 2;
                        break;
+               case 'r':
+                       target_residual_change = atoi(optarg) / 100.0;
+                       skip_args += 2;
+                       break;
                case 'q':
                        quick = 1;
                        skip_args += 1;
@@ -329,8 +335,9 @@ static void print_help(const char *app)
        printf(" -h --help                           This help\n");
        printf(" -d --depth <bits>                   Save images with given color bit depth (default=%d)\n", save_depth);
        printf(" -O --output-prefix <path>/<prefix>  Store result image of a sequence using this prefix\n");
-       printf(" -i --in-itr-num <num>               Alter inner iterations (weightening count) of colorization algorithm (default=%d)\n", in_itr_num);
-       printf(" -o --out-itr-num <num>              Alter outer iterations (complete turns) of colorization algorithm (default=%d)\n", out_itr_num);
+       printf(" -i --in-itr-num <num>               Alter inner iterations (smoothing count) of colorization algorithm (default=%d)\n", in_itr_num);
+       printf(" -o --out-itr-num <num>              Set iterations (fixed turns) of colorization algorithm (default=%d)\n", out_itr_num);
+       printf(" -r --residual-change <percent>      Abort iterations if residual has reached minimum change (default=%.0f)\n", target_residual_change*100);
        printf(" -q --quick                          Use quick render, but sufaces may be colorized incomplete\n");
        printf(" -z --zscale <levels>                How many grids (staring with the finest) should be scaled in z direction to generate the next coarse grid ");
        if (scalexyz < 999)
@@ -638,7 +645,7 @@ next_sequence:
 
        if (test != FLOW_NEXT && test != FLOW_PREV && test != MARKED && test != MASK && test != MASK_COLOR && test != BC_ONLY && test != BC_IMAGE) {
                printf("Colorizing %d frames, please wait...\n", k);
-               rc = colorize(I, mI, flow, flow_i, in_itr_num, out_itr_num, quick, scalexyz, feat_names, NULL);
+               rc = colorize(I, mI, flow, flow_i, in_itr_num, out_itr_num, target_residual_change, quick, scalexyz, feat_names, NULL);
                if (rc < 0) {
                        if (k > 1)
                                printf("No memory! Use smaller frames or less frames between key frames or add more memory.");