efros_freeman  0.1
quilting.c
Go to the documentation of this file.
1 /*
2  Copyright (c) 2016 Lara Raad <lara.raad@cmla.ens-cachan.fr>,
3  Bruno Galerne <bruno.galerne@parisdescartes.fr>
4 
5  Quilting is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Affero General Public License as
7  published by the Free Software Foundation, either version 3 of the
8  License, or (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <math.h>
22 #include <string.h>
23 #include <assert.h>
24 #include <float.h>
25 #include <fftw3.h>
26 #include <time.h>
27 
28 #ifdef _OPENMP
29  #include <omp.h>
30 #else
31  #define omp_get_thread_num() 0
32 #endif
33 
34 #include "quilting.h"
35 #include "patch_search.h"
36 #include "boundary_cut.h"
37 #include "blending.h"
38 #include "random_number.h"
39 
40 #define MAX_DIST FLT_MAX
41 
42 /**
43 * This method synthesizes a texture image quilting patches taken from an
44 * input sample texture.
45 * @author Lara Raad
46 * @param src_im The input texture sample
47 * @param wp The size of the patches
48 * @param wo The size of the overlap area betwenn patches
49 * @param p_row Number of patches per row to paste in the synthesized img
50 * @param p_col Number of patches per col to paste in the synthesized img
51 * @param tol The threshold used to select patches from the input img
52 * @date 24/05/2012
53 */
54 Image quilting_synthesis(Image src_im, int wp, int wo, int p_row, int p_col,
55  float tol, Image * position_map, Image * synth_map,
56  long * seed)
57 {
58  Image out_im;// synthesized image
59  long double *patch_normsH, *patch_normsV, *patch_normsL;
60  Corner patch_src;// position (x,y) of the patch to paste in the output img
61  Corner temp;// temporary position (x,y) of the patch under construction
62  int step_size;// step size between each patch to paste in the output img
63  int ii, jj, inc_s, h_s, w_s, w_o;
64  int fft_size; // size of the r2c ffts for the source image
65 
66  int Nc = p_col;
67  int Nr = p_row;
68 
69  /*************************************************************************/
70  /*** INITIALIZATION ***/
71  /*************************************************************************/
72 
73  //* Initialize ouput image : out_im *//
74  out_im = initialize(src_im, wp, wo, p_row, p_col,&patch_src);
75 
76  //* Initiialize synthesis map *//
77  initialize_image(synth_map, out_im.h, out_im.w, 3);
78 
79  h_s = src_im.h;
80  w_s = src_im.w;
81  w_o = out_im.w;
82 
83  inc_s = h_s*w_s;
84  step_size = wp - wo;
85  fft_size = h_s*((int) (w_s/2) + 1);
86 
87  int h_dict, w_dict;
88  h_dict = h_s-wp+1;
89  w_dict = w_s-wp+1;
90 
91  // create the norm of each valid patch in src_im
92  // initialize the image of the patches norms from src_im (horizontal ov)
93  patch_normsH = (long double *) malloc(inc_s*sizeof(long double));
94  // initialize the image of the patches norms from src_im (vertical ov)
95  patch_normsV = (long double *) malloc(inc_s*sizeof(long double));
96  // initialize the image of the patches norms from src_im (L-shape ov)
97  patch_normsL = (long double *) malloc(inc_s*sizeof(long double));
98 
99  compute_input_patch_norms(src_im, patch_normsH,
100  patch_normsV, patch_normsL, wp, wo);
101 
102  //create the fft of the src_im for each channel
103  fftwl_complex *fft_srcR, *fft_srcG, *fft_srcB;
104  fft_srcR = (fftwl_complex*) fftwl_malloc(sizeof(fftwl_complex)*(fft_size));
105  fft_srcG = (fftwl_complex*) fftwl_malloc(sizeof(fftwl_complex)*(fft_size));
106  fft_srcB = (fftwl_complex*) fftwl_malloc(sizeof(fftwl_complex)*(fft_size));
107  im_fft(src_im.img, fft_srcR, h_s, w_s);
108  im_fft(src_im.img + inc_s, fft_srcG, h_s, w_s);
109  im_fft(src_im.img + 2*inc_s, fft_srcB, h_s, w_s);
110 
111  Image aux_mask;// Mask of all zeros to initialize the synthesis map
112  initialize_image(&aux_mask, wp, wp, 1);
113 
114  temp.x = 0;
115  temp.y = 0;
116  update_synth_map(synth_map, position_map, &patch_src, &temp, wp, aux_mask);
117 
118  /*************************************************************************/
119  /*** MAIN SYNTHESIS LOOP (RUN IN PARALLEL) ***/
120  /*************************************************************************/
121 
122  for(jj=0; jj<(int) (Nr + 2*(Nc-1) -1)*step_size + 1; jj+=step_size)
123  {
124  #pragma omp parallel
125  {
126  /* initialize random generator seed for each thread */
127  long s;
128  if ( seed != NULL ) s = *seed ^ omp_get_thread_num();
129  else s = time(NULL) ^ omp_get_thread_num();
130  random_number(&s);
131 
132  #pragma omp for
133  for(ii=0; ii<(int) (Nc-1)*step_size+1; ii+=step_size)
134  {
135  //not for the seed patch
136  if ((ii>0 || jj>0) && (jj-2*ii >= 0) && (jj-2*ii < w_o-wp+1))
137  {
138  Corner temp;
139  Corner patch_pos;
140  Image boundary_mask;
141 
142  //* Initialize boundary mask *//
143  initialize_image(&boundary_mask, wp, wp, 1);
144 
145  temp.x = ii;
146  temp.y = jj-2*ii;
147 
148  // Patch search: Randomly pick a patch that
149  // is close to the minimal distance
150  patch_search(src_im, out_im, temp, wp, patch_normsH,
151  patch_normsV, patch_normsL, fft_srcR, fft_srcG,
152  fft_srcB, h_dict, w_dict, &patch_pos, tol);
153 
154  // compute boundary mask
155  compute_boundary_mask(src_im, out_im, &boundary_mask,
156  wo, wp, &temp, patch_pos);
157 
158  // Updating synthesis map
159  update_synth_map(synth_map, position_map, &patch_pos,
160  &temp, wp, boundary_mask);
161 
162  // blending new patch into out_im
163  blend_patch(boundary_mask, &out_im, src_im, patch_pos,
164  temp, wp, wo);
165 
166  free(boundary_mask.img);
167  }
168  }
169  }
170  }
171 
172  //free memory
173  free(patch_normsH);
174  free(patch_normsV);
175  free(patch_normsL);
176  free(aux_mask.img);
177  fftwl_free(fft_srcR);
178  fftwl_free(fft_srcG);
179  fftwl_free(fft_srcB);
180 
181  return out_im;
182 }