2 #ifndef vil_gauss_filter_hxx_ 3 #define vil_gauss_filter_hxx_ 14 # include <vcl_msvc_warnings.h> 21 inline unsigned char vl_round(
double x,
unsigned char ) {
return (
unsigned char )(x<0?x-0.5:x+0.5);}
22 inline signed char vl_round(
double x,
signed char ) {
return (
signed char )(x<0?x-0.5:x+0.5);}
23 inline unsigned short vl_round(
double x,
unsigned short ) {
return (
unsigned short)(x<0?x-0.5:x+0.5);}
24 inline signed short vl_round(
double x,
signed short ) {
return (
signed short)(x<0?x-0.5:x+0.5);}
25 inline unsigned int vl_round(
double x,
unsigned int ) {
return (
unsigned int )(x<0?x-0.5:x+0.5);}
26 inline signed int vl_round(
double x,
signed int ) {
return (
signed int )(x<0?x-0.5:x+0.5);}
27 inline unsigned long vl_round(
double x,
unsigned long ) {
return (
unsigned long )(x<0?x-0.5:x+0.5);}
28 inline signed long vl_round(
double x,
signed long ) {
return (
signed long )(x<0?x-0.5:x+0.5);}
29 inline double vl_round(
double x,
double ) {
return x; }
30 inline float vl_round(
double x,
float ) {
return (
float)x; }
38 template <
class srcT,
class destT>
40 destT* dest_im, std::ptrdiff_t dest_istep, std::ptrdiff_t dest_jstep,
42 destT* work, std::ptrdiff_t work_jstep)
44 assert (nx > 3 && ny > 3);
48 for (
unsigned int y=0;y<ny;y++)
50 destT* work_row = work + y*work_jstep;
51 const srcT* src_col3 = src_im + y*src_jstep;
52 const srcT* src_col2 = src_col3 - src_istep;
53 const srcT* src_col1 = src_col3 - 2 * src_istep;
54 const srcT* src_col4 = src_col3 + src_istep;
55 const srcT* src_col5 = src_col3 + 2 * src_istep;
60 work_row[x] =
vl_round( params.
filt2() * src_col1[x*src_istep]
61 + params.
filt1() * src_col2[x*src_istep]
62 + params.
filt0() * src_col3[x*src_istep]
63 + params.
filt1() * src_col4[x*src_istep]
64 + params.
filt2() * src_col5[x*src_istep], (destT)0);
69 + params.
filt_edge2() * src_col5[0], (destT)0);
82 + params.
filt_edge1() * src_col2[(nx-1)*src_istep]
83 + params.
filt_edge0() * src_col3[(nx-1)*src_istep], (destT)0);
88 for (
unsigned int y=2;y<ny-2;y++)
90 destT* dest_row = dest_im + y*dest_jstep;
92 const destT* work_row3 = work + y*work_jstep;
93 const destT* work_row2 = work_row3 - work_jstep;
94 const destT* work_row1 = work_row3 - 2 * work_jstep;
95 const destT* work_row4 = work_row3 + work_jstep;
96 const destT* work_row5 = work_row3 + 2 * work_jstep;
98 for (
unsigned int x=0; x<nx; x++)
99 dest_row[x*dest_istep] =
vl_round( params.
filt2() * work_row1[x]
100 + params.
filt1() * work_row2[x]
101 + params.
filt0() * work_row3[x]
102 + params.
filt1() * work_row4[x]
103 + params.
filt2() * work_row5[x], (destT)0);
108 const destT* work_row_bottom_1 = work;
109 const destT* work_row_bottom_2 = work_row_bottom_1 + work_jstep;
110 const destT* work_row_bottom_3 = work_row_bottom_1 + 2 * work_jstep;
111 const destT* work_row_bottom_4 = work_row_bottom_1 + 3 * work_jstep;
113 const destT* work_row_top_5 = work + (ny-1) * work_jstep;
114 const destT* work_row_top_4 = work_row_top_5 - work_jstep;
115 const destT* work_row_top_3 = work_row_top_5 - 2 * work_jstep;
116 const destT* work_row_top_2 = work_row_top_5 - 3 * work_jstep;
118 destT* dest_row_top = dest_im + (ny-1) * dest_jstep;
119 destT* dest_row_next_top = dest_row_top - dest_jstep;
120 destT* dest_row_bottom = dest_im;
121 destT* dest_row_next_bottom = dest_row_bottom + dest_jstep;
123 for (
unsigned int x=0;x<nx;x++)
127 + params.
filt_edge2() * work_row_top_3[x], (destT)0);
141 + params.
filt_edge0() * work_row_bottom_1[x], (destT)0);
146 template <
class srcT,
class destT>
152 unsigned ni = src_im.
ni();
153 unsigned nj = src_im.
nj();
154 unsigned n_planes = src_im.
nplanes();
157 assert (work.
jstep() == (std::ptrdiff_t)ni);
159 if (ni > 3 && nj > 3)
161 for (
unsigned p=0;p<n_planes;++p)
163 &dest_im(0,0,p), dest_im.
istep(), dest_im.
jstep(), ni,nj,
167 if (ni==0 || nj==0)
return;
170 for (
unsigned p=0;p<n_planes;++p)
171 for (
unsigned j=0;j<nj;++j)
172 work(0,j,p) =
vl_round(src_im(0,j,p), destT());
176 const double k0 = params.filt0()/(params.filt0() + params.filt1());
177 const double k1 = params.filt1()/(params.filt0() + params.filt1());
178 for (
unsigned p=0;p<n_planes;++p)
179 for (
unsigned j=0;j<nj;++j)
181 work(0,j,p) =
vl_round(k0*src_im(0,j,p) + k1*src_im(1,j,p), destT());
182 work(1,j,p) =
vl_round(k1*src_im(0,j,p) + k0*src_im(1,j,p), destT());
187 const double ke0 = params.filt0()/(params.filt0() + params.filt1());
188 const double ke1 = params.filt1()/(params.filt0() + params.filt1());
189 const double k0 = params.filt0()/(params.filt0() + 2.0*params.filt1());
190 const double k1 = params.filt1()/(params.filt0() + 2.0*params.filt1());
191 for (
unsigned p=0;p<n_planes;++p)
192 for (
unsigned j=0;j<nj;++j)
194 work(0,j,p) =
vl_round(ke0*src_im(0,j,p) + ke1*src_im(1,j,p) , destT());
195 work(1,j,p) =
vl_round(k1 *src_im(0,j,p) + k0 *src_im(1,j,p) + k1 *src_im(2,j,p), destT());
196 work(2,j,p) =
vl_round( ke1*src_im(1,j,p) + ke0*src_im(2,j,p), destT());
201 const double ke0 = params.filt_edge0();
202 const double ke1 = params.filt_edge1();
203 const double ke2 = params.filt_edge2();
204 const double kpn1= params.filt_pen_edge_n1();
205 const double kp0 = params.filt_pen_edge0();
206 const double kp1 = params.filt_pen_edge1();
207 const double kp2 = params.filt_pen_edge2();
208 for (
unsigned p=0;p<n_planes;++p)
209 for (
unsigned j=0;j<nj;++j)
211 work(0,j,p) =
vl_round(ke0 *src_im(0,j,p) + ke1*src_im(1,j,p) + ke2*src_im(2,j,p) , destT());
212 work(1,j,p) =
vl_round(kpn1*src_im(0,j,p) + kp0*src_im(1,j,p) + kp1*src_im(2,j,p) + kp2 *src_im(3,j,p), destT());
213 work(2,j,p) =
vl_round(kp2 *src_im(0,j,p) + kp1*src_im(1,j,p) + kp0*src_im(2,j,p) + kpn1*src_im(3,j,p), destT());
214 work(3,j,p) =
vl_round( ke2*src_im(1,j,p) + ke1*src_im(2,j,p) + ke0 *src_im(3,j,p), destT());
220 kernel[0] = kernel[4] = params.filt2();
221 kernel[1] = kernel[3] = params.filt1();
222 kernel[2] = params.filt0();
230 const double k0 = params.filt0()/(params.filt0() + params.filt1());
231 const double k1 = params.filt1()/(params.filt0() + params.filt1());
232 for (
unsigned p=0;p<n_planes;++p)
233 for (
unsigned i=0;i<ni;++i)
235 dest_im(i,0,p) =
vl_round(k0 * work(i,0,p) + k1 * work(i,1,p), destT());
236 dest_im(i,1,p) =
vl_round(k1 * work(i,0,p) + k0 * work(i,1,p), destT());
241 const double ke0 = params.filt0()/(params.filt0() + params.filt1());
242 const double ke1 = params.filt1()/(params.filt0() + params.filt1());
243 const double k0 = params.filt0()/(params.filt0() + 2.0*params.filt1());
244 const double k1 = params.filt1()/(params.filt0() + 2.0*params.filt1());
245 for (
unsigned p=0;p<n_planes;++p)
246 for (
unsigned i=0;i<ni;++i)
248 dest_im(i,0,p) =
vl_round(ke0*work(i,0,p) + ke1*work(i,1,p) , destT());
249 dest_im(i,1,p) =
vl_round(k1 *work(i,0,p) + k0 *work(i,1,p) + k1 *work(i,2,p), destT());
250 dest_im(i,2,p) =
vl_round( ke1*work(i,1,p) + ke0*work(i,2,p), destT());
255 const double ke0 = params.filt_edge0();
256 const double ke1 = params.filt_edge1();
257 const double ke2 = params.filt_edge2();
258 const double kpn1= params.filt_pen_edge_n1();
259 const double kp0 = params.filt_pen_edge0();
260 const double kp1 = params.filt_pen_edge1();
261 const double kp2 = params.filt_pen_edge2();
262 for (
unsigned p=0;p<n_planes;++p)
263 for (
unsigned i=0;i<ni;++i)
265 dest_im(i,0,p) =
vl_round(ke0 *work(i,0,p) + ke1*work(i,1,p) + ke2*work(i,2,p) , destT());
266 dest_im(i,1,p) =
vl_round(kpn1*work(i,0,p) + kp0*work(i,1,p) + kp1*work(i,2,p) + kp2 *work(i,3,p), destT());
267 dest_im(i,2,p) =
vl_round(kp2 *work(i,0,p) + kp1*work(i,1,p) + kp0*work(i,2,p) + kpn1*work(i,3,p), destT());
268 dest_im(i,3,p) =
vl_round( ke2*work(i,1,p) + ke1*work(i,2,p) + ke0 *work(i,3,p), destT());
274 kernel[0] = kernel[4] = params.filt2();
275 kernel[1] = kernel[3] = params.filt1();
276 kernel[2] = params.filt0();
284 vsl_indent_inc(std::cout);
285 std::cout << vsl_indent() <<
"Work image B\n";
286 workb_.print_all(std::cout);
287 vsl_indent_dec(std::cout);
291 #undef VIL_GAUSS_FILTER_INSTANTIATE 292 #define VIL_GAUSS_FILTER_INSTANTIATE(srcT, destT) \ 293 template void vil_gauss_filter_5tap(const vil_image_view<srcT >& src_im, \ 294 vil_image_view<destT >& dest_im, \ 295 const vil_gauss_filter_5tap_params& params, \ 296 vil_image_view<destT >& work) 298 #endif // vil_gauss_filter_hxx_ double filt1() const
Filter tap value.
Concrete view of image data of type T held in memory.
double filt_edge0() const
Filter tap value.
double filt2() const
Filter tap value.
void set_size(unsigned ni, unsigned nj) override
resize current planes to ni x nj.
std::ptrdiff_t jstep() const
Add this to your pixel pointer to get next j pixel.
unsigned ni() const
Width.
unsigned nj() const
Height.
double filt_pen_edge0() const
Filter tap value.
double filt_pen_edge2() const
Filter tap value.
Kernel is trimmed and reweighed, to allow convolution up to boundary.
double filt_edge1() const
Filter tap value.
double filt0() const
Filter tap value.
double filt_pen_edge1() const
Filter tap value.
double filt_pen_edge_n1() const
Filter tap value.
void vil_gauss_filter_5tap(const srcT *src_im, std::ptrdiff_t src_istep, std::ptrdiff_t src_jstep, destT *dest_im, std::ptrdiff_t dest_istep, std::ptrdiff_t dest_jstep, unsigned nx, unsigned ny, const vil_gauss_filter_5tap_params ¶ms, destT *work, std::ptrdiff_t work_jstep)
Smooth and subsample src_im to produce dest_im.
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.
unsigned char vl_round(double x, unsigned char)
unsigned nplanes() const
Number of planes.
double filt_edge2() const
Filter tap value.
std::ptrdiff_t istep() const
Add this to your pixel pointer to get next i pixel.
1D Convolution with cunning boundary options
vil_image_view< T > vil_transpose(const vil_image_view< T > &v)
Create a view which appears as the transpose of this view.