IIINSTRUMENT Pipeline Reference Manual 4.6.1
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
43static cpl_error_code visir_destripe_mask(cpl_mask *);
44
45static int visir_destripe_image_one_float(cpl_image *, double, double,
46 cpl_boolean, cpl_boolean);
47static cpl_error_code visir_destripe_find_max_index_float(const cpl_image *,
48 int, int,
49 int, int, double *,
50 int *, int *, int *);
51
52static int visir_destripe_image_one_double(cpl_image *, double, double,
53 cpl_boolean, cpl_boolean);
54static 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/*----------------------------------------------------------------------------*/
81cpl_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/*----------------------------------------------------------------------------*/
151static 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.