VISIR Pipeline Reference Manual  4.1.0
visir_destripe.c
1 /* $Id: visir_destripe.c,v 1.15 2012-02-09 13:44:15 jtaylor Exp $
2  *
3  * This file is part of the VISIR Pipeline
4  * Copyright (C) 2002,2003 European Southern Observatory
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
19  */
20 
21 /*
22  * $Author: jtaylor $
23  * $Date: 2012-02-09 13:44:15 $
24  * $Revision: 1.15 $
25  * $Name: not supported by cvs2svn $
26  */
27 
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 
32 /*-----------------------------------------------------------------------------
33  Includes
34  -----------------------------------------------------------------------------*/
35 
36 #include "visir_destripe.h"
37 #include "visir_utils.h"
38 
39 /*-----------------------------------------------------------------------------
40  Private function prototypes
41  -----------------------------------------------------------------------------*/
42 
43 static cpl_error_code visir_destripe_mask(cpl_mask *);
44 
45 static int visir_destripe_image_one_float(cpl_image *, double, double,
46  cpl_boolean, cpl_boolean);
47 static cpl_error_code visir_destripe_find_max_index_float(const cpl_image *,
48  int, int,
49  int, int, double *,
50  int *, int *, int *);
51 
52 static int visir_destripe_image_one_double(cpl_image *, double, double,
53  cpl_boolean, cpl_boolean);
54 static cpl_error_code visir_destripe_find_max_index_double(const cpl_image *,
55  int, int,
56  int, int, double *,
57  int *, int *, int *);
58 
59 /*----------------------------------------------------------------------------*/
63 /*----------------------------------------------------------------------------*/
64 
67 /*----------------------------------------------------------------------------*/
80 /*----------------------------------------------------------------------------*/
81 cpl_error_code visir_destripe_image(cpl_image * self, int niter,
82  double threshold, double thres_detect,
83  cpl_boolean morpho)
84 {
85 
86  cpl_boolean do_horizontal = CPL_TRUE;
87  cpl_boolean did_find = CPL_FALSE;
88 
89  bug_if(self == NULL);
90  bug_if(niter < 1);
91 
92  do {
93 
94  const char * sdir = do_horizontal ? "horizontal" : "vertical";
95  int j = 0; /* Avoid (false) uninit warning */
96 
97  switch (cpl_image_get_type(self)) {
98  case CPL_TYPE_DOUBLE:
99  for (j = 0; j < niter; j++) {
100  if (visir_destripe_image_one_double(self, threshold,
101  thres_detect, morpho,
102  do_horizontal)) break;
103  }
104  break;
105  case CPL_TYPE_FLOAT:
106  for (j = 0; j < niter; j++) {
107  if (visir_destripe_image_one_float(self, threshold,
108  thres_detect, morpho,
109  do_horizontal)) break;
110  }
111  break;
112  default:
113  bug_if( 1 );
114  }
115 
116  if (j == 0) {
117  cpl_msg_info(cpl_func, "No %s stripes found", sdir);
118  } else if (j < niter) {
119  did_find = CPL_TRUE;
120  cpl_msg_info(cpl_func, "No more %s stripes found in iteration %d",
121  sdir, j+1);
122  } else {
123  did_find = CPL_TRUE;
124  cpl_msg_info(cpl_func, "Stopped %s destriping after %d iterations",
125  sdir, niter);
126  }
127 
128  skip_if(0);
129 
130  do_horizontal = !do_horizontal;
131  } while (!did_find && !do_horizontal);
132 
133  end_skip;
134 
135  return cpl_error_get_code();
136 
137 }
138 
142 /*----------------------------------------------------------------------------*/
150 /*----------------------------------------------------------------------------*/
151 static cpl_error_code visir_destripe_mask(cpl_mask * self)
152 {
153 
154  const int niter = 3;
155  cpl_mask * kernel = cpl_mask_new(3, 5);
156  cpl_mask * copy = cpl_mask_new(cpl_mask_get_size_x(self),
157  cpl_mask_get_size_y(self));
158  int i;
159 
160  bug_if(0);
161 
162  /* self = 1-(closing(1-self)) */
163  cpl_mask_not(self);
164 
165  /* Fill the kernel */
166  cpl_mask_not(kernel);
167 
168  bug_if(cpl_mask_filter(self, self, kernel,
169  CPL_FILTER_CLOSING, CPL_BORDER_ZERO));
170 
171  cpl_mask_delete(kernel);
172 
173  /* Create the new kernel */
174  kernel = cpl_mask_new(5, 3);
175  cpl_mask_not(kernel);
176  cpl_mask_set(kernel, 1, 1, CPL_BINARY_0);
177  cpl_mask_set(kernel, 5, 1, CPL_BINARY_0);
178  cpl_mask_set(kernel, 1, 3, CPL_BINARY_0);
179  cpl_mask_set(kernel, 5, 3, CPL_BINARY_0);
180  /* self = 1-(dilation(1-self)) */
181  for (i = 0; i < 2*(niter/2); i += 2) {
182  bug_if(cpl_mask_filter(copy, self, kernel,
183  CPL_FILTER_DILATION, CPL_BORDER_ZERO));
184  bug_if(cpl_mask_filter(self, copy, kernel,
185  CPL_FILTER_DILATION, CPL_BORDER_ZERO));
186  }
187  for (; i < niter; i++) { /* Last iteration w. copy, when niter is odd */
188  bug_if(cpl_mask_filter(copy, self, kernel,
189  CPL_FILTER_DILATION, CPL_BORDER_ZERO));
190  bug_if(cpl_mask_copy(self, copy, 1, 1));
191  }
192 
193  cpl_mask_delete(kernel);
194 
195  /* Create the new kernel */
196  kernel = cpl_mask_new(5, 5); /* Initialized to zero */
197  cpl_mask_set(kernel, 3, 1, CPL_BINARY_1);
198  cpl_mask_set(kernel, 2, 2, CPL_BINARY_1);
199  cpl_mask_set(kernel, 3, 2, CPL_BINARY_1);
200  cpl_mask_set(kernel, 4, 2, CPL_BINARY_1);
201  cpl_mask_set(kernel, 1, 3, CPL_BINARY_1);
202  cpl_mask_set(kernel, 2, 3, CPL_BINARY_1);
203  cpl_mask_set(kernel, 3, 3, CPL_BINARY_1);
204  cpl_mask_set(kernel, 4, 3, CPL_BINARY_1);
205  cpl_mask_set(kernel, 5, 3, CPL_BINARY_1);
206  cpl_mask_set(kernel, 2, 4, CPL_BINARY_1);
207  cpl_mask_set(kernel, 3, 4, CPL_BINARY_1);
208  cpl_mask_set(kernel, 4, 4, CPL_BINARY_1);
209  cpl_mask_set(kernel, 3, 5, CPL_BINARY_1);
210  /* self = 1-(dilation(1-self)) */
211  for (i = 0; i < 2*(niter/2); i += 2) {
212  bug_if(cpl_mask_filter(copy, self, kernel,
213  CPL_FILTER_DILATION, CPL_BORDER_ZERO));
214  bug_if(cpl_mask_filter(self, copy, kernel,
215  CPL_FILTER_DILATION, CPL_BORDER_ZERO));
216  }
217  for (; i < niter; i++) { /* Last iteration w. copy, when niter is odd */
218  bug_if(cpl_mask_filter(copy, self, kernel,
219  CPL_FILTER_DILATION, CPL_BORDER_ZERO));
220  bug_if(cpl_mask_copy(self, copy, 1, 1));
221  }
222 
223  bug_if(cpl_mask_not(self));
224 
225  end_skip;
226 
227  cpl_mask_delete(copy);
228  cpl_mask_delete(kernel);
229 
230  return cpl_error_get_code();
231 }
232 
233 
234 
235 /* These macros are needed for support of the different pixel types */
236 
237 #define CONCAT(a,b) a ## _ ## b
238 #define CONCAT2X(a,b) CONCAT(a,b)
239 
240 #define PIXEL_TYPE double
241 #define PIXEL_TYPE_CPL CPL_TYPE_DOUBLE
242 #include "visir_destripe_body.c"
243 #undef PIXEL_TYPE
244 #undef PIXEL_TYPE_CPL
245 
246 #define PIXEL_TYPE float
247 #define PIXEL_TYPE_CPL CPL_TYPE_FLOAT
248 #include "visir_destripe_body.c"
249 #undef PIXEL_TYPE
250 #undef PIXEL_TYPE_CPL
cpl_error_code visir_destripe_image(cpl_image *self, int niter, double threshold, double thres_detect, cpl_boolean morpho)
Remove the stripes frome an image using iterations.