CR2RE Pipeline Reference Manual 1.6.8
hdrl_fpn.c
1/*
2 * This file is part of the HDRL
3 * Copyright (C) 2013,2014 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#include "hdrl_fpn.h"
25
26
27/*---------------------------------------------------------------------------*/
59/*----------------------------------------------------------------------------*/
60
63/* ---------------------------------------------------------------------------*/
112/* ---------------------------------------------------------------------------*/
113cpl_error_code hdrl_fpn_compute(
114 cpl_image *img_in,
115 const cpl_mask *mask_in,
116 const cpl_size dc_mask_x,
117 const cpl_size dc_mask_y,
118 cpl_image **power_spectrum,
119 double *std,
120 double *std_mad)
121{
122 /* Check Entries */
123 cpl_ensure_code(img_in, CPL_ERROR_NULL_INPUT);
124
125 cpl_ensure_code( dc_mask_x >= 1 && dc_mask_y >= 1
126 && *power_spectrum == NULL, CPL_ERROR_ILLEGAL_INPUT);
127
128 /* Check all of the pixels are good */
129 if (cpl_image_count_rejected(img_in) != 0) {
130 return cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
131 "The image can't contain bad pixels");
132 }
133
134 /* Check if the size of the mask match with the image */
135 cpl_size nx = cpl_image_get_size_x(img_in);
136 cpl_size ny = cpl_image_get_size_y(img_in);
137 if (mask_in) {
138 cpl_ensure_code( nx == cpl_mask_get_size_x(mask_in)
139 && ny == cpl_mask_get_size_y(mask_in),
140 CPL_ERROR_INCOMPATIBLE_INPUT);
141 }
142
143 /* Create ouput image */
144 *power_spectrum = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
145
146 /* Calculate the fft of the input image
147 * Converted previously to complex to get nx columns instead of (nx / 2) + 1 */
148 cpl_image *img_in_complex = cpl_image_cast(img_in, CPL_TYPE_DOUBLE_COMPLEX);
149 cpl_image *fft_image = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE_COMPLEX);
150 cpl_fft_image(fft_image, img_in_complex, CPL_FFT_FORWARD);
151 cpl_image_delete(img_in_complex);
152
153 /* Extract a double complex array */
154 double complex *fft_image_array = cpl_image_get_data_double_complex(fft_image);
155
156 /* Calculate the power spectrum as: cabs(value)**2 == value x value_conjugate
157 * Normalize image: cpl_fft_image scale the image in the number of elements */
158 double norm_size = nx * ny;
159 for (cpl_size y = 0; y < ny; y++) {
160 for (cpl_size x = 0; x < nx ; x++) {
161
162 /* Get position in the double complex array */
163 cpl_size idx = (y * nx) + x;
164
165 /* Get power spectrum of each cell and apply the normalization */
166 double complex value_complex = fft_image_array[idx];
167 double norm_value = creal(value_complex * conj(value_complex)) / norm_size;
168
169 /* Save the normalized value in the output image */
170 cpl_image_set(*power_spectrum, x + 1, y + 1, norm_value);
171 }
172 }
173 cpl_image_delete(fft_image);
174
175
176 /* If exist mask, use it and add region defined by dc_mask_x/y */
177 cpl_mask *out_mask = NULL;
178 if (mask_in) {
179 out_mask = cpl_mask_duplicate(mask_in);
180 } else {
181 out_mask = cpl_mask_new(nx, ny);
182 }
183
184 /* Check and apply the mask */
185 for (cpl_size i = 1; i <= dc_mask_x; i++) {
186 for (cpl_size j = 1; j <= dc_mask_y; j++) {
187 cpl_mask_set(out_mask, i, j, CPL_BINARY_1);
188 }
189 }
190 cpl_image_reject_from_mask(*power_spectrum, out_mask);
191
192 /* Cleanup */
193 cpl_mask_delete(out_mask);
194
195
196 /* Get the STD */
197 *std = cpl_image_get_stdev(*power_spectrum);
198
199
200 /* Get the MAD */
201 double mad = 0.;
202 cpl_image_get_mad(*power_spectrum, &mad);
203 *std_mad = CPL_MATH_STD_MAD * mad;
204
205
206 return CPL_ERROR_NONE;
207}
208
209
cpl_error_code hdrl_fpn_compute(cpl_image *img_in, const cpl_mask *mask_in, const cpl_size dc_mask_x, const cpl_size dc_mask_y, cpl_image **power_spectrum, double *std, double *std_mad)
Algorithms to compute fixed pattern noise on a single image.
Definition: hdrl_fpn.c:113