00001
00002 #ifndef brip_subpix_convolution_h
00003 #define brip_subpix_convolution_h
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <vil/algo/vil_correlate_1d.h>
00016 #include <vil/algo/vil_correlate_2d.h>
00017 #include <vil/vil_transpose.h>
00018 #include <vgl/vgl_point_2d.h>
00019
00020
00021
00022
00023
00024
00025
00026
00027 template <class srcT, class destT, class kernelT, class accumT>
00028 inline void brip_subpix_convolve_2d(const vil_image_view<srcT>& src_im,
00029 vil_image_view<destT>& dest_im,
00030 kernelT kernel, accumT ac,
00031 int N)
00032 {
00033 int two_pow_N = 1 << N;
00034
00035
00036 int src_ni = 1+src_im.ni()-kernel.ni(); assert(src_ni >= 0);
00037 int src_nj = 1+src_im.nj()-kernel.nj(); assert(src_nj >= 0);
00038
00039
00040 int dest_ni = two_pow_N*src_im.ni(); assert(dest_ni >= 0);
00041 int dest_nj = two_pow_N*src_im.nj(); assert(dest_nj >= 0);
00042
00043
00044 dest_im.set_size(dest_ni,dest_nj,1);
00045 dest_im.fill(0);
00046
00047
00048 vcl_ptrdiff_t s_istep = src_im.istep(), s_jstep = src_im.jstep();
00049 vcl_ptrdiff_t s_pstep = src_im.planestep();
00050 vcl_ptrdiff_t d_istep = dest_im.istep(), d_jstep = dest_im.jstep();
00051
00052
00053
00054
00055 for (int shift_i=0; shift_i<two_pow_N; shift_i++){
00056 for (int shift_j=0; shift_j<two_pow_N; shift_j++){
00057
00058 kernel.recompute_kernel(double(shift_i)/two_pow_N, double(shift_j)/two_pow_N);
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 int khs = (kernel.ni()-1)/2;
00073 const srcT* src_row = src_im.top_left_ptr();
00074
00075
00076 destT* dest_row = dest_im.top_left_ptr()+(shift_i+two_pow_N*khs)+(shift_j+two_pow_N*khs)*d_jstep;
00077
00078 for (int j=0;j<src_nj;++j,src_row+=s_jstep,dest_row+=two_pow_N*d_jstep)
00079 {
00080 const srcT* sp = src_row;
00081 destT* dp = dest_row;
00082 for (int i=0;i<src_ni;++i, sp += s_istep, dp += two_pow_N*d_istep){
00083
00084 *dp = (destT)vil_correlate_2d_at_pt(sp, s_istep, s_jstep, s_pstep, kernel, ac);
00085 }
00086 }
00087 }
00088 }
00089 }
00090
00091
00092 template <class srcT, class kernelT, class accumT>
00093 inline void brip_subpix_convolve_2d(const vil_image_view<srcT>& src_im,
00094 const vcl_vector<vgl_point_2d<accumT> >& pts,
00095 vcl_vector<accumT>& res,
00096 kernelT kernel, accumT ac,
00097 int )
00098 {
00099 res.resize(pts.size());
00100 int khs = (kernel.ni()-1)/2;
00101
00102
00103 vcl_ptrdiff_t s_istep = src_im.istep(), s_jstep = src_im.jstep(), s_pstep = src_im.planestep();
00104
00105 for (unsigned i=0; i<pts.size(); i++)
00106 {
00107
00108 int x = (int) vcl_floor(pts[i].x());
00109 int y = (int) vcl_floor(pts[i].y());
00110
00111
00112
00113 if (x<khs || y<khs){
00114 res[i]=0;
00115 continue;
00116 }
00117
00118
00119 double dx = pts[i].x() - x;
00120 double dy = pts[i].y() - y;
00121
00122
00123 kernel.recompute_kernel(dx, dy);
00124
00125
00126
00127
00128
00129
00130 const srcT* sp = src_im.top_left_ptr() + (x-khs)*s_istep + (y-khs)*s_jstep;
00131
00132
00133 res[i] = (accumT)vil_correlate_2d_at_pt(sp, s_istep, s_jstep, s_pstep, kernel, ac);
00134 }
00135 }
00136
00137
00138 template <class srcT, class kernelT, class accumT>
00139 inline void brip_subpix_convolve_2d(const vil_image_view<srcT>& src_im,
00140 const vcl_vector<vgl_point_2d<accumT> >& pts,
00141 const vcl_vector<accumT>& thetas,
00142 vcl_vector<accumT>& res,
00143 kernelT kernel, accumT ac,
00144 int )
00145 {
00146 res.resize(pts.size());
00147 int khs = (kernel.ni()-1)/2;
00148
00149
00150 vcl_ptrdiff_t s_istep = src_im.istep(), s_jstep = src_im.jstep(), s_pstep = src_im.planestep();
00151
00152 for (unsigned i=0; i<pts.size(); i++)
00153 {
00154
00155 int x = (int) vcl_floor(pts[i].x());
00156 int y = (int) vcl_floor(pts[i].y());
00157
00158
00159
00160 if (x<khs || y<khs){
00161 res[i]=0;
00162 continue;
00163 }
00164
00165
00166 double dx = pts[i].x() - x;
00167 double dy = pts[i].y() - y;
00168
00169
00170 kernel.recompute_kernel(dx, dy, thetas[i]);
00171
00172
00173
00174
00175
00176
00177 const srcT* sp = src_im.top_left_ptr() + (x-khs)*s_istep + (y-khs)*s_jstep;
00178
00179
00180 res[i] = (accumT)vil_correlate_2d_at_pt(sp, s_istep, s_jstep, s_pstep, kernel, ac);
00181 }
00182 }
00183
00184
00185
00186
00187
00188
00189
00190
00191 template <class srcT, class destT, class kernelT, class accumT>
00192 inline void brip_subpix_convolve_2d_sep(const vil_image_view<srcT>& src_im,
00193 vil_image_view<destT>& dest_im,
00194 kernelT kernel, accumT ac,
00195 int N)
00196 {
00197 int two_pow_N = 1 << N;
00198
00199
00200 int src_ni = src_im.ni(); assert(src_ni >= 0);
00201 int src_nj = src_im.nj(); assert(src_nj >= 0);
00202
00203
00204 int dest_ni = two_pow_N*src_im.ni(); assert(dest_ni >= 0);
00205 int dest_nj = two_pow_N*src_im.nj(); assert(dest_nj >= 0);
00206
00207
00208 dest_im.set_size(dest_ni,dest_nj,1);
00209 dest_im.fill(0);
00210
00211
00212 vcl_ptrdiff_t s_istep = src_im.istep(), s_jstep = src_im.jstep();
00213 vcl_ptrdiff_t d_istep = dest_im.istep(), d_jstep = dest_im.jstep();
00214
00215
00216
00217
00218 for (int shift_i=0; shift_i<two_pow_N; shift_i++){
00219 for (int shift_j=0; shift_j<two_pow_N; shift_j++){
00220
00221
00222 kernel.recompute_kernel(double(shift_i)/two_pow_N, double(shift_j)/two_pow_N);
00223
00224
00225 int khs = kernel.khs;
00226
00227
00228 vil_image_view<destT> work_im;
00229 vil_correlate_1d(src_im, work_im, &kernel.K_x[khs], -khs, khs,
00230 ac, vil_convolve_no_extend, vil_convolve_no_extend);
00231
00232
00233 vil_image_view<destT> work_im2;
00234 work_im2.set_size(src_im.ni(), src_im.nj(), src_im.nplanes());
00235
00236 vil_image_view<destT> work_im_t = vil_transpose(work_im);
00237 vil_image_view<destT> work_im2_t = vil_transpose(work_im2);
00238
00239 vil_correlate_1d(work_im_t, work_im2_t,
00240 &kernel.K_y[khs], -khs, khs,
00241 ac, vil_convolve_no_extend, vil_convolve_no_extend);
00242
00243
00244 destT* src_row = work_im2.top_left_ptr();
00245
00246
00247 destT* dest_row = dest_im.top_left_ptr()+(shift_i)+(shift_j)*d_jstep;
00248
00249 for (int j=0;j<src_nj;++j, src_row+=s_jstep, dest_row+=two_pow_N*d_jstep)
00250 {
00251 const destT* sp = src_row;
00252 destT* dp = dest_row;
00253 for (int i=0;i<src_ni;++i, sp += s_istep, dp += two_pow_N*d_istep){
00254 *dp = (destT) *sp;
00255 }
00256 }
00257 }
00258 }
00259 }
00260
00261 #endif // brip_subpix_convolution_h