[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

correlation.hxx
1/************************************************************************/
2/* */
3/* Copyright 2007-2014 by Benjamin Seppke */
4/* */
5/* This file is part of the VIGRA computer vision library. */
6/* The VIGRA Website is */
7/* http://hci.iwr.uni-heidelberg.de/vigra/ */
8/* Please direct questions, bug reports, and contributions to */
9/* ullrich.koethe@iwr.uni-heidelberg.de or */
10/* vigra@informatik.uni-hamburg.de */
11/* */
12/* Permission is hereby granted, free of charge, to any person */
13/* obtaining a copy of this software and associated documentation */
14/* files (the "Software"), to deal in the Software without */
15/* restriction, including without limitation the rights to use, */
16/* copy, modify, merge, publish, distribute, sublicense, and/or */
17/* sell copies of the Software, and to permit persons to whom the */
18/* Software is furnished to do so, subject to the following */
19/* conditions: */
20/* */
21/* The above copyright notice and this permission notice shall be */
22/* included in all copies or substantial portions of the */
23/* Software. */
24/* */
25/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */
26/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */
27/* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */
28/* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */
29/* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
30/* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
31/* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
32/* OTHER DEALINGS IN THE SOFTWARE. */
33/* */
34/************************************************************************/
35
36#ifndef VIGRA_CORRELATION_HXX
37#define VIGRA_CORRELATION_HXX
38
39#include "stdimage.hxx"
40#include "inspectimage.hxx"
41#include "functorexpression.hxx"
42#include "multi_math.hxx"
43#include "multi_fft.hxx"
44#include "integral_image.hxx"
45
46// "slow" correlation algorithms are performed using the windowing filter env.
47#include "applywindowfunction.hxx"
48
49namespace vigra
50{
51
52/** \addtogroup Correlation Image Correlation
53
54 Fast (FFT-based) and slow algorithms to estimate the correlation between images.
55*/
56//@{
57
58/********************************************************/
59/* */
60/* Fast cross correlation of an image w.r.t a mask */
61/* */
62/********************************************************/
63
64/** \brief This function performes a fast cross-correlation
65
66 This function performes a fast cross-correlation using the Fast Fourier Transform and
67 the dependency of the convolution and the correlation in Fourier space.
68
69 The input pixel type <tt>T1</tt> must be a \ref LinearSpace "linear space" over
70 the window functions' value_type <tt>T</tt>, i.e. addition of source values, multiplication with functions' values,
71 and NumericTraits must be defined. The mask's value_type must be an \ref AlgebraicField "algebraic field",
72 i.e. the arithmetic operations (+, -, *, /) and NumericTraits must be defined.
73
74 By default, the borders are filled with zeros. Use the clearBorders switch to change that behavior if you need to.
75
76 <b> Declarations:</b>
77
78 pass 2D array views:
79 \code
80 namespace vigra {
81 template <class T1, class S1,
82 class T2, class S2,
83 class T3, class S3,
84 unsigned int N>
85 void
86 fastCrossCorrelation(MultiArrayView<N, T1, S1> const & in,
87 MultiArrayView<N, T2, S2> const & mask,
88 MultiArrayView<N, T3, S3> out,
89 bool clearBorders=true);
90
91 }
92 \endcode
93
94
95 <b> Usage:</b>
96
97 <b>\#include</b> <vigra/correlation.hxx><br/>
98 Namespace: vigra
99
100 \code
101 unsigned int m_w=51, m_h=51;
102 unsigned int w=1000, h=1000;
103 MultiArray<2, float> mask(m_w,m_h), src(w,h), dest(w,h);
104 ...
105
106 //compute fast cross correlation of mask and image -> dest
107 fastCrossCorrelation(mask, src, dest);
108 \endcode
109
110 <b> Preconditions:</b>
111
112 The image must be larger than the size of the mask.
113 */
114doxygen_overloaded_function(template <...> void fastCrossCorrelation)
115
116template <class T1, class S1,
117class T2, class S2,
118class T3, class S3,
119unsigned int N>
121 MultiArrayView<N, T2, S2> const & mask,
123 bool clearBorders=true)
124{
125 vigra_precondition(in.shape() == out.shape(),
126 "vigra::fastCrossCorrelation(): shape mismatch between input and output.");
127 correlateFFT(in, mask, out);
128
129 if(clearBorders)
130 {
131 typedef typename MultiArrayShape<N>::type Shape;
132 Shape maskRadius(floor(mask.shape()/2));
133 initMultiArrayBorder(out, maskRadius, maskRadius, T3());
134 }
135}
136
137namespace detail {
138
139template<class T1, class S1>
140inline double integralMultiArrayWindowMean(MultiArrayView<1, T1, S1> const & in,
141 typename MultiArrayView<1, T1, S1>::difference_type const & left,
142 typename MultiArrayView<1, T1, S1>::difference_type const & right)
143{
144 return in[right]-in[left];
145}
146
147template<class T1, class S1>
148inline double integralMultiArrayWindowMean(MultiArrayView<2, T1, S1> const & in,
151{
152 return in[lr] - in(lr[0],ul[1]) - in(ul[0],lr[1]) + in[ul];
153}
154
155template<class T1, class S1>
156inline double integralMultiArrayWindowMean(MultiArrayView<3, T1, S1> const & in,
159{
160 return (in[lr] - in(lr[0],ul[1],lr[2]) - in(ul[0],lr[1],lr[2]) + in(ul[0],ul[1],lr[2]))
161 - (in(lr[0],lr[1],ul[2]) - in(lr[0],ul[1],ul[2]) - in(ul[0],lr[1],ul[2]) + in[ul]);
162}
163
164} // namespace detail
165
166/********************************************************/
167/* */
168/* Fast normalized cross correlation of mask to image */
169/* */
170/********************************************************/
171
172/** \brief This function performes a fast normalized cross-correlation
173
174 To compute the normalized cross correlation in a fast way, it is using the Fast Fourier Transform and sum-image look-up-tables as it is suggested by J.P.Lewis (1995):
175 <i>"Fast Normalized Cross-Correlation"</i>.
176
177 The input pixel type <tt>T1</tt> must be a \ref LinearSpace "linear space" over
178 the window functions' value_type <tt>T</tt>, i.e. addition of source values, multiplication with functions' values,
179 and NumericTraits must be defined. The mask's value_type must be an \ref AlgebraicField "algebraic field",
180 i.e. the arithmetic operations (+, -, *, /) and NumericTraits must be defined.
181
182 By default, the borders are filled with zeros. Use the clearBorders switch to change that behavior if you need to.
183
184 <b> Declarations:</b>
185
186 pass 2D array views:
187 \code
188 namespace vigra {
189 template <class T1, class S1,
190 class T2, class S2,
191 class T3, class S3>
192 void
193 fastNormalizedCrossCorrelation(MultiArrayView<2, T1, S1> const & in,
194 MultiArrayView<2, T2, S2> const & mask,
195 MultiArrayView<2, T3, S3> out,
196 bool clearBorders=true);
197
198 }
199 \endcode
200
201
202 <b> Usage:</b>
203
204 <b>\#include</b> <vigra/correlation.hxx><br/>
205 Namespace: vigra
206
207 \code
208 unsigned int m_w=51, m_h=51;
209 unsigned int w=1000, h=1000;
210 MultiArray<2, float> mask(m_w,m_h), src(w,h), dest(w,h);
211 ...
212
213 //compute normalized cross correlation of mask and image -> dest
214 fastNormalizedCrossCorrelation(mask, src, dest);
215 \endcode
216
217 <b> Preconditions:</b>
218
219 The image must be larger than the size of the mask.
220*/
221doxygen_overloaded_function(template <...> void fastNormalizedCrossCorrelation)
222
223template <class T1, class S1,
224 class T2, class S2,
225 class T3, class S3,
226 unsigned int N>
228 MultiArrayView<N, T2, S2> const & mask,
230 bool clearBorders=true)
231{
232 using namespace vigra::multi_math;
233 typedef typename MultiArrayShape<N>::type Shape;
234
235 vigra_precondition(in.shape() == out.shape(),
236 "vigra::fastNormalizedCrossCorrelation(): shape mismatch between input and output.");
237
238 vigra_precondition(N>0 && N<=3,
239 "vigra::fastNormalizedCrossCorrelation(): only implemented for arrays of 1, 2 or 3 dimensions.");
240
241 for(unsigned int dim=0; dim<N; dim++)
242 {
243 vigra_precondition(mask.shape()[dim] % 2 == 1, "vigra::fastNormalizedCrossCorrelation(): Mask width has to be of odd size!");
244 vigra_precondition(in.shape()[dim] >= mask.shape()[dim] , "vigra::fastNormalizedCrossCorrelation(): Mask is larger than image!");
245 }
246
247 //find mask mean and variance
248 double mask_mean = 0.0,
249 mask_var = 0.0,
250 mask_size = prod(mask.shape());
251 mask.meanVariance(&mask_mean, &mask_var);
252
253 //calculate the fix part of the denumerator a.k.a. the mask std. deviation
254 double fix_denumerator = mask_size*sqrt(mask_var);
255
256 if(fix_denumerator == 0)
257 {
258 out = 0;
259 }
260 else
261 {
262 //pre-normalize the mask
263 MultiArray<N, double> norm_mask(mask.shape());
264 norm_mask = mask;
265 norm_mask -= mask_mean;
266
267 //calculate (semi-normalized) numerator:
268 MultiArray<N, double> corr_result(in.shape());
269
270 corr_result=in;
271 fastCrossCorrelation(corr_result, norm_mask, corr_result, clearBorders);
272
273
274 //Create fast sum tables for the variable denumerator
275 MultiArray<N, double> sum_table(in.shape()+1),
276 sum_table2(in.shape()+1);
277
279
280 // now finally fill the sum tables
281 // keep a zero line/coloum at the beginning to avoid border computations and conditionals
282 integralMultiArray(in,sum_table.subarray(zero_diff+1, in.shape()+1));
283 integralMultiArraySquared(in, sum_table2.subarray(zero_diff+1, in.shape()+1));
284
285 MultiCoordinateIterator<N> i(in.shape()-mask.shape()+1), end = i.getEndIterator();
286
287 Shape maskRadius(floor(mask.shape()/2));
288 for(; i != end; ++i)
289 {
290 //calculate e(window) and e(window^2)
291 double window_mean = detail::integralMultiArrayWindowMean(sum_table, *i, *i+mask.shape()),
292 window_squared_mean = detail::integralMultiArrayWindowMean(sum_table2, *i, *i+mask.shape()),
293 var_denumerator = sqrt(mask_size*window_squared_mean - window_mean*window_mean);
294
295 //calculate overall result
296 if(var_denumerator == 0)
297 {
298 out[*i+maskRadius] = 0;
299 }
300 else
301 {
302 out[*i+maskRadius] = mask_size*corr_result[*i+maskRadius]/(var_denumerator*fix_denumerator);
303 }
304 }
305 }
306}
307
308template<class MaskIterator, class MaskAccessor>
309class CorrelationFunctor
310{
311public:
312 CorrelationFunctor(MaskIterator m_ul, MaskIterator m_lr, MaskAccessor m_acc)
313 : m_mask_ul(m_ul),
314 m_mask_lr(m_lr),
315 m_mask_acc(m_acc)
316 {
317 }
318
319 CorrelationFunctor(triple<MaskIterator,MaskIterator,MaskAccessor> m)
320 : m_mask_ul(m.first),
321 m_mask_lr(m.second),
322 m_mask_acc(m.third)
323 {
324 }
325
326 template <class SrcIterator, class SrcAccessor, class DestIterator, class DestAccessor>
327 void operator()(SrcIterator s, SrcAccessor s_acc, DestIterator d, DestAccessor d_acc) const
328 {
329 using namespace vigra;
330
331 SrcIterator s_ul = s - windowShape()/2,
332 s_lr = s + windowShape()/2+Diff2D(1,1);
333
334 //find img2 mean
335 FindAverage<double> average;
336 inspectImage(srcIterRange(s_ul, s_lr, s_acc), average);
337
338 SrcIterator ys = s_ul;
339 SrcIterator xs = ys;
340
341 MaskIterator ym = m_mask_ul;
342 MaskIterator xm = ym;
343
344 double res=0;
345
346 for( ; ys.y != s_lr.y; ys.y++, ym.y++)
347 {
348 for(xs = ys, xm = ym; xs.x != s_lr.x; xs.x++, xm.x++)
349 {
350 res += m_mask_acc(xm)*s_acc(xs);
351 }
352 }
353 d_acc.set(res,d);
354 }
355
356 Diff2D windowShape() const
357 {
358 return m_mask_lr - m_mask_ul;
359 }
360
361private:
362 MaskIterator m_mask_ul;
363 MaskIterator m_mask_lr;
364 MaskAccessor m_mask_acc;
365};
366
367/********************************************************/
368/* */
369/* Cross correlation of mask to image */
370/* */
371/********************************************************/
372
373/** \brief This function performes a (slow) cross-correlation
374
375 This function performes a (slow) cross-correlation using the window function environment
376 and comparison of the mask with the underlying image part for each pixel. This may
377 however be faster for very few comparisons.
378
379 The input pixel type <tt>T1</tt> must be a \ref LinearSpace "linear space" over
380 the window functions' value_type <tt>T</tt>, i.e. addition of source values, multiplication with functions' values,
381 and NumericTraits must be defined. The mask's value_type must be an \ref AlgebraicField "algebraic field",
382 i.e. the arithmetic operations (+, -, *, /) and NumericTraits must be defined.
383
384 <b> Declarations:</b>
385
386 pass 2D array views:
387 \code
388 namespace vigra {
389 template <class T1, class S1,
390 class T2, class S2,
391 class T3, class S3>
392 void
393 crossCorrelation(MultiArrayView<2, T1, S1> const & in,
394 MultiArrayView<2, T2, S2> const & mask,
395 MultiArrayView<2, T3, S3> out);
396
397 }
398 \endcode
399
400 \deprecatedAPI{crossCorrelation}
401 pass \ref ImageIterators and \ref DataAccessors :
402 \code
403 namespace vigra {
404 template <class SrcIterator, class SrcAccessor,
405 class MaskIterator, class MaskAccessor,
406 class DestIterator, class DestAccessor>
407 void crossCorrelation(SrcIterator s_ul, SrcIterator s_lr, SrcAccessor s_acc,
408 MaskIterator m_ul, MaskIterator m_lr, MaskAccessor m_acc,
409 DestIterator d_ul, DestAccessor d_acc);
410 }
411 \endcode
412 use argument objects in conjunction with \ref ArgumentObjectFactories :
413 \code
414 namespace vigra {
415 template <class SrcIterator, class SrcAccessor,
416 class MaskIterator, class MaskAccessor,
417 class DestIterator, class DestAccessor>
418 void
419 crossCorrelation(triple<MaskIterator, MaskIterator, MaskAccessor> src,
420 triple<SrcIterator, SrcIterator, SrcAccessor> mask,
421 pair<DestIterator, DestAccessor> dest);
422 }
423 \endcode
424 \deprecatedEnd
425
426 <b> Usage:</b>
427
428 <b>\#include</b> <vigra/correlation.hxx><br/>
429 Namespace: vigra
430
431 \code
432 unsigned int m_w=51, m_h=51;
433 unsigned int w=1000, h=1000;
434 MultiArray<2, float> mask(m_w,m_h), src(w,h), dest(w,h);
435 ...
436
437 //compute (slow) cross correlation of mask and image -> dest
438 crossCorrelation(mask, src, dest);
439 \endcode
440
441 <b> Preconditions:</b>
442
443 The image must be larger than the size of the mask.
444*/
445doxygen_overloaded_function(template <...> void crossCorrelation)
446
447template <class SrcIterator, class SrcAccessor,
448 class MaskIterator, class MaskAccessor,
449 class DestIterator, class DestAccessor>
450inline void crossCorrelation(SrcIterator s_ul, SrcIterator s_lr, SrcAccessor s_acc,
451 MaskIterator m_ul, MaskIterator m_lr, MaskAccessor m_acc,
452 DestIterator d_ul, DestAccessor d_acc,
453 BorderTreatmentMode border = BORDER_TREATMENT_AVOID)
454{
455 CorrelationFunctor<MaskIterator, MaskAccessor> func(m_ul, m_lr, m_acc);
456 applyWindowFunction(s_ul, s_lr, s_acc, d_ul, d_acc, func, border);
457}
458
459template <class SrcIterator, class SrcAccessor,
460 class MaskIterator, class MaskAccessor,
461 class DestIterator, class DestAccessor>
462inline void crossCorrelation(triple<SrcIterator, SrcIterator, SrcAccessor> src,
463 triple<MaskIterator, MaskIterator, MaskAccessor> mask,
464 pair<DestIterator, DestAccessor> dest,
465 BorderTreatmentMode border = BORDER_TREATMENT_AVOID)
466{
467 crossCorrelation(src.first, src.second, src.third,
468 mask.first, mask.second, mask.third,
469 dest.first, dest.second,
470 border);
471}
472
473template <class T1, class S1,
474 class T2, class S2,
475 class T3, class S3>
476inline void crossCorrelation(MultiArrayView<2, T1, S1> const & in,
477 MultiArrayView<2, T2, S2> const & mask,
479{
480 vigra_precondition(in.shape() == out.shape(),
481 "vigra::crossCorrelation(): shape mismatch between input and output.");
482 crossCorrelation(srcImageRange(in),
483 srcImageRange(mask),
484 destImage(out));
485}
486
487template<class MaskIterator, class MaskAccessor>
488class NormalizedCorrelationFunctor
489{
490public:
491
492 NormalizedCorrelationFunctor(MaskIterator m_ul, MaskIterator m_lr, MaskAccessor m_acc)
493 : m_mask_ul(m_ul),
494 m_mask_lr(m_lr),
495 m_mask_acc(m_acc),
496 m_s11(0.0),
497 m_avg1(0.0)
498 {
499 init_s11();
500 }
501
502 NormalizedCorrelationFunctor(triple<MaskIterator,MaskIterator,MaskAccessor> mask)
503 : m_mask_ul(mask.first),
504 m_mask_lr(mask.second),
505 m_mask_acc(mask.third),
506 m_s11(0.0),
507 m_avg1(0.0)
508 {
509 init_s11();
510 }
511
512 template <class SrcIterator, class SrcAccessor, class DestIterator, class DestAccessor>
513 void operator()(SrcIterator s, SrcAccessor s_acc, DestIterator d, DestAccessor d_acc) const
514 {
515 using namespace vigra;
516
517 SrcIterator s_ul = s - windowShape()/2,
518 s_lr = s + windowShape()/2+Diff2D(1,1);
519
520 if(m_s11 == 0.0)
521 {
522 d_acc.set(0,d);
523 }
524 else
525 {
526 //find img2 mean
527 FindAverage<double> average;
528 inspectImage(srcIterRange(s_ul, s_lr, s_acc), average);
529
530 SrcIterator ys = s_ul;
531 SrcIterator xs = ys;
532
533 MaskIterator ym = m_mask_ul;
534 MaskIterator xm = ym;
535
536 double s1=0,s2=0, s12=0, s22=0;
537
538 for( ; ys.y != s_lr.y; ys.y++, ym.y++)
539 {
540 for(xs = ys, xm = ym; xs.x != s_lr.x; xs.x++, xm.x++)
541 {
542 s1 = m_mask_acc(xm);
543 s2 = s_acc(xs);
544 s12 += (s1-m_avg1)*(s2-average());
545 s22 += (s2-average())*(s2-average());
546 }
547 }
548 if(s22 == 0.0)
549 {
550 d_acc.set(0,d);
551 }
552 else
553 {
554 d_acc.set(s12/sqrt(m_s11*s22),d);
555 }
556 }
557 }
558
559 Diff2D windowShape() const
560 {
561 return m_mask_lr - m_mask_ul;
562 }
563
564private:
565 void init_s11()
566 {
567 //find mask mean
568 FindAverage<double> average;
569 inspectImage(srcIterRange(m_mask_ul, m_mask_lr, m_mask_acc), average);
570
571 MaskIterator ym = m_mask_ul;
572 MaskIterator xm = ym;
573
574 m_avg1 = average();
575
576 for( ; ym.y != m_mask_lr.y; ym.y++)
577 {
578 for(xm = ym; xm.x != m_mask_lr.x; xm.x++)
579 {
580 m_s11 += (m_mask_acc(xm)-m_avg1)*(m_mask_acc(xm)-m_avg1);
581 }
582 }
583 }
584
585 MaskIterator m_mask_ul;
586 MaskIterator m_mask_lr;
587 MaskAccessor m_mask_acc;
588
589 double m_s11;
590 double m_avg1;
591};
592
593/********************************************************/
594/* */
595/* Normalized Cross correlation of mask to image */
596/* */
597/********************************************************/
598
599/** \brief This function performes a (slow) normalized cross-correlation
600
601 This function performes a (slow) normalized cross-correlation using the window function
602 environment and comparison of the mask with the underlying image part for each pixel.
603 This may however be faster for very few comparisons.
604
605 The input pixel type <tt>T1</tt> must be a \ref LinearSpace "linear space" over
606 the window functions' value_type <tt>T</tt>, i.e. addition of source values, multiplication with functions' values,
607 and NumericTraits must be defined. The mask's value_type must be an \ref AlgebraicField "algebraic field",
608 i.e. the arithmetic operations (+, -, *, /) and NumericTraits must be defined.
609
610 <b> Declarations:</b>
611
612 pass 2D array views:
613 \code
614 namespace vigra {
615 template <class T1, class S1,
616 class T2, class S2,
617 class T3, class S3>
618 void
619 normalizedCrossCorrelation(MultiArrayView<2, T1, S1> const & in,
620 MultiArrayView<2, T2, S2> const & mask,
621 MultiArrayView<2, T3, S3> out);
622
623 }
624 \endcode
625
626 \deprecatedAPI{normalizedCrossCorrelation}
627 pass \ref ImageIterators and \ref DataAccessors :
628 \code
629 namespace vigra {
630 template <class SrcIterator, class SrcAccessor,
631 class MaskIterator, class MaskAccessor,
632 class DestIterator, class DestAccessor>
633 void normalizedCrossCorrelation(SrcIterator s_ul, SrcIterator s_lr, SrcAccessor s_acc,
634 MaskIterator m_ul, MaskIterator m_lr, MaskAccessor m_acc,
635 DestIterator d_ul, DestAccessor d_acc);
636 }
637 \endcode
638 use argument objects in conjunction with \ref ArgumentObjectFactories :
639 \code
640 namespace vigra {
641 template <class SrcIterator, class SrcAccessor,
642 class MaskIterator, class MaskAccessor,
643 class DestIterator, class DestAccessor>
644 void
645 normalizedCrossCorrelation(triple<SrcIterator, SrcIterator, SrcAccessor> src,
646 triple<MaskIterator, MaskIterator, MaskAccessor> mask,
647 pair<DestIterator, DestAccessor> dest);
648 }
649 \endcode
650 \deprecatedEnd
651
652 <b> Usage:</b>
653
654 <b>\#include</b> <vigra/correlation.hxx><br/>
655 Namespace: vigra
656
657 \code
658 unsigned int m_w=51, m_h=51;
659 unsigned int w=1000, h=1000;
660 MultiArray<2, float> mask(m_w,m_h), src(w,h), dest(w,h);
661 ...
662
663 //compute (slow) normalized cross correlation of mask and image -> dest
664 normalizedCrossCorrelation(mask, src, dest);
665 \endcode
666
667 <b> Preconditions:</b>
668
669 The image must be larger than the size of the mask.
670*/
671doxygen_overloaded_function(template <...> void normalizedCrossCorrelation)
672
673
674template <class SrcIterator, class SrcAccessor,
675 class MaskIterator, class MaskAccessor,
676 class DestIterator, class DestAccessor>
677inline void normalizedCrossCorrelation(SrcIterator s_ul, SrcIterator s_lr, SrcAccessor s_acc,
678 MaskIterator m_ul, MaskIterator m_lr, MaskAccessor m_acc,
679 DestIterator d_ul, DestAccessor d_acc,
680 BorderTreatmentMode border = BORDER_TREATMENT_AVOID)
681{
682 NormalizedCorrelationFunctor<MaskIterator, MaskAccessor> func(m_ul, m_lr, m_acc);
683 applyWindowFunction(s_ul, s_lr, s_acc, d_ul, d_acc, func, border);
684}
685
686template <class SrcIterator, class SrcAccessor,
687 class MaskIterator, class MaskAccessor,
688 class DestIterator, class DestAccessor>
689inline void normalizedCrossCorrelation(triple<SrcIterator, SrcIterator, SrcAccessor> src,
690 triple<MaskIterator, MaskIterator, MaskAccessor> mask,
691 pair<DestIterator, DestAccessor> dest,
692 BorderTreatmentMode border = BORDER_TREATMENT_AVOID)
693{
694 normalizedCrossCorrelation(src.first, src.second, src.third,
695 mask.first, mask.second, mask.third,
696 dest.first, dest.second,
697 border);
698}
699
700template <class T1, class S1,
701 class T2, class S2,
702 class T3, class S3>
704 MultiArrayView<2, T2, S2> const & mask,
706{
707 vigra_precondition(in.shape() == out.shape(),
708 "vigra::normalizedCrossCorrelation(): shape mismatch between input and output.");
709 normalizedCrossCorrelation(srcImageRange(in),
710 srcImageRange(mask),
711 destImage(out));
712}
713
714//@}
715
716} //end of namespace vigra
717
718#endif //VIGRA_CORRELATION_HXX
TinyVector< MultiArrayIndex, N > type
Definition multi_shape.hxx:272
Base class for, and view to, MultiArray.
Definition multi_array.hxx:705
MultiArrayView subarray(difference_type p, difference_type q) const
Definition multi_array.hxx:1530
const difference_type & shape() const
Definition multi_array.hxx:1650
MultiArrayShape< actual_dimension >::type difference_type
Definition multi_array.hxx:739
void meanVariance(U *mean, U *variance) const
Definition multi_array.hxx:1782
Main MultiArray class containing the memory management.
Definition multi_array.hxx:2479
view_type::difference_type difference_type
Definition multi_array.hxx:2524
Iterate over a virtual array where each element contains its coordinate.
Definition multi_iterator.hxx:89
Definition fftw3.hxx:623
int floor(FixedPoint< IntBits, FracBits > v)
rounding down.
Definition fixedpoint.hxx:667
void fastNormalizedCrossCorrelation(...)
This function performes a fast normalized cross-correlation.
SquareRootTraits< FixedPoint< IntBits, FracBits > >::SquareRootResult sqrt(FixedPoint< IntBits, FracBits > v)
square root.
Definition fixedpoint.hxx:616
void crossCorrelation(...)
This function performes a (slow) cross-correlation.
void correlateFFT(...)
Correlate an array with a kernel by means of the Fourier transform.
void inspectImage(...)
Apply read-only functor to every pixel in the image.
void fastCrossCorrelation(...)
This function performes a fast cross-correlation.
void applyWindowFunction(...)
Apply a window function to each pixels of a given image.
NumericTraits< V >::Promote prod(TinyVectorBase< V, SIZE, D1, D2 > const &l)
product of the vector's elements
Definition tinyvector.hxx:2097
void normalizedCrossCorrelation(...)
This function performes a (slow) normalized cross-correlation.
void initMultiArrayBorder(...)
Write values to the specified border values in the array.

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de)
Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany

html generated using doxygen and Python
vigra 1.12.1 (Thu Feb 27 2025)