vil_abs_shuffle_distance.hxx
Go to the documentation of this file.
1 #ifndef vil_abs_shuffle_distance_hxx_
2 #define vil_abs_shuffle_distance_hxx_
3 //:
4 // \file
5 // \brief Compute shuffle distance between two images
6 // \author Tim Cootes
7 
9 #include <cassert>
10 #ifdef _MSC_VER
11 # include <vcl_msvc_warnings.h>
12 #endif
13 
14 //: Computes shuffle distance between image1 and image2
15 // For each pixel in image1 it finds the pixel in image2 with
16 // the closest value in an offset area defined by the element.
17 // Returns mean over all pixels of this minimum value.
18 // \relatesalso vil_image_view
19 // \relatesalso vil_structuring_element
20 template <class T1, class T2>
22  const vil_image_view<T2>& image2,
23  const vil_structuring_element& element,
24  bool include_borders)
25 {
26  unsigned ni = image1.ni();
27  unsigned nj = image1.nj();
28  assert(image1.nplanes()==1);
29  assert(image2.nplanes()==1);
30  assert(image2.ni()==ni);
31  assert(image2.nj()==nj);
32 
33  std::ptrdiff_t istep1 = image1.istep(), jstep1 = image1.jstep(),
34  istep2 = image2.istep(), jstep2 = image2.jstep();
35 
36  const T1* image1_row0 = image1.top_left_ptr();
37  const T2* image2_row0 = image2.top_left_ptr();
38 
39  std::vector<std::ptrdiff_t> offset;
40  vil_compute_offsets(offset,element,istep2,jstep2);
41 
42  // Define box in which all element will be valid
43  int ilo = -element.min_i();
44  int ihi = ni-1-element.max_i();
45  int jlo = -element.min_j();
46  int jhi = nj-1-element.max_j();
47 
48  double sum=0.0;
49 
50  if (include_borders)
51  {
52  // Deal with left edge
53  for (int i=0;i<ilo;++i)
54  for (unsigned int j=0;j<nj;++j)
55  sum+=vil_abs_shuffle_distance(image1(i,j),image2,0,element,i,j);
56  // Deal with right edge
57  for (unsigned int i=ihi+1;i<ni;++i)
58  for (unsigned int j=0;j<nj;++j)
59  sum+=vil_abs_shuffle_distance(image1(i,j),image2,0,element,i,j);
60 
61  // Deal with bottom edge
62  for (int i=ilo;i<=ihi;++i)
63  for (int j=0;j<jlo;++j)
64  sum+=vil_abs_shuffle_distance(image1(i,j),image2,0,element,i,j);
65  // Deal with top edge
66  for (int i=ilo;i<=ihi;++i)
67  for (unsigned int j=jhi+1;j<nj;++j)
68  sum+=vil_abs_shuffle_distance(image1(i,j),image2,0,element,i,j);
69  }
70 
71  for (int j=jlo;j<=jhi;++j)
72  {
73  const T1* p1 = image1_row0 + j*jstep1 + ilo*istep1;
74  const T2* p2 = image2_row0 + j*jstep2 + ilo*istep2;
75 
76  for (int i=ilo;i<=ihi;++i,p1+=istep1,p2+=istep2)
77  sum += vil_abs_shuffle_distance(*p1,p2,&offset[0],offset.size());
78  }
79 
80  int np = ni*nj;
81  if (!include_borders) np = (1+ihi-ilo)*(1+jhi-jlo);
82 
83  return sum/np;
84 }
85 
86 #undef VIL_ABS_SHUFFLE_DISTANCE_INSTANTIATE
87 #define VIL_ABS_SHUFFLE_DISTANCE_INSTANTIATE( T1, T2 ) \
88 template double vil_abs_shuffle_distance(const vil_image_view< T1 >& image1, \
89  const vil_image_view< T2 >& image2, \
90  const vil_structuring_element& element, \
91  bool include_borders)
92 
93 #endif // vil_abs_shuffle_distance_hxx_
int max_i() const
Elements in box bounded by [min_i(),max_i()][min_j(),max_j()].
Structuring element for morphology represented as a list of non-zero pixels.
Concrete view of image data of type T held in memory.
Definition: vil_fwd.h:13
int max_j() const
Elements in box bounded by [min_i(),max_i()][min_j(),max_j()].
double vil_abs_shuffle_distance(T1 v0, const vil_image_view< T2 > &image, unsigned plane, const vil_structuring_element &element, int i0, int j0)
Return min difference of pixels under structuring element centred at (i0,j0).
std::ptrdiff_t jstep() const
Add this to your pixel pointer to get next j pixel.
unsigned ni() const
Width.
unsigned nj() const
Height.
void vil_compute_offsets(std::vector< std::ptrdiff_t > &offset, const vil_structuring_element &element, std::ptrdiff_t istep, std::ptrdiff_t jstep)
Generate a list of offsets for use on image with istep,jstep.
Compute shuffle distance between two images.
int min_j() const
Elements in box bounded by [min_i(),max_i()][min_j(),max_j()].
T * top_left_ptr()
Pointer to the first (top left in plane 0) pixel.
unsigned nplanes() const
Number of planes.
int min_i() const
Elements in box bounded by [min_i(),max_i()][min_j(),max_j()].
std::ptrdiff_t istep() const
Add this to your pixel pointer to get next i pixel.