00001
00002 #ifndef vil_correlate_1d_h_
00003 #define vil_correlate_1d_h_
00004
00005
00006
00007
00008
00009 #include <vcl_algorithm.h>
00010 #include <vcl_cstring.h>
00011 #include <vcl_cassert.h>
00012 #include <vcl_iostream.h>
00013 #include <vil/vil_image_view.h>
00014 #include <vil/vil_image_resource.h>
00015 #include <vil/vil_property.h>
00016 #include <vil/algo/vil_convolve_1d.h>
00017
00018
00019
00020 template <class srcT, class destT, class kernelT, class accumT>
00021 inline void vil_correlate_1d(const srcT* src0, unsigned nx, vcl_ptrdiff_t s_step,
00022 destT* dest0, vcl_ptrdiff_t d_step,
00023 const kernelT* kernel,
00024 vcl_ptrdiff_t k_lo, vcl_ptrdiff_t k_hi,
00025 accumT ac,
00026 vil_convolve_boundary_option start_option,
00027 vil_convolve_boundary_option end_option)
00028 {
00029
00030 vil_convolve_edge_1d(src0,nx,s_step,dest0,d_step,kernel,-k_hi,-k_lo,-1,ac,start_option);
00031
00032 const kernelT* k_begin = kernel+k_lo;
00033 const kernelT* k_end = kernel+k_hi+1;
00034 const srcT* src = src0;
00035
00036 destT* end_dest = dest0 + d_step*(int(nx)-k_hi);
00037 for (destT* dest = dest0-d_step*k_lo;dest!=end_dest;dest+=d_step,src+=s_step)
00038 {
00039 accumT sum = 0;
00040 const srcT* s= src;
00041 for (const kernelT *k = k_begin;k!=k_end; ++k,s+=s_step) sum+= (accumT)((*k)*(*s));
00042 *dest = destT(sum);
00043 }
00044
00045
00046 vil_convolve_edge_1d(src0+(nx-1)*s_step,nx,-s_step,
00047 dest0+(nx-1)*d_step,-d_step,
00048 kernel,k_lo,k_hi,1,ac,end_option);
00049 }
00050
00051
00052
00053
00054
00055
00056
00057
00058 template <class srcT, class destT, class kernelT, class accumT>
00059 inline void vil_correlate_1d(const vil_image_view<srcT>& src_im,
00060 vil_image_view<destT>& dest_im,
00061 const kernelT* kernel,
00062 vcl_ptrdiff_t k_lo, vcl_ptrdiff_t k_hi,
00063 accumT ac,
00064 vil_convolve_boundary_option start_option,
00065 vil_convolve_boundary_option end_option)
00066 {
00067 unsigned ni = src_im.ni();
00068 unsigned nj = src_im.nj();
00069 vcl_ptrdiff_t s_istep = src_im.istep(), s_jstep = src_im.jstep();
00070
00071 dest_im.set_size(ni,nj,src_im.nplanes());
00072 vcl_ptrdiff_t d_istep = dest_im.istep(),d_jstep = dest_im.jstep();
00073
00074 for (unsigned int p=0;p<src_im.nplanes();++p)
00075 {
00076
00077 const srcT* src_row = src_im.top_left_ptr()+p*src_im.planestep();
00078 destT* dest_row = dest_im.top_left_ptr()+p*dest_im.planestep();
00079
00080
00081
00082 if (s_istep == 1)
00083 {
00084 if (d_istep == 1)
00085 for (unsigned int j=0;j<nj;++j,src_row+=s_jstep,dest_row+=d_jstep)
00086 vil_correlate_1d(src_row,ni,1, dest_row,1,
00087 kernel,k_lo,k_hi,ac,start_option,end_option);
00088 else
00089 for (unsigned int j=0;j<nj;++j,src_row+=s_jstep,dest_row+=d_jstep)
00090 vil_correlate_1d(src_row,ni,1, dest_row,d_istep,
00091 kernel,k_lo,k_hi,ac,start_option,end_option);
00092 }
00093 else
00094 {
00095 if (d_istep == 1)
00096 for (unsigned int j=0;j<nj;++j,src_row+=s_jstep,dest_row+=d_jstep)
00097 vil_correlate_1d(src_row,ni,s_istep, dest_row,1,
00098 kernel,k_lo,k_hi,ac,start_option,end_option);
00099 else
00100 for (unsigned int j=0;j<nj;++j,src_row+=s_jstep,dest_row+=d_jstep)
00101 vil_correlate_1d(src_row,ni,s_istep, dest_row,d_istep,
00102 kernel,k_lo,k_hi,ac,start_option,end_option);
00103 }
00104 }
00105 }
00106
00107 template <class destT, class kernelT, class accumT>
00108 vil_image_resource_sptr vil_correlate_1d(
00109 const vil_image_resource_sptr& src_im,
00110 const destT dt,
00111 const kernelT* kernel, vcl_ptrdiff_t k_lo, vcl_ptrdiff_t k_hi,
00112 const accumT ac,
00113 vil_convolve_boundary_option start_option,
00114 vil_convolve_boundary_option end_option);
00115
00116
00117 template <class kernelT, class accumT, class destT>
00118 class vil_correlate_1d_resource : public vil_image_resource
00119 {
00120
00121
00122 vil_correlate_1d_resource(const vil_image_resource_sptr& src,
00123 const kernelT* kernel, vcl_ptrdiff_t k_lo, vcl_ptrdiff_t k_hi,
00124 vil_convolve_boundary_option start_option,
00125 vil_convolve_boundary_option end_option) :
00126 src_(src), kernel_(kernel), klo_(k_lo), khi_(k_hi),
00127 start_option_(start_option), end_option_(end_option)
00128 {
00129
00130 assert (start_option != vil_convolve_periodic_extend ||
00131 end_option != vil_convolve_periodic_extend);
00132 }
00133
00134 friend vil_image_resource_sptr vil_correlate_1d VCL_NULL_TMPL_ARGS (
00135 const vil_image_resource_sptr& src_im, const destT dt, const kernelT* kernel,
00136 vcl_ptrdiff_t k_lo, vcl_ptrdiff_t k_hi, const accumT ac,
00137 vil_convolve_boundary_option start_option,
00138 vil_convolve_boundary_option end_option);
00139
00140 public:
00141 virtual vil_image_view_base_sptr get_copy_view(unsigned i0, unsigned ni,
00142 unsigned j0, unsigned nj) const
00143 {
00144 if (i0 + ni > src_->ni() || j0 + nj > src_->nj()) return 0;
00145 const unsigned lsrc = (unsigned)vcl_max(0,int(i0+klo_));
00146 const unsigned hsrc = vcl_min(src_->ni(),(unsigned int)(i0+ni-klo_+khi_));
00147 const unsigned lboundary = vcl_min((unsigned) -klo_, i0);
00148 assert (hsrc > lsrc);
00149 vil_image_view_base_sptr vs = src_->get_view(lsrc, hsrc-lsrc, j0, nj);
00150 vil_image_view<destT> dest(vs->ni(), vs->nj(), vs->nplanes());
00151 switch (vs->pixel_format())
00152 {
00153 #define macro( F , T ) \
00154 case F : \
00155 vil_correlate_1d(static_cast<vil_image_view<T >&>(*vs),dest, \
00156 kernel_, klo_, khi_, accumT(), start_option_, end_option_); \
00157 return new vil_image_view<destT>(vil_crop(dest, lboundary, ni, 0, nj));
00158
00159 macro(VIL_PIXEL_FORMAT_BYTE , vxl_byte )
00160 macro(VIL_PIXEL_FORMAT_SBYTE , vxl_sbyte )
00161 macro(VIL_PIXEL_FORMAT_UINT_32 , vxl_uint_32 )
00162 macro(VIL_PIXEL_FORMAT_UINT_16 , vxl_uint_16 )
00163 macro(VIL_PIXEL_FORMAT_INT_32 , vxl_int_32 )
00164 macro(VIL_PIXEL_FORMAT_INT_16 , vxl_int_16 )
00165 macro(VIL_PIXEL_FORMAT_BOOL , bool )
00166 macro(VIL_PIXEL_FORMAT_FLOAT , float )
00167 macro(VIL_PIXEL_FORMAT_DOUBLE , double )
00168
00169
00170 #undef macro
00171 default:
00172 return 0;
00173 }
00174 }
00175
00176 virtual unsigned nplanes() const { return src_->nplanes(); }
00177 virtual unsigned ni() const { return src_->ni(); }
00178 virtual unsigned nj() const { return src_->nj(); }
00179
00180 virtual enum vil_pixel_format pixel_format() const
00181 { return vil_pixel_format_of(accumT()); }
00182
00183
00184
00185 virtual bool put_view(const vil_image_view_base& , unsigned , unsigned )
00186 {
00187 vcl_cerr << "WARNING: vil_correlate_1d_resource::put_back\n"
00188 << "\tYou can't push data back into a correlate filter.\n";
00189 return false;
00190 }
00191
00192
00193 virtual bool get_property(char const* tag, void* property_value = 0) const
00194 {
00195 if (0==vcl_strcmp(tag, vil_property_read_only))
00196 return property_value ? (*static_cast<bool*>(property_value)) = true : true;
00197
00198 return src_->get_property(tag, property_value);
00199 }
00200
00201 protected:
00202 vil_image_resource_sptr src_;
00203 const kernelT* kernel_;
00204 vcl_ptrdiff_t klo_, khi_;
00205 vil_convolve_boundary_option start_option_, end_option_;
00206 };
00207
00208
00209
00210
00211
00212
00213 template <class destT, class kernelT, class accumT>
00214 vil_image_resource_sptr vil_correlate_1d(
00215 const vil_image_resource_sptr& src_im,
00216 const destT ,
00217 const kernelT* kernel, vcl_ptrdiff_t k_lo, vcl_ptrdiff_t k_hi,
00218 const accumT,
00219 vil_convolve_boundary_option start_option,
00220 vil_convolve_boundary_option end_option)
00221 {
00222 return new vil_correlate_1d_resource<kernelT, accumT, destT>(src_im, kernel, k_lo, k_hi, start_option, end_option);
00223 }
00224
00225 #endif // vil_correlate_1d_h_