CR2RE Pipeline Reference Manual 1.6.10
hdrl_image_math.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/*-----------------------------------------------------------------------------
25 Includes
26 -----------------------------------------------------------------------------*/
27
28#include "hdrl_elemop.h"
29#include "hdrl_image.h"
30#include "hdrl_collapse.h"
31
32#include <cpl.h>
33#include <math.h>
34
35/*-----------------------------------------------------------------------------
36 Functions
37 -----------------------------------------------------------------------------*/
38
39/*----------------------------------------------------------------------------*/
57/*----------------------------------------------------------------------------*/
58cpl_error_code
59hdrl_image_add_image(hdrl_image * self, const hdrl_image * other)
60{
61 cpl_ensure_code(self, CPL_ERROR_NULL_INPUT);
62 cpl_ensure_code(other, CPL_ERROR_NULL_INPUT);
63 /* size check included in elemop */
64 return hdrl_elemop_image_add_image(hdrl_image_get_image(self), hdrl_image_get_error(self),
67}
68
69/*----------------------------------------------------------------------------*/
87/*----------------------------------------------------------------------------*/
88hdrl_image *
89hdrl_image_add_image_create(const hdrl_image * self, const hdrl_image * other)
90{
91 hdrl_image * n = hdrl_image_duplicate(self);
92
93 if (hdrl_image_add_image(n, other)) {
95 return NULL;
96 }
97
98 return n;
99}
100
101/*----------------------------------------------------------------------------*/
115/*----------------------------------------------------------------------------*/
116cpl_error_code
117hdrl_image_add_scalar(hdrl_image * self, hdrl_value value)
118{
119 cpl_ensure_code(self, CPL_ERROR_NULL_INPUT);
120 /* size check included in elemop */
121 return hdrl_elemop_image_add_scalar(hdrl_image_get_image(self),
123 value.data, value.error);
124}
125
126/*----------------------------------------------------------------------------*/
135/*----------------------------------------------------------------------------*/
136cpl_error_code
137hdrl_image_sub_image(hdrl_image * self, const hdrl_image * other)
138{
139 cpl_ensure_code(self, CPL_ERROR_NULL_INPUT);
140 cpl_ensure_code(other, CPL_ERROR_NULL_INPUT);
141 /* size check included in elemop */
142 return hdrl_elemop_image_sub_image(hdrl_image_get_image(self), hdrl_image_get_error(self),
145}
146
147/*----------------------------------------------------------------------------*/
156/*----------------------------------------------------------------------------*/
157hdrl_image *
158hdrl_image_sub_image_create(const hdrl_image * self, const hdrl_image * other)
159{
160 hdrl_image * n = hdrl_image_duplicate(self);
161
162 if (hdrl_image_sub_image(n, other)) {
164 return NULL;
165 }
166
167 return n;
168}
169
170/*----------------------------------------------------------------------------*/
179/*----------------------------------------------------------------------------*/
180cpl_error_code
181hdrl_image_sub_scalar(hdrl_image * self, hdrl_value value)
182{
183 cpl_ensure_code(self, CPL_ERROR_NULL_INPUT);
184 /* size check included in elemop */
185 return hdrl_elemop_image_sub_scalar(hdrl_image_get_image(self),
187 value.data, value.error);
188}
189
190/*----------------------------------------------------------------------------*/
199/*----------------------------------------------------------------------------*/
200cpl_error_code
201hdrl_image_mul_image(hdrl_image * self, const hdrl_image * other)
202{
203 cpl_ensure_code(self, CPL_ERROR_NULL_INPUT);
204 cpl_ensure_code(other, CPL_ERROR_NULL_INPUT);
205 /* size check included in elemop */
206 return hdrl_elemop_image_mul_image(hdrl_image_get_image(self), hdrl_image_get_error(self),
209}
210
211/*----------------------------------------------------------------------------*/
220/*----------------------------------------------------------------------------*/
221hdrl_image *
222hdrl_image_mul_image_create(const hdrl_image * self, const hdrl_image * other)
223{
224 hdrl_image * n = hdrl_image_duplicate(self);
225
226 if (hdrl_image_mul_image(n, other)) {
228 return NULL;
229 }
230
231 return n;
232}
233
234/*----------------------------------------------------------------------------*/
243/*----------------------------------------------------------------------------*/
244cpl_error_code
245hdrl_image_mul_scalar(hdrl_image * self, hdrl_value value)
246{
247 cpl_ensure_code(self, CPL_ERROR_NULL_INPUT);
248 /* size check included in elemop */
249 return hdrl_elemop_image_mul_scalar(hdrl_image_get_image(self),
251 value.data, value.error);
252}
253
254/*----------------------------------------------------------------------------*/
271/*----------------------------------------------------------------------------*/
272cpl_error_code
273hdrl_image_div_image(hdrl_image * self, const hdrl_image * other)
274{
275 cpl_ensure_code(self, CPL_ERROR_NULL_INPUT);
276 cpl_ensure_code(other, CPL_ERROR_NULL_INPUT);
277 /* size check included in elemop */
278 return hdrl_elemop_image_div_image(hdrl_image_get_image(self), hdrl_image_get_error(self),
281}
282
283/*----------------------------------------------------------------------------*/
300/*----------------------------------------------------------------------------*/
301hdrl_image *
302hdrl_image_div_image_create(const hdrl_image * self, const hdrl_image * other)
303{
304 hdrl_image * n = hdrl_image_duplicate(self);
305
306 if (hdrl_image_div_image(n, other)) {
308 return NULL;
309 }
310
311 return n;
312}
313
314/*----------------------------------------------------------------------------*/
327/*----------------------------------------------------------------------------*/
328cpl_error_code
329hdrl_image_div_scalar(hdrl_image * self, hdrl_value value)
330{
331 cpl_ensure_code(self, CPL_ERROR_NULL_INPUT);
332 /* size check included in elemop */
333 return hdrl_elemop_image_div_scalar(hdrl_image_get_image(self),
335 value.data, value.error);
336}
337/*----------------------------------------------------------------------------*/
343/*----------------------------------------------------------------------------*/
344static cpl_error_code
345hdrl_image_collapse(hdrl_collapse_imagelist_to_vector_t * red,
346 const hdrl_image * self,
347 hdrl_data_t * result, hdrl_error_t * error,
348 int * contrib, void * eout)
349{
350 cpl_imagelist * ld = cpl_imagelist_new();
351 cpl_imagelist * le = cpl_imagelist_new();
352 cpl_vector * od = NULL, * oe = NULL;
353 cpl_array * oc = NULL;
354 cpl_error_code fail;
355
356 CPL_DIAG_PRAGMA_PUSH_IGN(-Wcast-qual);
357 cpl_imagelist_set(ld, hdrl_image_get_image((hdrl_image * )self), 0);
358 cpl_imagelist_set(le, hdrl_image_get_error((hdrl_image * )self), 0);
359 CPL_DIAG_PRAGMA_POP;
360
361 fail = hdrl_collapse_imagelist_to_vector_call(red, ld, le, &od, &oe, &oc,
362 eout);
363 cpl_imagelist_unwrap(ld);
364 cpl_imagelist_unwrap(le);
365
366 if (fail == CPL_ERROR_NONE) {
367 if (result) {
368 *result = cpl_vector_get(od, 0);
369 }
370 if (error) {
371 *error = cpl_vector_get(oe, 0);
372 }
373 if (contrib) {
374 *contrib = cpl_array_get_int(oc, 0, NULL);
375 }
376 }
377 else {
378 if (result) {
379 *result = NAN;
380 }
381 if (error) {
382 *error = NAN;
383 }
384 }
385
386 cpl_vector_delete(od);
387 cpl_vector_delete(oe);
388 cpl_array_delete(oc);
389
390 return fail;
391}
392
393/*----------------------------------------------------------------------------*/
400/*----------------------------------------------------------------------------*/
401hdrl_value
402hdrl_image_get_mean(const hdrl_image * self)
403{
404 hdrl_collapse_imagelist_to_vector_t * red =
405 hdrl_collapse_imagelist_to_vector_mean();
406 hdrl_value res;
407 hdrl_image_collapse(red, self, &res.data, &res.error, NULL, NULL);
408 hdrl_collapse_imagelist_to_vector_delete(red);
409 return res;
410}
411
412/*----------------------------------------------------------------------------*/
423/*----------------------------------------------------------------------------*/
424hdrl_value
425hdrl_image_get_sigclip_mean(const hdrl_image * self, double kappa_low,
426 double kappa_high, int niter)
427{
428 hdrl_collapse_imagelist_to_vector_t * red =
429 hdrl_collapse_imagelist_to_vector_sigclip(kappa_low, kappa_high, niter);
430 hdrl_value res;
431 hdrl_image_collapse(red, self, &res.data, &res.error, NULL, NULL);
432 hdrl_collapse_imagelist_to_vector_delete(red);
433 return res;
434}
435
436/*----------------------------------------------------------------------------*/
446/*----------------------------------------------------------------------------*/
447hdrl_value
448hdrl_image_get_minmax_mean(const hdrl_image * self, double nlow,
449 double nhigh)
450{
451 hdrl_collapse_imagelist_to_vector_t * red =
452 hdrl_collapse_imagelist_to_vector_minmax(nlow, nhigh);
453 hdrl_value res;
454 hdrl_image_collapse(red, self, &res.data, &res.error, NULL, NULL);
455 hdrl_collapse_imagelist_to_vector_delete(red);
456 return res;
457}
458
459/*----------------------------------------------------------------------------*/
472/*----------------------------------------------------------------------------*/
473hdrl_value
474hdrl_image_get_mode(const hdrl_image * self, double histo_min,
475 double histo_max, double bin_size,
476 hdrl_mode_type method, cpl_size error_niter)
477{
478 hdrl_collapse_imagelist_to_vector_t * red =
479 hdrl_collapse_imagelist_to_vector_mode(histo_min, histo_max, bin_size,
480 method, error_niter);
481 hdrl_value res;
482 hdrl_image_collapse(red, self, &res.data, &res.error, NULL, NULL);
483 hdrl_collapse_imagelist_to_vector_delete(red);
484 return res;
485}
486
487/*----------------------------------------------------------------------------*/
499/*----------------------------------------------------------------------------*/
500hdrl_value
501hdrl_image_get_median(const hdrl_image * self)
502{
503 hdrl_collapse_imagelist_to_vector_t * red =
504 hdrl_collapse_imagelist_to_vector_median();
505 hdrl_value res;
506 hdrl_image_collapse(red, self, &res.data, &res.error, NULL, NULL);
507 hdrl_collapse_imagelist_to_vector_delete(red);
508 return res;
509}
510
511/*----------------------------------------------------------------------------*/
518/*----------------------------------------------------------------------------*/
519hdrl_value
520hdrl_image_get_weighted_mean(const hdrl_image * self)
521{
522 hdrl_collapse_imagelist_to_vector_t * red =
523 hdrl_collapse_imagelist_to_vector_weighted_mean();
524 hdrl_value res;
525 hdrl_image_collapse(red, self, &res.data, &res.error, NULL, NULL);
526 hdrl_collapse_imagelist_to_vector_delete(red);
527 return res;
528}
529
530/*----------------------------------------------------------------------------*/
538/*----------------------------------------------------------------------------*/
539double
540hdrl_image_get_stdev(const hdrl_image * self)
541{
542 return cpl_image_get_stdev(hdrl_image_get_image_const(self));
543}
544
545/*----------------------------------------------------------------------------*/
553/*----------------------------------------------------------------------------*/
554hdrl_value
555hdrl_image_get_sum(const hdrl_image * self)
556{
557 int contrib;
558 hdrl_value res;
559 hdrl_collapse_imagelist_to_vector_t * red =
560 hdrl_collapse_imagelist_to_vector_mean();
561 cpl_error_code err = hdrl_image_collapse(red, self, &res.data, &res.error,
562 &contrib, NULL);
563 if (err == CPL_ERROR_NONE) {
564 res.data *= contrib;
565 res.error *= contrib;
566 }
567 else {
568 res.data = NAN;
569 res.error = NAN;
570 }
571 hdrl_collapse_imagelist_to_vector_delete(red);
572 return res;
573}
574
575/*----------------------------------------------------------------------------*/
583/*----------------------------------------------------------------------------*/
584hdrl_value
585hdrl_image_get_sqsum(const hdrl_image * self)
586{
587 /* TODO could be a specialized collapse method for better performance */
588 hdrl_image * tmp = hdrl_image_pow_scalar_create(self, (hdrl_value){2, 0.});
589 hdrl_value res = hdrl_image_get_sum(tmp);
591 return res;
592}
593
594
595/*----------------------------------------------------------------------------*/
604/*----------------------------------------------------------------------------*/
605cpl_error_code
606hdrl_image_pow_scalar(hdrl_image * self, const hdrl_value exponent)
607{
608 cpl_ensure_code(self, CPL_ERROR_NULL_INPUT);
609 /* size check included in elemop */
610 return hdrl_elemop_image_pow_scalar(hdrl_image_get_image(self),
612 exponent.data, exponent.error);
613}
614
615/*----------------------------------------------------------------------------*/
624/*----------------------------------------------------------------------------*/
625hdrl_image *
626hdrl_image_pow_scalar_create(const hdrl_image * self, const hdrl_value exponent)
627{
628 hdrl_image * n = hdrl_image_duplicate(self);
629
630 if (hdrl_image_pow_scalar(n, exponent)) {
632 return NULL;
633 }
634
635 return n;
636}
637
638/*----------------------------------------------------------------------------*/
647/*----------------------------------------------------------------------------*/
648cpl_error_code
649hdrl_image_exp_scalar(hdrl_image * self, const hdrl_value base)
650{
651 cpl_ensure_code(self, CPL_ERROR_NULL_INPUT);
652 /* size check included in elemop */
653 return hdrl_elemop_image_exp_scalar(hdrl_image_get_image(self),
655 base.data, base.error);
656}
657
658/*----------------------------------------------------------------------------*/
667/*----------------------------------------------------------------------------*/
668hdrl_image *
669hdrl_image_exp_scalar_create(const hdrl_image * self, const hdrl_value base)
670{
671 hdrl_image * n = hdrl_image_duplicate(self);
672
673 if (hdrl_image_exp_scalar(n, base)) {
675 return NULL;
676 }
677
678 return n;
679}
hdrl_image * hdrl_image_pow_scalar_create(const hdrl_image *self, const hdrl_value exponent)
computes the power of an image by a scalar creating a new image
cpl_error_code hdrl_image_sub_image(hdrl_image *self, const hdrl_image *other)
Subtract two images, store the result in the first image.
cpl_error_code hdrl_image_div_scalar(hdrl_image *self, hdrl_value value)
Elementwise division of an image with a scalar.
hdrl_value hdrl_image_get_median(const hdrl_image *self)
computes the median and associated error of an image.
hdrl_value hdrl_image_get_sqsum(const hdrl_image *self)
computes the sum of all pixel values and the error of a squared image.
hdrl_value hdrl_image_get_mode(const hdrl_image *self, double histo_min, double histo_max, double bin_size, hdrl_mode_type method, cpl_size error_niter)
computes the mode and the associated error of an image.
hdrl_image * hdrl_image_sub_image_create(const hdrl_image *self, const hdrl_image *other)
Subtract two images.
cpl_error_code hdrl_image_pow_scalar(hdrl_image *self, const hdrl_value exponent)
computes the power of an image by a scalar
cpl_error_code hdrl_image_add_image(hdrl_image *self, const hdrl_image *other)
Add two images, store the result in the first image.
cpl_error_code hdrl_image_div_image(hdrl_image *self, const hdrl_image *other)
Divide two images, store the result in the first image.
cpl_error_code hdrl_image_mul_scalar(hdrl_image *self, hdrl_value value)
Elementwise multiplication of an image with a scalar.
hdrl_image * hdrl_image_duplicate(const hdrl_image *himg)
copy hdrl_image
Definition: hdrl_image.c:391
hdrl_value hdrl_image_get_minmax_mean(const hdrl_image *self, double nlow, double nhigh)
computes the minmax rejected mean and the associated error of an image.
hdrl_value hdrl_image_get_sigclip_mean(const hdrl_image *self, double kappa_low, double kappa_high, int niter)
computes the sigma-clipped mean and associated error of an image.
double hdrl_image_get_stdev(const hdrl_image *self)
computes the standard deviation of the data of an image
hdrl_image * hdrl_image_div_image_create(const hdrl_image *self, const hdrl_image *other)
Divide two images and return the resulting image.
cpl_error_code hdrl_image_add_scalar(hdrl_image *self, hdrl_value value)
Elementwise addition of a scalar to an image.
cpl_error_code hdrl_image_mul_image(hdrl_image *self, const hdrl_image *other)
Multiply two images, store the result in the first image.
hdrl_value hdrl_image_get_sum(const hdrl_image *self)
computes the sum of all pixel values and the associated error of an image.
cpl_error_code hdrl_image_exp_scalar(hdrl_image *self, const hdrl_value base)
computes the exponential of an image by a scalar
cpl_image * hdrl_image_get_error(hdrl_image *himg)
get error as cpl image
Definition: hdrl_image.c:131
hdrl_value hdrl_image_get_mean(const hdrl_image *self)
computes mean pixel value and associated error of an image.
hdrl_value hdrl_image_get_weighted_mean(const hdrl_image *self)
computes the weighted mean and associated error of an image.
const cpl_image * hdrl_image_get_error_const(const hdrl_image *himg)
get error as cpl image
Definition: hdrl_image.c:144
hdrl_image * hdrl_image_add_image_create(const hdrl_image *self, const hdrl_image *other)
Add two images.
hdrl_image * hdrl_image_mul_image_create(const hdrl_image *self, const hdrl_image *other)
Multiply two images.
cpl_image * hdrl_image_get_image(hdrl_image *himg)
get data as cpl image
Definition: hdrl_image.c:105
const cpl_image * hdrl_image_get_image_const(const hdrl_image *himg)
get data as cpl image
Definition: hdrl_image.c:118
hdrl_image * hdrl_image_exp_scalar_create(const hdrl_image *self, const hdrl_value base)
computes the exponential of an image by a scalar creating a new image
void hdrl_image_delete(hdrl_image *himg)
delete hdrl_image
Definition: hdrl_image.c:379
cpl_error_code hdrl_image_sub_scalar(hdrl_image *self, hdrl_value value)
Elementwise subtraction of a scalar from an image.