void poisson_recursive(float *out, float *in, float *dat, int w, int h, int scale) { float *init = xmalloc(w*h*sizeof*init); if (scale > 1) { int ws = ceil(w/2.0); int hs = ceil(h/2.0); float *ins = xmalloc(ws * hs * sizeof*ins); float *dats = xmalloc(ws * hs * sizeof*dats); float *outs = xmalloc(ws * hs * sizeof*outs); zoom_out_by_factor_two(ins, ws, hs, in, w, h); zoom_out_by_factor_two(dats, ws, hs, dat, w, h); for (int i = 0; i < ws*hs; i++) dats[i] *= 4; poisson_recursive(outs, ins, dats, ws, hs, scale-1); zoom_in_by_factor_two(init, w, h, outs, ws, hs); free(ins); free(dats); free(outs); } else { for (int i = 0 ; i < w*h; i++) init[i] = 0; } poisson_solver_with_init(out, in, dat, w, h, init); free(init); }
void poisson_rec(float *out, float *in, float *dat, int w, int h, float tstep, int niter, int scale) { float *init = xmalloc(w*h*sizeof*init); if (scale > 1) { int ws = ceil(w/2.0); int hs = ceil(h/2.0); float *ins = xmalloc(ws * hs * sizeof*ins); float *dats = xmalloc(ws * hs * sizeof*dats); float *outs = xmalloc(ws * hs * sizeof*outs); zoom_out_by_factor_two(ins, ws, hs, in, w, h); zoom_out_by_factor_two(dats, ws, hs, dat, w, h); poisson_rec(outs, ins, dats, ws, hs, tstep, niter, scale-1); zoom_in_by_factor_two(init, w, h, outs, ws, hs); free(ins); free(dats); free(outs); } else { for (int i = 0 ; i < w*h; i++) init[i] = 0; } poisson_extension_with_init(out, in, dat, w, h, tstep, niter, init); free(init); }
// recursive function to find the displacement vector that minimizes error // // A, B: input images // w: width // h: heigth // scale: number of multi-scale recursions // d: optimal displacement (output) // void find_displacement(int d[2], float *A, float *B, int w, int h, int scale) { // find an initial rhough displacement d if (scale > 1) // call the function recursively { int ws = ceil(w/2.0); int hs = ceil(h/2.0); float *As = malloc(ws * hs * sizeof*As); float *Bs = malloc(ws * hs * sizeof*Bs); zoom_out_by_factor_two(As, ws, hs, A, w, h); zoom_out_by_factor_two(Bs, ws, hs, B, w, h); find_displacement(d, As, Bs, ws, hs, scale-1); free(As); free(Bs); d[0] *= 2; d[1] *= 2; } else { d[0] = 0; d[1] = 0; } // refine the rhough displacement by local optimization int bestn = -1, neig[9][2] = { {-1,-1},{-1,0},{-1,1}, {0,-1},{0,0},{0,1}, {1,-1},{1,0},{1,1}, }; float best = INFINITY; float tbest[9]; #ifdef _OPENMP #pragma omp parallel for #endif for (int n = 0; n < 9; n++) { int D[2] = {d[0] + neig[n][0], d[1] + neig[n][1]}; float r = eval_displacement(A, B, w, h, D); tbest[n] = r; ////#pragma omp critical // if (r < best) { // best = r; // bestn = n; // } } for (int n = 0; n < 9; n++) if (tbest[n] < best) { best = tbest[n]; bestn = n; } d[0] += neig[bestn][0]; d[1] += neig[bestn][1]; fprintf(stderr, "%dx%d: %d %d\n", w, h, d[0], d[1]); }
void mnehs_affine_ms(float *out, float *in, int w, int h, float *a, int aw, int ah, float *b, int bw, int bh, double PA[8], double PB[8], float alpha2, int niter, int scale) { float *init = xmalloc(w*h*sizeof*init); if (scale > 1) { int ws = ceil( w/2.0); int hs = ceil( h/2.0); int aws = ceil(aw/2.0); int ahs = ceil(ah/2.0); int bws = ceil(bw/2.0); int bhs = ceil(bh/2.0); float *is = xmalloc( ws * hs * sizeof*is); float *os = xmalloc( ws * hs * sizeof*os); float *as = xmalloc(aws * bhs * sizeof*as); float *bs = xmalloc(bws * bhs * sizeof*bs); double PAs[8] = { PA[0], PA[1], PA[2]/2, PA[3]/2, PA[4], PA[5], PA[6]/2, PA[7]/2 }; double PBs[8] = { PB[0], PB[1], PB[2]/2, PB[3]/2, PB[4], PB[5], PB[6]/2, PB[7]/2 }; zoom_out_by_factor_two(is, ws, hs, in, w, h); zoom_out_by_factor_two(as, aws, ahs, a, aw, ah); zoom_out_by_factor_two(bs, bws, bhs, b, bw, bh); mnehs_affine_ms(os, is, ws, hs, as, aws, ahs, bs, bws, bhs, PAs, PBs, alpha2, niter, scale - 1); zoom_in_by_factor_two(init, w, h, os, ws, hs); free(is); free(os); free(as); free(bs); } else { for (int i = 0; i < w * h; i++) init[i] = in[i]; } global_scale = scale; mnehs_affine(out, init, w,h, a,aw,ah, b,bw,bh, PA, PB, alpha2, niter); free(init); }
static void create_pyramid(struct pan_state *e) { for (int s = 0; s < MAX_PYRAMID_LEVELS; s++) { int lw = s ? e->pyr_w [s-1] : e->w ; int lh = s ? e->pyr_h [s-1] : e->h ; unsigned char *lrgb = s ? e->pyr_rgb[s-1] : e->rgb; int sw = ceil(lw / 2.0); int sh = ceil(lh / 2.0); unsigned char *srgb = malloc(3 * sw * sh); zoom_out_by_factor_two(srgb, sw, sh, lrgb, lw, lh); e->pyr_w[s] = sw; e->pyr_h[s] = sh; e->pyr_rgb[s] = srgb; } }
// inpaint the NAN values of an image void simplest_inpainting(float *x, int w, int h) { float *y = malloc(w * h * sizeof*y); if (w > 1 || h > 1) { int ws = ceil(w/2.0); int hs = ceil(h/2.0); float *xs = malloc(ws * hs * sizeof*xs); zoom_out_by_factor_two(xs, ws, hs, x, w, h); simplest_inpainting(xs, ws, hs); zoom_in_by_factor_two(y, w, h, xs, ws, hs); free(xs); } for (int i = 0; i < w*h; i++) if (isnan(x[i])) x[i] = y[i]; free(y); }