vil_orientations.cxx
Go to the documentation of this file.
1 #include <cmath>
2 #include "vil_orientations.h"
3 //:
4 // \file
5 // \brief Functions to compute orientations and gradient magnitude
6 // \author Tim Cootes
7 
8 #include <cassert>
9 #ifdef _MSC_VER
10 # include <vcl_msvc_warnings.h>
11 #endif
12 
13 //: Compute orientation (in radians) and gradient magnitude at each pixel
15  const vil_image_view<float>& grad_j,
16  vil_image_view<float>& orient_im,
17  vil_image_view<float>& grad_mag)
18 {
19  assert(grad_i.nplanes()==1 && grad_j.nplanes()==1);
20  unsigned ni = grad_i.ni(), nj = grad_j.nj();
21  assert(grad_j.ni()==ni && grad_j.nj()==nj);
22  orient_im.set_size(ni,nj,1);
23  grad_mag.set_size(ni,nj,1);
24 
25  const std::ptrdiff_t gi_istep = grad_i.istep(), gi_jstep = grad_i.jstep();
26  const std::ptrdiff_t gj_istep = grad_j.istep(), gj_jstep = grad_j.jstep();
27  const std::ptrdiff_t o_istep = orient_im.istep(), o_jstep = orient_im.jstep();
28  const std::ptrdiff_t gm_istep = grad_mag.istep(), gm_jstep = grad_mag.jstep();
29 
30  const float * gi_row = &grad_i(0,0);
31  const float * gj_row = &grad_j(0,0);
32  float * o_row = &orient_im(0,0);
33  float * gm_row = &grad_mag(0,0);
34 
35  for (unsigned j=0;j<nj;++j, gi_row+=gi_jstep, gj_row+=gj_jstep,
36  o_row+=o_jstep, gm_row+=gm_jstep)
37  {
38  const float* pgi = gi_row;
39  const float* pgj = gj_row;
40  float *po = o_row;
41  float *pgm = gm_row;
42  for (unsigned i=0;i<ni;++i, pgi+=gi_istep, pgj+=gj_istep,
43  po+=o_istep, pgm+=gm_istep)
44  {
45  *po = std::atan2(*pgj,*pgi);
46  *pgm = std::sqrt(pgi[0]*pgi[0] + pgj[0]*pgj[0]);
47  }
48  }
49 }
50 
51 //: Compute discrete orientation and gradient magnitude at each pixel
52 // Computes orientation at each pixel and scales to range [0,n_orientations-1].
53 // Orientation of i corresponds to angles in range [(i-0.5)dA,(i+0.5)dA]
54 // where dA=2*pi/n_orientations.
55 // Images assumed to be single plane
57  const vil_image_view<float>& grad_j,
58  vil_image_view<vxl_byte>& orient_im,
59  vil_image_view<float>& grad_mag,
60  unsigned n_orientations)
61 {
62  assert(grad_i.nplanes()==1 && grad_j.nplanes()==1);
63  assert(n_orientations<=256);
64  unsigned ni = grad_i.ni(), nj = grad_j.nj();
65  assert(grad_j.ni()==ni && grad_j.nj()==nj);
66  orient_im.set_size(ni,nj,1);
67  grad_mag.set_size(ni,nj,1);
68 
69  const std::ptrdiff_t gi_istep = grad_i.istep(), gi_jstep = grad_i.jstep();
70  const std::ptrdiff_t gj_istep = grad_j.istep(), gj_jstep = grad_j.jstep();
71  const std::ptrdiff_t o_istep = orient_im.istep(), o_jstep = orient_im.jstep();
72  const std::ptrdiff_t gm_istep = grad_mag.istep(), gm_jstep = grad_mag.jstep();
73 
74  const float * gi_row = &grad_i(0,0);
75  const float * gj_row = &grad_j(0,0);
76  vxl_byte * o_row = &orient_im(0,0);
77  float * gm_row = &grad_mag(0,0);
78 
79  float scale = (2*n_orientations-1)/(6.28319f);
80 
81  for (unsigned j=0;j<nj;++j, gi_row+=gi_jstep, gj_row+=gj_jstep,
82  o_row+=o_jstep, gm_row+=gm_jstep)
83  {
84  const float* pgi = gi_row;
85  const float* pgj = gj_row;
86  vxl_byte *po = o_row;
87  float *pgm = gm_row;
88  for (unsigned i=0;i<ni;++i, pgi+=gi_istep, pgj+=gj_istep,
89  po+=o_istep, pgm+=gm_istep)
90  {
91  // In order to ensure bins are centred at k*2pi/n_orientation points,
92  // compute position in twice angle range, then adjust.
93  int A2 = int((std::atan2(*pgj,*pgi)+3.14159)*scale);
94  *po = vxl_byte(((A2+1)/2)%n_orientations);
95  *pgm = std::sqrt(pgi[0]*pgi[0] + pgj[0]*pgj[0]);
96  }
97  }
98 }
99 
100 //: Compute discrete orientation and gradient magnitude at edge pixels
101 // Computes orientation at each pixel and scales to range [0,n_orientations].
102 // If gradient magnitude is less than grad_threshold, then orientation
103 // of zero is set, meaning undefined orientation.
104 //
105 // Orientation of i>0 corresponds to angles in range [(i-1.5)dA,(i-0.5)dA]
106 // where dA=2*pi/n_orientations.
107 //
108 // Images assumed to be single plane
110  const vil_image_view<float>& grad_j,
111  vil_image_view<vxl_byte>& orient_im,
112  vil_image_view<float>& grad_mag,
113  float grad_threshold,
114  unsigned n_orientations)
115 {
116  assert(grad_i.nplanes()==1 && grad_j.nplanes()==1);
117  assert(n_orientations<=256);
118  unsigned ni = grad_i.ni(), nj = grad_j.nj();
119  assert(grad_j.ni()==ni && grad_j.nj()==nj);
120  orient_im.set_size(ni,nj,1);
121  grad_mag.set_size(ni,nj,1);
122 
123  const std::ptrdiff_t gi_istep = grad_i.istep(), gi_jstep = grad_i.jstep();
124  const std::ptrdiff_t gj_istep = grad_j.istep(), gj_jstep = grad_j.jstep();
125  const std::ptrdiff_t o_istep = orient_im.istep(), o_jstep = orient_im.jstep();
126  const std::ptrdiff_t gm_istep = grad_mag.istep(), gm_jstep = grad_mag.jstep();
127 
128  const float * gi_row = &grad_i(0,0);
129  const float * gj_row = &grad_j(0,0);
130  vxl_byte * o_row = &orient_im(0,0);
131  float * gm_row = &grad_mag(0,0);
132 
133  float scale = (2*n_orientations-1)/(6.28319f);
134 
135  for (unsigned j=0;j<nj;++j, gi_row+=gi_jstep, gj_row+=gj_jstep,
136  o_row+=o_jstep, gm_row+=gm_jstep)
137  {
138  const float* pgi = gi_row;
139  const float* pgj = gj_row;
140  vxl_byte *po = o_row;
141  float *pgm = gm_row;
142  for (unsigned i=0;i<ni;++i, pgi+=gi_istep, pgj+=gj_istep,
143  po+=o_istep, pgm+=gm_istep)
144  {
145  *pgm = std::sqrt(pgi[0]*pgi[0] + pgj[0]*pgj[0]);
146  if (*pgm<grad_threshold) *po=0;
147  else
148  {
149  // In order to ensure bins are centred at k*2pi/n_orientation points,
150  // compute position in twice angle range, then adjust.
151  int A2 = int((std::atan2(*pgj,*pgi)+3.14159)*scale);
152  *po = vxl_byte(1+((A2+1)/2)%n_orientations);
153  }
154  }
155  }
156 }
Concrete view of image data of type T held in memory.
Definition: vil_fwd.h:13
void set_size(unsigned ni, unsigned nj) override
resize current planes to ni x nj.
void vil_orientations_at_edges(const vil_image_view< float > &grad_i, const vil_image_view< float > &grad_j, vil_image_view< vxl_byte > &orient_im, vil_image_view< float > &grad_mag, float grad_threshold, unsigned n_orientations=255)
Compute discrete orientation and gradient magnitude at edge pixels.
Functions to compute orientations and gradient magnitude.
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_orientations(const vil_image_view< float > &grad_i, const vil_image_view< float > &grad_j, vil_image_view< float > &orient_im, vil_image_view< float > &grad_mag)
Compute orientation (in radians) and gradient magnitude at each pixel.
unsigned nplanes() const
Number of planes.
std::ptrdiff_t istep() const
Add this to your pixel pointer to get next i pixel.