CR2RE Pipeline Reference Manual 1.6.10
hdrl_bpm_utils.c
1/*
2 * This file is part of the HDRL
3 * Copyright (C) 2013 European Southern Observatory
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (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 General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#ifdef HAVE_CONFIG_H
21#include <config.h>
22#endif
23
24/*-----------------------------------------------------------------------------
25 Includes
26-----------------------------------------------------------------------------*/
27
28#include "hdrl_types.h"
29#include "hdrl_image.h"
30#include "hdrl_imagelist.h"
31#include "hdrl_utils.h"
32
33#include "hdrl_bpm_utils.h"
34#include "hdrl_prototyping.h"
35
36#include <cpl.h>
37#include <string.h>
38#include <math.h>
39
40/*-----------------------------------------------------------------------------
41 Static
42 -----------------------------------------------------------------------------*/
43
44/*----------------------------------------------------------------------------*/
48/*----------------------------------------------------------------------------*/
49
52/*----------------------------------------------------------------------------*/
62/*----------------------------------------------------------------------------*/
63cpl_imagelist * hdrl_bpm_filter_list(
64 const cpl_imagelist * inlist,
65 cpl_size kernel_nx,
66 cpl_size kernel_ny,
67 cpl_filter_mode filter)
68{
69 cpl_imagelist * out ;
70 cpl_size nima;
71
72 /* Check Entries */
73 cpl_ensure(inlist != NULL, CPL_ERROR_NULL_INPUT, NULL);
74 nima = cpl_imagelist_get_size(inlist) ;
75
76 /* Create Output list */
77 out = cpl_imagelist_new() ;
78
79 /* Loop over the imagelist */
80 for (cpl_size i = 0 ; i < nima ; i++) {
81 cpl_mask * mask_in, * mask_out;
82 /* Convert input image to mask */
83 mask_in = cpl_mask_threshold_image_create(
84 cpl_imagelist_get_const(inlist, i), -0.5, 0.5);
85 cpl_mask_not(mask_in);
86
87 /* Filter mask */
88 mask_out = hdrl_bpm_filter(mask_in, kernel_nx, kernel_ny, filter) ;
89 cpl_mask_delete(mask_in) ;
90 if (mask_out == NULL) {
91 cpl_imagelist_delete(out) ;
92 return NULL ;
93 }
94
95 /* Convert mask to image and store it in the list */
96 cpl_imagelist_set(out, cpl_image_new_from_mask(mask_out), i);
97 cpl_mask_delete(mask_out) ;
98 }
99 return out ;
100}
101
102/*----------------------------------------------------------------------------*/
120/*----------------------------------------------------------------------------*/
122 const cpl_mask * input_mask,
123 cpl_size kernel_nx,
124 cpl_size kernel_ny,
125 cpl_filter_mode filter)
126{
127 cpl_mask * kernel;
128 cpl_mask * filtered_mask;
129 cpl_mask * expanded_mask;
130 cpl_mask * expanded_filtered_mask;
131
132 /* Check Entries */
133 cpl_ensure(input_mask != NULL, CPL_ERROR_NULL_INPUT, NULL);
134 cpl_ensure(kernel_nx >= 1, CPL_ERROR_ILLEGAL_INPUT, NULL);
135 cpl_ensure(kernel_ny >= 1, CPL_ERROR_ILLEGAL_INPUT, NULL);
136 cpl_ensure(filter == CPL_FILTER_EROSION || filter == CPL_FILTER_DILATION ||
137 filter == CPL_FILTER_OPENING || filter == CPL_FILTER_CLOSING,
138 CPL_ERROR_ILLEGAL_INPUT, NULL);
139
140 /* Only odd-sized masks allowed */
141 cpl_ensure((kernel_nx&1) == 1, CPL_ERROR_ILLEGAL_INPUT, NULL);
142 cpl_ensure((kernel_ny&1) == 1, CPL_ERROR_ILLEGAL_INPUT, NULL);
143
144 kernel = cpl_mask_new(kernel_nx, kernel_ny);
145 cpl_mask_not(kernel); /* All values set to unity*/
146
147 /* Enlarge the original mask with the kernel size and assume that outside
148 * all pixels are good */
149 expanded_mask = cpl_mask_new(
150 cpl_mask_get_size_x(input_mask) + 2 * kernel_nx,
151 cpl_mask_get_size_y(input_mask) + 2 * kernel_ny);
152
153 cpl_mask_copy(expanded_mask, input_mask, kernel_nx + 1, kernel_ny +1 );
154
155 expanded_filtered_mask = cpl_mask_new(cpl_mask_get_size_x(expanded_mask),
156 cpl_mask_get_size_y(expanded_mask));
157
158 if(cpl_mask_filter(expanded_filtered_mask, expanded_mask, kernel, filter,
159 CPL_BORDER_ZERO) != CPL_ERROR_NONE) {
160
161 cpl_mask_delete(kernel);
162 cpl_mask_delete(expanded_filtered_mask);
163 cpl_mask_delete(expanded_mask);
164 return NULL;
165 }
166
167 /* Extract the original mask from the expanded mask */
168 filtered_mask = cpl_mask_extract(expanded_filtered_mask,
169 kernel_nx+1, kernel_ny + 1,
170 cpl_mask_get_size_x(input_mask) + kernel_nx,
171 cpl_mask_get_size_y(input_mask) + kernel_ny);
172
173
174 /* Free memory */
175 cpl_mask_delete(kernel);
176 cpl_mask_delete(expanded_filtered_mask);
177 cpl_mask_delete(expanded_mask);
178
179 return filtered_mask;
180}
181
182/*----------------------------------------------------------------------------*/
191/*----------------------------------------------------------------------------*/
192cpl_mask * hdrl_bpm_to_mask(const cpl_image * bpm, uint64_t selection)
193{
194 cpl_ensure(bpm, CPL_ERROR_NULL_INPUT, NULL);
195 cpl_ensure(cpl_image_get_type(bpm) == CPL_TYPE_INT,
196 CPL_ERROR_ILLEGAL_INPUT, NULL);
197 /* cpl currently only has int images, but use 64 for forward compat */
198 cpl_ensure(selection <= CX_MAXUINT, CPL_ERROR_UNSUPPORTED_MODE, NULL);
199 unsigned int iselection = (unsigned int)selection;
200 const unsigned int * data=(const unsigned int *)cpl_image_get_data_int_const(bpm);
201 const size_t nx = cpl_image_get_size_x(bpm);
202 const size_t ny = cpl_image_get_size_y(bpm);
203 cpl_mask * msk = cpl_mask_new(nx, ny);
204 cpl_binary * dmsk = cpl_mask_get_data(msk);
205 for (size_t i = 0; i < ny * nx; i++) {
206 dmsk[i] = (data[i] & iselection) ? 1 : 0;
207 }
208 return msk;
209}
210
211/*----------------------------------------------------------------------------*/
220/*----------------------------------------------------------------------------*/
221cpl_image * hdrl_mask_to_bpm(const cpl_mask * mask, uint64_t flag)
222{
223 cpl_ensure(mask, CPL_ERROR_NULL_INPUT, NULL);
224 /* cpl currently only has int images, but use 64 for forward compatibility */
225 cpl_ensure(flag <= CX_MAXUINT, CPL_ERROR_UNSUPPORTED_MODE, NULL);
226 unsigned int iflag = (unsigned int)flag;
227 const size_t nx = cpl_mask_get_size_x(mask);
228 const size_t ny = cpl_mask_get_size_y(mask);
229 cpl_image * bpm = cpl_image_new(nx, ny, CPL_TYPE_INT);
230 const cpl_binary * dmsk = cpl_mask_get_data_const(mask);
231 unsigned int * data = (unsigned int *)cpl_image_get_data_int(bpm);
232 for (size_t i = 0; i < ny * nx; i++) {
233 data[i] = dmsk[i] ? iflag : 0;
234 }
235 return bpm;
236}
237
238/*----------------------------------------------------------------------------*/
262/*----------------------------------------------------------------------------*/
264 cpl_imagelist * list,
265 cpl_mask ** masks)
266{
267 cpl_ensure_code(list, CPL_ERROR_NULL_INPUT);
268 cpl_ensure_code(masks, CPL_ERROR_NULL_INPUT);
269
270 for (size_t i = 0; i < (size_t)cpl_imagelist_get_size(list); i++) {
271 cpl_image * img = cpl_imagelist_get(list, i);
272 cpl_mask * img_mask = cpl_image_get_bpm(img);
273 /* zero mask */
274 cpl_mask_xor(img_mask, img_mask);
275 /* add new mask */
276 cpl_mask_or(img_mask, masks[i]);
277 }
278 return cpl_error_get_code();
279}
280
281/*----------------------------------------------------------------------------*/
291/*----------------------------------------------------------------------------*/
293 cpl_imagelist * list,
294 cpl_mask * new_mask,
295 cpl_mask *** pold_mask)
296{
297 cpl_ensure_code(list, CPL_ERROR_NULL_INPUT);
298 cpl_ensure_code(new_mask, CPL_ERROR_NULL_INPUT);
299
300 if (pold_mask) {
301 *pold_mask = cpl_malloc(sizeof(*pold_mask) *
302 cpl_imagelist_get_size(list));
303 }
304
305 for (size_t i = 0; i < (size_t)cpl_imagelist_get_size(list); i++) {
306 cpl_image * img = cpl_imagelist_get(list, i);
307 cpl_mask * img_mask = cpl_image_get_bpm(img);
308 if (pold_mask) {
309 (*pold_mask)[i] = cpl_mask_duplicate(img_mask);
310 }
311
312 cpl_mask_or(img_mask, new_mask);
313 }
314 return cpl_error_get_code();
315}
316
cpl_image * hdrl_mask_to_bpm(const cpl_mask *mask, uint64_t flag)
convert cpl_mask to bad pixel information mask
cpl_mask * hdrl_bpm_to_mask(const cpl_image *bpm, uint64_t selection)
convert bad pixel information mask to a cpl_mask
cpl_mask * hdrl_bpm_filter(const cpl_mask *input_mask, cpl_size kernel_nx, cpl_size kernel_ny, cpl_filter_mode filter)
Allows the growing and shrinking of bad pixel masks. It can be used to e.g. set pixels to bad if the ...
cpl_imagelist * hdrl_bpm_filter_list(const cpl_imagelist *inlist, cpl_size kernel_nx, cpl_size kernel_ny, cpl_filter_mode filter)
Wrapper around hdrl_bpm_filter() to filter list of images.
cpl_error_code hdrl_join_mask_on_imagelist(cpl_imagelist *list, cpl_mask *new_mask, cpl_mask ***pold_mask)
join mask with existing masks in an imagelist
cpl_error_code hdrl_set_masks_on_imagelist(cpl_imagelist *list, cpl_mask **masks)
apply array of masks to an image list