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

correlation.hxx VIGRA

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 
49 namespace 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  */
115 
116 template <class T1, class S1,
117 class T2, class S2,
118 class T3, class S3,
119 unsigned int N>
120 inline void fastCrossCorrelation(MultiArrayView<N, T1, S1> const & in,
121  MultiArrayView<N, T2, S2> const & mask,
122  MultiArrayView<N, T3, S3> out,
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 
137 namespace detail {
138 
139 template<class T1, class S1>
140 inline 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 
147 template<class T1, class S1>
148 inline double integralMultiArrayWindowMean(MultiArrayView<2, T1, S1> const & in,
149  typename MultiArrayView<2, T1, S1>::difference_type const & ul,
150  typename MultiArrayView<2, T1, S1>::difference_type const & lr)
151 {
152  return in[lr] - in(lr[0],ul[1]) - in(ul[0],lr[1]) + in[ul];
153 }
154 
155 template<class T1, class S1>
156 inline double integralMultiArrayWindowMean(MultiArrayView<3, T1, S1> const & in,
157  typename MultiArrayView<3, T1, S1>::difference_type const & ul,
158  typename MultiArrayView<3, T1, S1>::difference_type const & lr)
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 */
222 
223 template <class T1, class S1,
224  class T2, class S2,
225  class T3, class S3,
226  unsigned int N>
227 inline void fastNormalizedCrossCorrelation(MultiArrayView<N, T1, S1> const & in,
228  MultiArrayView<N, T2, S2> const & mask,
229  MultiArrayView<N, T3, S3> out,
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 
278  typename MultiArray<N, double>::difference_type zero_diff;
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 
308 template<class MaskIterator, class MaskAccessor>
309 class CorrelationFunctor
310 {
311 public:
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 
361 private:
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 */
446 
447 template <class SrcIterator, class SrcAccessor,
448  class MaskIterator, class MaskAccessor,
449  class DestIterator, class DestAccessor>
450 inline 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 
459 template <class SrcIterator, class SrcAccessor,
460  class MaskIterator, class MaskAccessor,
461  class DestIterator, class DestAccessor>
462 inline 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 
473 template <class T1, class S1,
474  class T2, class S2,
475  class T3, class S3>
476 inline 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 
487 template<class MaskIterator, class MaskAccessor>
488 class NormalizedCorrelationFunctor
489 {
490 public:
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 
564 private:
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 */
672 
673 
674 template <class SrcIterator, class SrcAccessor,
675  class MaskIterator, class MaskAccessor,
676  class DestIterator, class DestAccessor>
677 inline 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 
686 template <class SrcIterator, class SrcAccessor,
687  class MaskIterator, class MaskAccessor,
688  class DestIterator, class DestAccessor>
689 inline 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 
700 template <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
void fastNormalizedCrossCorrelation(...)
This function performes a fast normalized cross-correlation.
void fastCrossCorrelation(...)
This function performes a fast cross-correlation.
void initMultiArrayBorder(...)
Write values to the specified border values in the array.
const difference_type & shape() const
Definition: multi_array.hxx:1648
Two dimensional difference vector.
Definition: diff2d.hxx:185
Find the average pixel value in an image or ROI.
Definition: inspectimage.hxx:1248
NumericTraits< V >::Promote prod(TinyVectorBase< V, SIZE, D1, D2 > const &l)
product of the vector's elements
Definition: tinyvector.hxx:2097
doxygen_overloaded_function(template<...> void separableConvolveBlockwise) template< unsigned int N
Separated convolution on ChunkedArrays.
void crossCorrelation(...)
This function performes a (slow) cross-correlation.
void correlateFFT(...)
Correlate an array with a kernel by means of the Fourier transform.
Base class for, and view to, vigra::MultiArray.
Definition: multi_array.hxx:704
int floor(FixedPoint< IntBits, FracBits > v)
rounding down.
Definition: fixedpoint.hxx:667
void normalizedCrossCorrelation(...)
This function performes a (slow) normalized cross-correlation.
void inspectImage(...)
Apply read-only functor to every pixel in the image.
SquareRootTraits< FixedPoint< IntBits, FracBits > >::SquareRootResult sqrt(FixedPoint< IntBits, FracBits > v)
square root.
Definition: fixedpoint.hxx:616
void applyWindowFunction(...)
Apply a window function to each pixels of a given image.

© 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.11.1 (Fri May 19 2017)