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

correlation.hxx VIGRA

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

© 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.10.0 (Thu Jan 8 2015)