2 #ifndef vil_convolve_1d_h_ 3 #define vil_convolve_1d_h_ 21 # include <vcl_msvc_warnings.h> 95 template <
class srcT,
class destT,
class kernelT,
class accumT>
97 destT* dest, std::ptrdiff_t d_step,
98 const kernelT* kernel,
99 std::ptrdiff_t k_lo, std::ptrdiff_t k_hi,
100 std::ptrdiff_t kstep, accumT,
109 for (std::ptrdiff_t i=-k_hi;i<0;++i,dest+=d_step)
115 for (std::ptrdiff_t i=0;i<k_hi;++i,dest+=d_step)
119 const kernelT* k = kernel+i*kstep;
120 for (std::ptrdiff_t j=i;j>=k_lo;--j,s+=s_step,k-=kstep)
121 sum+= (accumT)((*s)*(*k));
128 std::ptrdiff_t i_max = k_hi-1;
129 for (std::ptrdiff_t i=0;i<=i_max;++i)
132 for (std::ptrdiff_t j=-k_hi;j<=-k_lo;++j)
134 if ((i+j)<0) sum+=(accumT)(src[0]*kernel[j*(-kstep)]);
135 else sum+=(accumT)(src[(i+j)*s_step]*kernel[j*(-kstep)]);
137 dest[i*d_step]=(destT)sum;
144 std::ptrdiff_t i_max = k_hi-1;
145 for (std::ptrdiff_t i=0;i<=i_max;++i)
148 for (std::ptrdiff_t j=-k_hi;j<=-k_lo;++j)
150 if ((i+j)<0) sum+=(accumT)(src[-(i+j)*s_step]*kernel[j*(-kstep)]);
151 else sum+=(accumT)(src[(i+j)*s_step]*kernel[j*(-kstep)]);
153 dest[i*d_step]=(destT)sum;
160 std::ptrdiff_t i_max = k_hi-1;
161 for (
int i=0;i<=i_max;++i)
164 for (std::ptrdiff_t j=k_hi;j>=k_lo;--j)
165 sum+=(accumT)(src[((i-j+n)%n)*s_step]*kernel[j*kstep]);
166 dest[i*d_step]=(destT)sum;
174 for (std::ptrdiff_t j=-k_hi;j<=-k_lo;++j) k_sum_all+=(accumT)(kernel[j*(-kstep)]);
176 std::ptrdiff_t i_max = k_hi-1;
177 for (std::ptrdiff_t i=0;i<=i_max;++i)
183 for (std::ptrdiff_t j=-i;j<=-k_lo;++j)
185 sum+=(accumT)(src[(i+j)*s_step]*kernel[j*(-kstep)]);
186 k_sum += (accumT)(kernel[j*(-kstep)]);
188 dest[i*d_step]=(destT)(sum*k_sum_all/k_sum);
193 std::cout<<
"ERROR: vil_convolve_edge_1d: " 194 <<
"Sorry, can't deal with supplied edge option.\n";
202 template <
class srcT,
class destT,
class kernelT,
class accumT>
204 destT* dest0, std::ptrdiff_t d_step,
205 const kernelT* kernel,
206 std::ptrdiff_t k_lo, std::ptrdiff_t k_hi,
211 assert(k_hi - k_lo <
int(nx));
214 vil_convolve_edge_1d(src0,nx,s_step,dest0,d_step,kernel,k_lo,k_hi,1,ac,start_option);
216 const kernelT* k_rbegin = kernel+k_hi;
217 const kernelT* k_rend = kernel+k_lo-1;
218 assert(k_rbegin >= k_rend);
219 const srcT* src = src0;
221 for (destT * dest = dest0 + d_step*k_hi,
222 *
const end_dest = dest0 + d_step*(
int(nx)+k_lo);
224 dest+=d_step,src+=s_step)
228 for (
const kernelT *k = k_rbegin;k!=k_rend;--k,s+=s_step)
229 sum+= (accumT)((*k)*(*s));
235 dest0+(nx-1)*d_step,-d_step,
236 kernel,-k_hi,-k_lo,-1,ac,end_option);
247 template <
class srcT,
class destT,
class kernelT,
class accumT>
250 const kernelT* kernel,
251 std::ptrdiff_t k_lo, std::ptrdiff_t k_hi,
256 unsigned n_i = src_im.
ni();
257 unsigned n_j = src_im.
nj();
258 assert(k_hi - k_lo +1 <= (
int) n_i);
259 std::ptrdiff_t s_istep = src_im.
istep(), s_jstep = src_im.
jstep();
262 std::ptrdiff_t d_istep = dest_im.
istep(),d_jstep = dest_im.
jstep();
264 for (
unsigned int p=0;p<src_im.
nplanes();++p)
276 for (
unsigned int j=0;j<n_j;++j,src_row+=s_jstep,dest_row+=d_jstep)
278 kernel,k_lo,k_hi,ac,start_option,end_option);
280 for (
unsigned int j=0;j<n_j;++j,src_row+=s_jstep,dest_row+=d_jstep)
282 kernel,k_lo,k_hi,ac,start_option,end_option);
287 for (
unsigned int j=0;j<n_j;++j,src_row+=s_jstep,dest_row+=d_jstep)
289 kernel,k_lo,k_hi,ac,start_option,end_option);
291 for (
unsigned int j=0;j<n_j;++j,src_row+=s_jstep,dest_row+=d_jstep)
293 kernel,k_lo,k_hi,ac,start_option,end_option);
298 template <
class destT,
class kernelT,
class accumT>
302 const kernelT* kernel,
int k_lo,
int k_hi,
308 template <
class kernelT,
class accumT,
class destT>
315 const kernelT* kernel,
int k_lo,
int k_hi,
328 int k_lo,
int k_hi,
const accumT ac,
334 unsigned j0,
unsigned n_j)
const override 336 if (i0 + n_i >
src_->ni() || j0 + n_j >
src_->nj())
return nullptr;
337 const unsigned lsrc = (unsigned) std::max(0,(
int)i0 +
klo_);
338 const unsigned hsrc = std::min(
src_->ni(),i0 + n_i -
klo_ +
khi_);
339 const unsigned lboundary = std::min((
unsigned) -
klo_, i0);
340 assert (hsrc > lsrc);
343 switch (vs->pixel_format())
345 #define macro( F , T ) \ 347 vil_convolve_1d(static_cast<vil_image_view<T >&>(*vs),dest, \ 348 kernel_, klo_, khi_, accumT(), start_option_, end_option_); \ 349 return new vil_image_view<destT>(vil_crop(dest, lboundary, n_i, 0, n_j)); 369 unsigned ni()
const override {
return src_->ni(); }
370 unsigned nj()
const override {
return src_->nj(); }
379 std::cerr <<
"WARNING: vil_convolve_1d_resource::put_back\n" 380 <<
"\tYou can't push data back into a convolve filter.\n";
385 bool get_property(
char const* tag,
void* property_value =
nullptr)
const override 388 return property_value ? (*static_cast<bool*>(property_value)) =
true :
true;
390 return src_->get_property(tag, property_value);
405 template <
class destT,
class kernelT,
class accumT>
409 const kernelT* kernel,
int k_lo,
int k_hi,
417 #endif // vil_convolve_1d_h_ An abstract base class of smart pointers to actual image data in memory.
vil_convolve_boundary_option end_option_
Extend the signal to be constant beyond the boundary.
Extend the signal periodically beyond the boundary.
Concrete view of image data of type T held in memory.
enum vil_pixel_format pixel_format() const override
Pixel Format.
unsigned ni() const override
Dimensions: Planes x ni x nj.
void set_size(unsigned ni, unsigned nj) override
resize current planes to ni x nj.
void vil_convolve_edge_1d(const srcT *src, unsigned n, std::ptrdiff_t s_step, destT *dest, std::ptrdiff_t d_step, const kernelT *kernel, std::ptrdiff_t k_lo, std::ptrdiff_t k_hi, std::ptrdiff_t kstep, accumT, vil_convolve_boundary_option option)
Convolve edge with kernel[x*kstep] x in [k_lo,k_hi] (k_hi>=0).
unsigned nj() const override
Dimensions: Planes x ni x nj.
std::ptrdiff_t jstep() const
Add this to your pixel pointer to get next j pixel.
vil_convolve_boundary_option
Available options for boundary behavior.
unsigned ni() const
Width.
A resource adaptor that behaves like a convolved version of its input.
unsigned nj() const
Height.
vil_convolve_1d_resource(const vil_image_resource_sptr &src, const kernelT *kernel, int k_lo, int k_hi, vil_convolve_boundary_option start_option, vil_convolve_boundary_option end_option)
Construct a convolve filter.
vil_convolve_boundary_option start_option_
std::ptrdiff_t planestep() const
Add this to your pixel pointer to get pixel on next plane.
vil_image_view_base_sptr get_copy_view(unsigned i0, unsigned n_i, unsigned j0, unsigned n_j) const override
Create a read/write view of a copy of this data.
Do not fill destination edges at all.
Kernel is trimmed and reweighed, to allow convolution up to boundary.
Abstract representation of an image source or image destination.
A base class reference-counting view of some image data.
Do not to extend the signal, but pad with zeros.
There is no class or function called vil_property.
T * top_left_ptr()
Pointer to the first (top left in plane 0) pixel.
void vil_convolve_1d(const vil_image_view< srcT > &src_im, vil_image_view< destT > &dest_im, const kernelT *kernel, std::ptrdiff_t k_lo, std::ptrdiff_t k_hi, accumT ac, vil_convolve_boundary_option start_option, vil_convolve_boundary_option end_option)
Convolve kernel[i] (i in [k_lo,k_hi]) with srcT in i-direction.
Zero-extend the input signal beyond the boundary.
unsigned nplanes() const
Number of planes.
bool get_property(char const *tag, void *property_value=nullptr) const override
Extra property information.
bool put_view(const vil_image_view_base &, unsigned, unsigned) override
Put the data in this view back into the image source.
Representation of a generic image source or destination.
Extend the signal by reflection about the boundary.
unsigned nplanes() const override
Dimensions: Planes x ni x nj.
std::ptrdiff_t istep() const
Add this to your pixel pointer to get next i pixel.
vil_image_resource_sptr src_
#define vil_property_read_only
Indicate that you can't call put_view on this image.