00001
00002 #ifndef vil1_ncc_txx_
00003 #define vil1_ncc_txx_
00004
00005
00006
00007
00008 #include "vil1_ncc.h"
00009 #include <vcl_cassert.h>
00010 #include <vcl_cmath.h>
00011
00012 template <class I1, class I2, class O>
00013 O vil1_ncc(vil1_memory_image_of<I1> const &a,
00014 vil1_memory_image_of<I2> const &b,
00015 O *)
00016 {
00017 assert(a.width() == b.width());
00018 assert(a.height() == b.height());
00019 unsigned w = a.width();
00020 unsigned h = a.height();
00021
00022
00023 O acc(0);
00024 O mean1(0);
00025 O mean2(0);
00026 O var1(0);
00027 O var2(0);
00028
00029 for (unsigned j=0; j<h; ++j) {
00030
00031 I1 const *ra = a[j];
00032 I2 const *rb = b[j];
00033
00034
00035 for (unsigned i=0; i<w; ++i) {
00036 mean1 += O(ra[i]);
00037 mean2 += O(rb[i]);
00038 }
00039 }
00040 mean1 /= O(w*h);
00041 mean2 /= O(w*h);
00042
00043 for (unsigned j=0; j<h; ++j) {
00044
00045 I1 const *ra = a[j];
00046 I2 const *rb = b[j];
00047
00048
00049 for (unsigned i=0; i<w; ++i) {
00050 O tmp1 = O(ra[i]) - mean1;
00051 O tmp2 = O(rb[i]) - mean2;
00052 var1 += tmp1 * tmp1;
00053 var2 += tmp2 * tmp2;
00054 acc += tmp1 * tmp2;
00055 }
00056 }
00057 var1 /= O(w*h);
00058 var2 /= O(w*h);
00059
00060
00061 return acc / (vcl_sqrt(w*h*var1) * vcl_sqrt(w*h*var2));
00062 }
00063
00064
00065
00066 #if defined(VCL_GCC_295)
00067
00068
00069 template <class T, class A>
00070 inline A vil1_ncc_cond(T const &x, A *) { return A(x); }
00071
00072 VCL_DEFINE_SPECIALIZATION
00073 inline double vil1_ncc_cond(unsigned char const &x, double *) { return (double(x)-127.5)/127.5; }
00074 #else
00075 # define vil1_ncc_cond(x, ptr_to_A) (x) //(typeof *ptr_to_A)(x)
00076 #endif
00077
00078 template <class T1, class T2, class A>
00079 A vil1_ncc(T1 const * const *I1, int x1, int y1,
00080 T2 const * const *I2, int x2, int y2,
00081 int size, A *)
00082 {
00083 unsigned N = 0;
00084 A S1=0, S2 = 0;
00085 A S11=0, S12=0, S22=0;
00086
00087 for (int j=-size; j<=size; ++j) {
00088 T1 const *row1 = I1[y1+j];
00089 T2 const *row2 = I2[y2+j];
00090 for (int i=-size; i<=size; ++i) {
00091 A im1 = vil1_ncc_cond(row1[x1+i], (A*)0);
00092 A im2 = vil1_ncc_cond(row2[x2+i], (A*)0);
00093 N += 1;
00094 S1 += im1; S2 += im2;
00095 S11 += im1*im1; S12 += im1*im2; S22 += im2*im2;
00096 }
00097 }
00098
00099 return (N*S12 - S1*S2) / vcl_sqrt((N*S11 - S1*S1) * (N*S22 - S2*S2));
00100 }
00101
00102
00103
00104 #define VIL1_NCC_INSTANTIATE(I1, I2, O) \
00105 template O vil1_ncc(vil1_memory_image_of<I1 > const &, \
00106 vil1_memory_image_of<I2 > const &, \
00107 O *); \
00108 template O vil1_ncc(I1 const * const *, int, int, \
00109 I2 const * const *, int, int, \
00110 int, O *)
00111
00112 #endif // vil1_ncc_txx_