core/vil/algo/vil_abs_shuffle_distance.txx
Go to the documentation of this file.
00001 #ifndef vil_abs_shuffle_distance_txx_
00002 #define vil_abs_shuffle_distance_txx_
00003 //:
00004 // \file
00005 // \brief Compute shuffle distance between two images
00006 // \author Tim Cootes
00007 
00008 #include "vil_abs_shuffle_distance.h"
00009 #include <vcl_cassert.h>
00010 
00011 //: Computes shuffle distance between image1 and image2
00012 // For each pixel in image1 it finds the pixel in image2 with
00013 // the closest value in an offset area defined by the element.
00014 // Returns mean over all pixels of this minimum value.
00015 // \relatesalso vil_image_view
00016 // \relatesalso vil_structuring_element
00017 template <class T1, class T2>
00018 double vil_abs_shuffle_distance(const vil_image_view<T1>& image1,
00019                                 const vil_image_view<T2>& image2,
00020                                 const vil_structuring_element& element,
00021                                 bool include_borders)
00022 {
00023   unsigned ni = image1.ni();
00024   unsigned nj = image1.nj();
00025   assert(image1.nplanes()==1);
00026   assert(image2.nplanes()==1);
00027   assert(image2.ni()==ni);
00028   assert(image2.nj()==nj);
00029 
00030   vcl_ptrdiff_t istep1 = image1.istep(),  jstep1 = image1.jstep(),
00031                 istep2 = image2.istep(), jstep2 = image2.jstep();
00032 
00033   const T1* image1_row0 = image1.top_left_ptr();
00034   const T2* image2_row0 = image2.top_left_ptr();
00035 
00036   vcl_vector<vcl_ptrdiff_t> offset;
00037   vil_compute_offsets(offset,element,istep2,jstep2);
00038 
00039   // Define box in which all element will be valid
00040   int ilo = -element.min_i();
00041   int ihi = ni-1-element.max_i();
00042   int jlo = -element.min_j();
00043   int jhi = nj-1-element.max_j();
00044 
00045   double sum=0.0;
00046 
00047   if (include_borders)
00048   {
00049     // Deal with left edge
00050     for (int i=0;i<ilo;++i)
00051       for (unsigned int j=0;j<nj;++j)
00052         sum+=vil_abs_shuffle_distance(image1(i,j),image2,0,element,i,j);
00053     // Deal with right edge
00054     for (unsigned int i=ihi+1;i<ni;++i)
00055       for (unsigned int j=0;j<nj;++j)
00056         sum+=vil_abs_shuffle_distance(image1(i,j),image2,0,element,i,j);
00057 
00058     // Deal with bottom edge
00059     for (int i=ilo;i<=ihi;++i)
00060       for (int j=0;j<jlo;++j)
00061         sum+=vil_abs_shuffle_distance(image1(i,j),image2,0,element,i,j);
00062     // Deal with top edge
00063     for (int i=ilo;i<=ihi;++i)
00064       for (unsigned int j=jhi+1;j<nj;++j)
00065         sum+=vil_abs_shuffle_distance(image1(i,j),image2,0,element,i,j);
00066   }
00067 
00068   for (int j=jlo;j<=jhi;++j)
00069   {
00070     const T1* p1 = image1_row0 + j*jstep1 + ilo*istep1;
00071     const T2* p2 = image2_row0 + j*jstep2 + ilo*istep2;
00072 
00073     for (int i=ilo;i<=ihi;++i,p1+=istep1,p2+=istep2)
00074       sum += vil_abs_shuffle_distance(*p1,p2,&offset[0],offset.size());
00075   }
00076 
00077   int np = ni*nj;
00078   if (!include_borders) np = (1+ihi-ilo)*(1+jhi-jlo);
00079 
00080   return sum/np;
00081 }
00082 
00083 #undef VIL_ABS_SHUFFLE_DISTANCE_INSTANTIATE
00084 #define VIL_ABS_SHUFFLE_DISTANCE_INSTANTIATE( T1, T2 ) \
00085 template double vil_abs_shuffle_distance(const vil_image_view< T1 >& image1, \
00086                                          const vil_image_view< T2 >& image2, \
00087                                          const vil_structuring_element& element, \
00088                                          bool include_borders)
00089 
00090 #endif // vil_abs_shuffle_distance_txx_