Go to the documentation of this file.00001
00002 #ifndef vil_find_peaks_h_
00003 #define vil_find_peaks_h_
00004
00005
00006
00007
00008
00009 #include <vil/vil_image_view.h>
00010 #include <vcl_vector.h>
00011
00012
00013
00014 template <class T>
00015 inline bool vil_is_peak_3x3(const T* im, vcl_ptrdiff_t i_step, vcl_ptrdiff_t j_step)
00016 {
00017 T v = *im;
00018 return v > im[i_step]
00019 && v > im[-i_step]
00020 && v > im[j_step]
00021 && v > im[-j_step]
00022 && v > im[i_step+j_step]
00023 && v > im[i_step-j_step]
00024 && v > im[j_step-i_step]
00025 && v > im[-i_step-j_step];
00026 }
00027
00028
00029
00030
00031
00032
00033 template <class T>
00034 inline void vil_find_peaks_3x3(vcl_vector<unsigned>& pi,
00035 vcl_vector<unsigned>& pj,
00036 const vil_image_view<T>& image,
00037 const T& min_thresh,
00038 bool clear_list=true)
00039 {
00040 if (clear_list) {
00041 pi.resize(0);
00042 pj.resize(0);
00043 }
00044 const unsigned ni1=image.ni()-1,nj1=image.nj()-1;
00045 const vcl_ptrdiff_t istep = image.istep(),jstep=image.jstep();
00046 const T* row = image.top_left_ptr()+istep+jstep;
00047 for (unsigned j=1;j<nj1;++j,row+=jstep)
00048 {
00049 const T* pixel = row;
00050 for (unsigned i=1;i<ni1;++i,pixel+=istep)
00051 if (*pixel>=min_thresh && vil_is_peak_3x3(pixel,istep,jstep))
00052 { pi.push_back(i); pj.push_back(j); }
00053 }
00054 }
00055
00056
00057
00058
00059
00060
00061 template<class T>
00062 bool vil_interpolate_peak(const T* pixel,
00063 vcl_ptrdiff_t istep, vcl_ptrdiff_t jstep,
00064 double& dx, double& dy, double& val)
00065 {
00066 dx=dy=0;
00067
00068
00069
00070
00071
00072
00073
00074
00075 const T& p11 = *pixel;
00076 const T& p01 = *(pixel-istep);
00077 const T& p21 = *(pixel+istep);
00078 const T& p10 = *(pixel-jstep);
00079 const T& p12 = *(pixel+jstep);
00080 const T& p00 = *(&p10-istep);
00081 const T& p20 = *(&p10+istep);
00082 const T& p02 = *(&p12-istep);
00083 const T& p22 = *(&p12+istep);
00084
00085
00086
00087
00088
00089 double Ix =(-p00-p01-p02 +p20+p21+p22)/6.0;
00090
00091
00092
00093 double Iy =(-p00-p10-p20 +p02+p12+p22)/6.0;
00094
00095
00096
00097 double Ixx = ((p00+p01+p02 +p20+p21+p22)-2.0*(p10+p11+p12))/3.0;
00098
00099
00100
00101 double Ixy = (p00+p22 -p02-p20)/4.0;
00102
00103
00104
00105 double Iyy = ((p00+p10+p20 +p02+p12+p22)-2.0*(p01+p11+p21))/3.0;
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 double det = Ixx*Iyy - Ixy*Ixy;
00118
00119 if (det<=0)
00120 return false;
00121
00122 dx = (Iy*Ixy - Ix*Iyy) / det;
00123 dy = (Ix*Ixy - Iy*Ixx) / det;
00124
00125 if (dx > 1.0 || dx < -1.0 || dy > 1.0 || dy < -1.0)
00126 return false;
00127
00128 double Io =(p00+p01+p02 +p10+p11+p12 +p20+p21+p22)/9.0;
00129
00130 val = Io + (Ix + 0.5*Ixx*dx + Ixy*dy)*dx + (Iy + 0.5*Iyy*dy)*dy;
00131
00132 return true;
00133 }
00134
00135
00136
00137
00138
00139
00140
00141
00142 template <class T>
00143 inline void vil_find_peaks_3x3_subpixel(vcl_vector<double>& px,
00144 vcl_vector<double>& py,
00145 vcl_vector<double>& val,
00146 const vil_image_view<T>& image,
00147 const T& min_thresh,
00148 bool clear_list=true)
00149 {
00150 if (clear_list) {
00151 px.resize(0);
00152 py.resize(0);
00153 val.resize(0);
00154 }
00155 const unsigned ni1=image.ni()-1,nj1=image.nj()-1;
00156 const vcl_ptrdiff_t istep = image.istep(),jstep=image.jstep();
00157 const T* row = image.top_left_ptr()+istep+jstep;
00158 double dx,dy,v;
00159 for (unsigned j=1;j<nj1;++j,row+=jstep)
00160 {
00161 const T* pixel = row;
00162 for (unsigned i=1;i<ni1;++i,pixel+=istep)
00163 if (*pixel>=min_thresh && vil_is_peak_3x3(pixel,istep,jstep) &&
00164 vil_interpolate_peak(pixel,istep,jstep,dx,dy,v))
00165 {
00166 px.push_back(i+dx);
00167 py.push_back(j+dy);
00168 val.push_back(v);
00169 }
00170 }
00171 }
00172
00173 #endif // vil_find_peaks_h_