32#include "hdrl_random.h"
33#include "hdrl_bpm_utils.h"
45#define HDRL_DELTA_COMPARE_QC HDRL_EPS_DATA * 2.0e1
46#define HDRL_DELTA_COMPARE_IMAGE HDRL_EPS_DATA * 1.5e1
49#define HDRL_FPN_TEST_EVEN_IMG_OUT "even_img_out.fits"
50#define HDRL_FPN_TEST_EVEN_MASK_OUT "even_mask_out.fits"
52#define HDRL_FPN_TEST_ODD_IMG_OUT "odd_img_out.fits"
53#define HDRL_FPN_TEST_ODD_MASK_OUT "odd_mask_out.fits"
55#define HDRL_FPN_TEST_FILTER_IMG_OUT "filter_img_out.fits"
56#define HDRL_FPN_TEST_FILTER_MASK_OUT "filter_mask_out.fits"
58#define HDRL_FPN_TEST_FILTER_MASK_IMG_OUT "filter_with_mask_img_out.fits"
59#define HDRL_FPN_TEST_FILTER_MASK_MASK_OUT "filter_with_mask_mask_out.fits"
62const double const_even_img[][4] = {
63 { 0.84, -0.27, 0.07, 0.74 },
64 { 0.57, -0.265, -0.07, 0.32 },
65 { 0.25, -0.268, 0.07, 0.72 },
66 { -0.9, -0.2, -0.05, 0.57 }
69const double const_odd_img[][5] = {
70 { 0.84, -0.27, 0.07, 0.74, 0.28 },
71 { -1.2, -0.255, -0.06, 0.65, 0.74 },
72 { -1.5, -0.25, 0.06, 0.64, 0.63 },
73 { -0.84, -0.248, -0.06, -0.63, 0.56 },
74 { -0.9, -0.2, -0.05, 0.57, -1.05 }
77const double const_filter_img[][5] = {
78 { 0.84, -0.27, 0.07, 0.74, 0.28 },
79 { 0.57, -0.265, -0.07, 0.32, 0.37 },
80 { 0.25, -0.268, 0.07, 0.72, 0.47 },
81 { -1.2, -0.255, -0.06, 0.65, 0.74 },
82 { -1.5, -0.25, 0.06, 0.64, 0.63 },
83 { -0.84, -0.248, -0.06, -0.63, 0.56 },
84 { 0.84, -0.236, 0.06, 0.59, 0.26 },
85 { 0.94, -0.244, -0.06, 0.69, -0.16 },
86 { -0.84, -0.23, 0.05, 0.43, -0.50 },
87 { -0.9, -0.2, -0.05, 0.57, -1.05 }
90const double const_even_img_out_python[][4] = {
91 { 0.2827580625, 0.1036180625, 0.2962080625, 0.1036180625 },
92 { 0.7368880625, 0.1449405625, 0.1099405625, 0.1804230625 },
93 { 0.0200930625, 0.2151505625, 0.0874680625, 0.2151505625 },
94 { 0.7368880625, 0.1804230625, 0.1099405625, 0.1449405625 }
97const double const_odd_img_out_python[][5] = {
98 { 0.12013156, 0.383159364837234, 0.265579755162766, 0.265579755162766, 0.383159364837234 },
99 { 1.54915433534651, 0.400709353348878, 0.29934484816896, 0.369019554281073, 0.0991814702143874 },
100 { 0.359162784653486, 0.467499565718927, 0.400883766651123, 0.0112476497856126, 0.72090627183104 },
101 { 0.359162784653486, 0.72090627183104, 0.0112476497856126, 0.400883766651123, 0.467499565718927 },
102 { 1.54915433534651, 0.0991814702143874, 0.369019554281073, 0.29934484816896, 0.400709353348878 }
105const double const_filter_img_out_python[][10] = {
106 { 0.08193152, 0.063075752708677, 0.822150095300018, 0.344980107291323, 0.0179478446999824, 0.28697888, 0.0179478446999824, 0.344980107291323, 0.822150095300018, 0.0630757527086773 },
107 { 1.58489635987986, 0.220252697693417, 0.896622688396041, 0.0654115585573622, 0.0653615133387257, 0.0349653602187383, 0.0286088875424546, 0.0741165605524927, 0.633926559509007, 0.179705468727281 },
108 { 0.089400680120138, 0.595806301442638, 0.211423052457545, 0.125587391272719, 0.156505251603959, 0.0308983997812617, 0.0250233804909936, 0.0969931623065833, 0.786391426661275, 0.722799299447507 },
109 { 0.089400680120138, 0.722799299447507, 0.786391426661275, 0.0969931623065836, 0.0250233804909936, 0.0308983997812617, 0.156505251603959, 0.125587391272719, 0.211423052457545, 0.595806301442638 },
110 { 1.58489635987986, 0.179705468727281, 0.633926559509007, 0.0741165605524925, 0.0286088875424546, 0.0349653602187383, 0.0653615133387257, 0.0654115585573621, 0.896622688396041, 0.220252697693417 }
128static void hdrl_fpn_tests(
void)
133 cpl_size even_img_nx = 4;
134 cpl_size even_img_ny = 4;
135 cpl_image *even_img = cpl_image_new(even_img_nx, even_img_ny, CPL_TYPE_DOUBLE);
136 for(cpl_size x = 0; x < even_img_nx; x++){
137 for(cpl_size y = 0; y < even_img_ny; y++){
138 cpl_image_set(even_img, x + 1, y + 1, const_even_img[x][y]);
144 cpl_size odd_img_nx = 5;
145 cpl_size odd_img_ny = 5;
146 cpl_image *odd_img = cpl_image_new(odd_img_nx, odd_img_ny, CPL_TYPE_DOUBLE);
147 for(cpl_size x = 0; x < odd_img_nx; x++){
148 for(cpl_size y = 0; y < odd_img_ny; y++){
149 cpl_image_set(odd_img, x + 1, y + 1, const_odd_img[x][y]);
155 cpl_size filter_img_nx = 10;
156 cpl_size filter_img_ny = 5;
157 cpl_image *filter_img = cpl_image_new(filter_img_nx, filter_img_ny, CPL_TYPE_DOUBLE);
158 for(cpl_size x = 0; x < filter_img_nx; x++){
159 for(cpl_size y = 0; y < filter_img_ny; y++){
160 cpl_image_set(filter_img, x + 1, y + 1, const_filter_img[x][y]);
167 cpl_image *out_img = NULL;
169 cpl_propertylist *qclist;
179 cpl_test_error(CPL_ERROR_NULL_INPUT);
183 cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
187 cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
190 cpl_image *in_img_dummy = cpl_image_new(2, 2, CPL_TYPE_DOUBLE);
192 cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
193 cpl_image_delete(in_img_dummy);
196 cpl_image *filter_img_reject = cpl_image_duplicate(filter_img);
197 cpl_image_reject(filter_img_reject, 1, 1);
199 cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
200 cpl_image_delete(filter_img_reject);
203 cpl_mask *mask_wrong_img = cpl_mask_new(filter_img_nx - 1, filter_img_ny - 1);
205 cpl_test_error(CPL_ERROR_INCOMPATIBLE_INPUT);
206 cpl_mask_delete(mask_wrong_img);
212 cpl_test_error(CPL_ERROR_NONE);
213 cpl_test_nonnull(out_img);
216 out_mask = cpl_image_new_from_mask(cpl_image_get_bpm(out_img));
217 qclist = cpl_propertylist_new();
218 cpl_propertylist_update_double(qclist,
"ESO QC FPN RMS", rms);
219 cpl_propertylist_update_double(qclist,
"ESO QC FPN MAD", mad);
220 cpl_image_save(out_img, HDRL_FPN_TEST_EVEN_IMG_OUT, CPL_TYPE_DOUBLE, qclist, CPL_IO_CREATE);
221 cpl_image_save(out_mask, HDRL_FPN_TEST_EVEN_MASK_OUT, CPL_TYPE_DOUBLE, qclist, CPL_IO_CREATE);
224 cpl_test_rel(rms, 0.217609641787739, HDRL_DELTA_COMPARE_QC);
225 cpl_test_rel(mad, 0.0612647385, HDRL_DELTA_COMPARE_QC);
228 for(cpl_size x = 0; x < even_img_nx; x++){
229 for(cpl_size y = 0; y < even_img_ny; y++){
230 if (!cpl_image_get(out_mask, x + 1, y + 1, &null)) {
231 cpl_test_rel(cpl_image_get(out_img, x + 1, y + 1, &null), const_even_img_out_python[y][x], HDRL_DELTA_COMPARE_IMAGE);
236 cpl_image_delete( out_img );
237 cpl_image_delete( out_mask );
238 cpl_propertylist_delete( qclist );
239 cpl_image_delete( even_img );
245 cpl_test_error(CPL_ERROR_NONE);
246 cpl_test_nonnull(out_img);
249 out_mask = cpl_image_new_from_mask(cpl_image_get_bpm(out_img));
250 qclist = cpl_propertylist_new();
251 cpl_propertylist_update_double(qclist,
"ESO QC FPN RMS", rms);
252 cpl_propertylist_update_double(qclist,
"ESO QC FPN MAD", mad);
253 cpl_image_save(out_img, HDRL_FPN_TEST_ODD_IMG_OUT, CPL_TYPE_DOUBLE, qclist, CPL_IO_CREATE);
254 cpl_image_save(out_mask, HDRL_FPN_TEST_ODD_MASK_OUT, CPL_TYPE_DOUBLE, qclist, CPL_IO_CREATE);
257 cpl_test_rel(rms, 0.381960894533284, HDRL_DELTA_COMPARE_QC);
258 cpl_test_rel(mad, 0.124653092119791, HDRL_DELTA_COMPARE_QC);
261 for(cpl_size x = 0; x < odd_img_nx; x++){
262 for(cpl_size y = 0; y < odd_img_ny; y++){
263 if (!cpl_image_get(out_mask, x + 1, y + 1, &null)) {
264 cpl_test_rel(cpl_image_get(out_img, x + 1, y + 1, &null), const_odd_img_out_python[y][x], HDRL_DELTA_COMPARE_IMAGE);
269 cpl_image_delete( out_img );
270 cpl_image_delete( out_mask );
271 cpl_propertylist_delete( qclist );
272 cpl_image_delete( odd_img );
279 cpl_test_error(CPL_ERROR_NONE);
280 cpl_test_nonnull(out_img);
283 cpl_mask *filter_mask = cpl_mask_duplicate(cpl_image_get_bpm(out_img));
286 out_mask = cpl_image_new_from_mask(cpl_image_get_bpm(out_img));
287 qclist = cpl_propertylist_new();
288 cpl_propertylist_update_double(qclist,
"ESO QC FPN RMS", rms);
289 cpl_propertylist_update_double(qclist,
"ESO QC FPN MAD", mad);
290 cpl_image_save(out_img, HDRL_FPN_TEST_FILTER_IMG_OUT, CPL_TYPE_DOUBLE, qclist, CPL_IO_CREATE);
291 cpl_image_save(out_mask, HDRL_FPN_TEST_FILTER_MASK_OUT, CPL_TYPE_DOUBLE, qclist, CPL_IO_CREATE);
294 cpl_test_rel(rms, 0.346571043362885, HDRL_DELTA_COMPARE_QC);
295 cpl_test_rel(mad, 0.140385898785234, HDRL_DELTA_COMPARE_QC);
298 for(cpl_size x = 0; x < filter_img_nx; x++){
299 for(cpl_size y = 0; y < filter_img_ny; y++){
300 if (!cpl_image_get(out_mask, x + 1, y + 1, &null)) {
301 cpl_test_rel(cpl_image_get(out_img, x + 1, y + 1, &null), const_filter_img_out_python[y][x], HDRL_DELTA_COMPARE_IMAGE);
306 cpl_image_delete( out_img );
307 cpl_image_delete( out_mask );
308 cpl_propertylist_delete( qclist );
313 cpl_mask_set(filter_mask, 1, 1, CPL_BINARY_0);
315 cpl_test_error(CPL_ERROR_NONE);
316 cpl_test_nonnull(out_img);
319 const cpl_mask *out_filter_mask = cpl_image_get_bpm(out_img);
320 out_mask = cpl_image_new_from_mask(out_filter_mask);
321 qclist = cpl_propertylist_new();
322 cpl_propertylist_update_double(qclist,
"ESO QC FPN RMS", rms);
323 cpl_propertylist_update_double(qclist,
"ESO QC FPN MAD", mad);
324 cpl_image_save(out_img, HDRL_FPN_TEST_FILTER_MASK_IMG_OUT, CPL_TYPE_DOUBLE, qclist, CPL_IO_CREATE);
325 cpl_image_save(out_mask, HDRL_FPN_TEST_FILTER_MASK_MASK_OUT, CPL_TYPE_DOUBLE, qclist, CPL_IO_CREATE);
328 cpl_test_rel(rms, 0.346571043362885, HDRL_DELTA_COMPARE_QC);
329 cpl_test_rel(mad, 0.140385898785234, HDRL_DELTA_COMPARE_QC);
332 for(cpl_size x = 0; x < filter_img_nx; x++){
333 for(cpl_size y = 0; y < filter_img_ny; y++){
334 if (!cpl_image_get(out_mask, x + 1, y + 1, &null)) {
335 cpl_test_rel(cpl_image_get(out_img, x + 1, y + 1, &null), const_filter_img_out_python[y][x], HDRL_DELTA_COMPARE_IMAGE);
341 for(cpl_size x = 1; x <= filter_img_nx; x++){
342 for(cpl_size y = 1; y <= filter_img_ny; y++){
343 cpl_binary bpm_pixel = cpl_mask_get(out_filter_mask, x, y);
344 if (x <= 3 && y <= 3) {
345 cpl_test_eq(bpm_pixel, CPL_BINARY_1);
347 cpl_test_eq(bpm_pixel, CPL_BINARY_0);
353 cpl_image_delete( out_img );
354 cpl_image_delete( out_mask );
355 cpl_propertylist_delete( qclist );
356 cpl_mask_delete( filter_mask );
357 cpl_image_delete( filter_img );
360 cpl_test_zero(remove(HDRL_FPN_TEST_EVEN_IMG_OUT ));
361 cpl_test_zero(remove(HDRL_FPN_TEST_EVEN_MASK_OUT ));
362 cpl_test_zero(remove(HDRL_FPN_TEST_ODD_IMG_OUT ));
363 cpl_test_zero(remove(HDRL_FPN_TEST_ODD_MASK_OUT ));
364 cpl_test_zero(remove(HDRL_FPN_TEST_FILTER_IMG_OUT ));
365 cpl_test_zero(remove(HDRL_FPN_TEST_FILTER_MASK_OUT ));
366 cpl_test_zero(remove(HDRL_FPN_TEST_FILTER_MASK_IMG_OUT ));
367 cpl_test_zero(remove(HDRL_FPN_TEST_FILTER_MASK_MASK_OUT));
412 cpl_test_init(PACKAGE_BUGREPORT, CPL_MSG_WARNING);
419 cpl_test_error(CPL_ERROR_NONE);
421 return cpl_test_end(0);
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.