28#include "hdrl_correlation.h"
34create_rect(
const cpl_size sz,
const cpl_size start,
const cpl_size stop){
36 cpl_array * v = cpl_array_new(sz, CPL_TYPE_DOUBLE);
38 for(cpl_size i = 0; i < sz; ++i){
42 if(i >= start && i <= stop)
45 cpl_array_set(v, i, p);
52create_gaussian(cpl_size num_samples,
const double mean,
const double stdev,
53 const double center,
double * delta_out){
55 cpl_array * v = cpl_array_new(num_samples, CPL_TYPE_DOUBLE);
56 const double size = 8.0;
57 const double delta = size * stdev / (double)num_samples;
58 const double start = -size * .5 * stdev + center;
59 for(cpl_size i = 0; i < num_samples; ++i){
60 const double x = delta * ((double)i) + start;
61 const double val = (x - mean) / stdev;
62 const double exponential = -.5 * pow(val, 2.0);
63 const double y = exp(exponential)/(stdev * sqrt(2. * CPL_MATH_PI));
64 cpl_array_set(v, i, y);
79void test_shift_pixel_precision(
const cpl_size in_shift){
81 const cpl_size sz = 28;
82 const cpl_size win = 14;
83 cpl_array * v1 = create_rect(sz, 3, 5);
84 cpl_array * v2 = create_rect(sz, 3 + llabs(in_shift), 5 + llabs(in_shift));
92 hdrl_xcorrelation_result * res =
96 const cpl_size shift = idx - win;
100 cpl_test_eq(shift, -in_shift);
103 cpl_test_rel(cpl_array_get(xcorr, idx, NULL),
104 25.0 * 3.0 /((
double)sz), 1e-5);
105 cpl_test_rel(cpl_array_get(xcorr, idx - 1, NULL),
106 25.0 * 2.0 /((
double)sz - 1.0), 1e-5);
107 cpl_test_rel(cpl_array_get(xcorr, idx + 1, NULL),
108 25.0 * 2.0 /((
double)sz - 1.0), 1e-5);
109 cpl_test_rel(cpl_array_get(xcorr, idx - 2, NULL),
110 25.0 * 1.0 /((
double)sz - 2.0), 1e-5);
111 cpl_test_rel(cpl_array_get(xcorr, idx + 2, NULL),
112 25.0 * 1.0 /((
double)sz - 2.0), 1e-5);
113 for(cpl_size i = 0; i < win * 2 + 1; i++){
114 if(i >= idx - 2 && i <= idx + 2)
continue;
115 cpl_test_rel(cpl_array_get(xcorr, i, NULL), 0.0, 1e-5);
121 cpl_array_delete(v1);
122 cpl_array_delete(v2);
125void test_shift_gaussian_fit(
const double mean_diff,
126 const cpl_boolean use_win_refinement){
128 const double m1 = 1.0;
129 const double m2 = m1 + mean_diff;
130 const double std_dev = sqrt(.5);
131 const cpl_size sz = 100;
132 cpl_size half_w = 180;
134 cpl_array * arr1 = create_gaussian(sz, m1, std_dev, .5 * (m1 + m2), &delta);
135 cpl_array * arr2 = create_gaussian(sz, m2, std_dev, .5 * (m1 + m2), &delta);
137 hdrl_xcorrelation_result * r = NULL;
139 if(use_win_refinement)
141 half_w, CPL_TRUE, delta, 0.5);
144 half_w, CPL_TRUE, delta, 0.5);
148 const double tolerance = use_win_refinement ? 5.6e-2 : 6e-2;
149 if (mean_diff != 0.0) {
150 cpl_test_rel(-peak + used_win * delta, mean_diff, tolerance);
152 cpl_test_abs(peak, used_win * delta, tolerance);
156 cpl_array_delete(arr1);
157 cpl_array_delete(arr2);
167 cpl_test_init(PACKAGE_BUGREPORT, CPL_MSG_WARNING);
169 test_shift_pixel_precision(0);
170 test_shift_pixel_precision(2);
171 test_shift_pixel_precision(6);
172 test_shift_pixel_precision(-2);
173 test_shift_pixel_precision(-6);
176 test_shift_gaussian_fit(2.4, CPL_FALSE);
177 test_shift_gaussian_fit(-2.4, CPL_FALSE);
178 test_shift_gaussian_fit(1.8, CPL_FALSE);
179 test_shift_gaussian_fit(0.0, CPL_FALSE);
181 test_shift_gaussian_fit(2.4, CPL_TRUE);
182 test_shift_gaussian_fit(-2.4, CPL_TRUE);
183 test_shift_gaussian_fit(1.8, CPL_TRUE);
184 test_shift_gaussian_fit(0.0, CPL_TRUE);
186 cpl_test_error(CPL_ERROR_NONE);
188 return cpl_test_end(0);
void hdrl_xcorrelation_result_delete(hdrl_xcorrelation_result *self)
Destructor for hdrl_xcorrelation_result.
hdrl_xcorrelation_result * hdrl_compute_xcorrelation(const cpl_array *arr1, const cpl_array *arr2, const cpl_size half_window, const cpl_boolean normalize)
Calculate cross-correlation.
const cpl_array * hdrl_xcorrelation_result_get_correlation(const hdrl_xcorrelation_result *self)
Getter for the cross correlation.
cpl_size hdrl_xcorrelation_result_get_peak_pixel(const hdrl_xcorrelation_result *self)
Get the index where the cross correlation reaches its maximum.
cpl_size hdrl_xcorrelation_result_get_half_window(const hdrl_xcorrelation_result *self)
Get the half_window used to calculate the cross-correlation.
hdrl_xcorrelation_result * hdrl_compute_offset_gaussian_internal(const cpl_array *arr1, const cpl_array *arr2, const cpl_size half_win, const cpl_boolean normalize, const double bin, const double wrange)
Calculate gaussian fit on cross-correlation.
hdrl_xcorrelation_result * hdrl_compute_offset_gaussian(const cpl_array *arr1, const cpl_array *arr2, const cpl_size half_win, const cpl_boolean normalize, const double bin, const double wrange)
Calculate gaussian fit on cross-correlation, does a second fitting for refinement.
double hdrl_xcorrelation_result_get_peak_subpixel(const hdrl_xcorrelation_result *self)
Get the index where the cross correlation reaches its maximum, with sub-pixel precision.