annotate src/__bilateral__.cc @ 571:d8ad8f768386

isbw: delegate checks to new shared private functions and add test blocks
author carandraug
date Sun, 02 Sep 2012 02:31:53 +0000
parents c45838839d86
children c6be7812523a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
561
c45838839d86 maint: update license to GPLv3 and mention non GPL files
carandraug
parents: 336
diff changeset
1 // Copyright (C) 2008 Soren Hauberg <soren@hauberg.org>
313
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
2 //
561
c45838839d86 maint: update license to GPLv3 and mention non GPL files
carandraug
parents: 336
diff changeset
3 // This program is free software; you can redistribute it and/or modify it under
c45838839d86 maint: update license to GPLv3 and mention non GPL files
carandraug
parents: 336
diff changeset
4 // the terms of the GNU General Public License as published by the Free Software
c45838839d86 maint: update license to GPLv3 and mention non GPL files
carandraug
parents: 336
diff changeset
5 // Foundation; either version 3 of the License, or (at your option) any later
c45838839d86 maint: update license to GPLv3 and mention non GPL files
carandraug
parents: 336
diff changeset
6 // version.
313
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
7 //
561
c45838839d86 maint: update license to GPLv3 and mention non GPL files
carandraug
parents: 336
diff changeset
8 // This program is distributed in the hope that it will be useful, but WITHOUT
c45838839d86 maint: update license to GPLv3 and mention non GPL files
carandraug
parents: 336
diff changeset
9 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
c45838839d86 maint: update license to GPLv3 and mention non GPL files
carandraug
parents: 336
diff changeset
10 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
c45838839d86 maint: update license to GPLv3 and mention non GPL files
carandraug
parents: 336
diff changeset
11 // details.
313
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
12 //
561
c45838839d86 maint: update license to GPLv3 and mention non GPL files
carandraug
parents: 336
diff changeset
13 // You should have received a copy of the GNU General Public License along with
c45838839d86 maint: update license to GPLv3 and mention non GPL files
carandraug
parents: 336
diff changeset
14 // this program; if not, see <http://www.gnu.org/licenses/>.
313
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
15
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
16 #include <octave/oct.h>
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
17
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
18 inline
331
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
19 double gauss (const double *x, const double *mu, const double sigma, const octave_idx_type ndims)
313
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
20 {
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
21 double s = 0;
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
22 for (octave_idx_type i = 0; i < ndims; i++)
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
23 {
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
24 const double d = x[i] - mu[i];
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
25 s += d*d;
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
26 }
331
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
27 return exp (-0.5*s/(sigma*sigma));
313
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
28 }
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
29
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
30 template <class MatrixType>
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
31 octave_value
331
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
32 bilateral (const MatrixType &im, const double sigma_d, const double sigma_r)
313
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
33 {
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
34 // Get sizes
331
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
35 const octave_idx_type ndims = im.ndims ();
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
36 const dim_vector size = im.dims ();
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
37 const octave_idx_type num_planes = (ndims == 2) ? 1 : size (2);
313
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
38
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
39 // Build spatial kernel
331
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
40 const int s = std::max ((int)xround (3*sigma_d), 1);
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
41 Matrix kernel (2*s+1, 2*s+1);
313
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
42 for (octave_idx_type r = 0; r < 2*s+1; r++)
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
43 {
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
44 for (octave_idx_type c = 0; c < 2*s+1; c++)
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
45 {
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
46 const int dr = r-s;
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
47 const int dc = c-s;
331
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
48 kernel (r,c) = exp (-0.5 * (dr*dr + dc*dc)/(sigma_d*sigma_d));
313
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
49 }
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
50 }
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
51
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
52 // Allocate output
331
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
53 dim_vector out_size (size);
335
d1fbac52b034 64bit fix
hauberg
parents: 331
diff changeset
54 out_size (0) = std::max (size (0) - 2*s, (octave_idx_type)0);
336
7abf13c5b3e3 Fix typo
goffioul
parents: 335
diff changeset
55 out_size (1) = std::max (size (1) - 2*s, (octave_idx_type)0);
331
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
56 MatrixType out = MatrixType (out_size);
313
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
57
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
58 // Iterate over every element of 'out'.
331
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
59 for (octave_idx_type r = 0; r < out_size (0); r++)
313
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
60 {
331
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
61 for (octave_idx_type c = 0; c < out_size (1); c++)
313
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
62 {
331
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
63 OCTAVE_QUIT;
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
64
313
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
65 // For each neighbour
326
23d88658d3ca Fix MSVC compilation
goffioul
parents: 313
diff changeset
66 OCTAVE_LOCAL_BUFFER (double, val, num_planes);
23d88658d3ca Fix MSVC compilation
goffioul
parents: 313
diff changeset
67 OCTAVE_LOCAL_BUFFER (double, sum, num_planes);
313
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
68 double k = 0;
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
69 for (octave_idx_type i = 0; i < num_planes; i++)
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
70 {
331
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
71 val[i] = im (r,c,i);
313
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
72 sum[i] = 0;
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
73 }
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
74 for (octave_idx_type kr = 0; kr < 2*s+1; kr++)
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
75 {
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
76 for (octave_idx_type kc = 0; kc < 2*s+1; kc++)
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
77 {
326
23d88658d3ca Fix MSVC compilation
goffioul
parents: 313
diff changeset
78 OCTAVE_LOCAL_BUFFER (double, lval, num_planes);
331
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
79 for (octave_idx_type i = 0; i < num_planes; i++)
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
80 lval[i] = im (r+kr, c+kc, i);
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
81 const double w = kernel (kr, kc) * gauss (val, lval, sigma_r, num_planes);
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
82 for (octave_idx_type i = 0; i < num_planes; i++)
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
83 sum[i] += w * lval[i];
313
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
84 k += w;
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
85 }
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
86 }
331
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
87 for (octave_idx_type i = 0; i < num_planes; i++)
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
88 out (r, c, i) = sum[i]/k;
313
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
89 }
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
90 }
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
91
331
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
92 return octave_value (out);
313
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
93 }
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
94
331
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
95 DEFUN_DLD (__bilateral__, args, , "\
313
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
96 -*- texinfo -*-\n\
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
97 @deftypefn {Loadable Function} __bilateral__(@var{im}, @var{sigma_d}, @var{sigma_r})\n\
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
98 Performs Gaussian bilateral filtering in the image @var{im}. @var{sigma_d} is the\n\
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
99 spread of the Gaussian used as closenes function, and @var{sigma_r} is the spread\n\
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
100 of Gaussian used as similarity function. This function is internal and should NOT\n\
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
101 be called directly. Instead use @code{imsmooth}.\n\
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
102 @end deftypefn\n\
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
103 ")
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
104 {
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
105 octave_value_list retval;
331
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
106 if (args.length () != 3)
313
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
107 {
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
108 print_usage ();
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
109 return retval;
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
110 }
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
111
331
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
112 const octave_idx_type ndims = args (0).ndims ();
313
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
113 if (ndims != 2 && ndims != 3)
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
114 {
331
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
115 error ("__bilateral__: only 2 and 3 dimensional is supported");
313
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
116 return retval;
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
117 }
331
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
118 const double sigma_d = args (1).scalar_value ();
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
119 const double sigma_r = args (2).scalar_value ();
313
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
120 if (error_state)
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
121 {
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
122 error("__bilateral__: invalid input");
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
123 return retval;
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
124 }
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
125
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
126 // Take action depending on input type
331
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
127 if (args (0).is_real_matrix ())
313
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
128 {
331
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
129 const NDArray im = args(0).array_value ();
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
130 retval = bilateral<NDArray> (im, sigma_d, sigma_r);
313
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
131 }
331
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
132 else if (args (0).is_int8_type ())
313
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
133 {
331
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
134 const int8NDArray im = args (0).int8_array_value ();
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
135 retval = bilateral<int8NDArray> (im, sigma_d, sigma_r);
313
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
136 }
331
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
137 else if (args (0).is_int16_type ())
313
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
138 {
331
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
139 const int16NDArray im = args (0).int16_array_value ();
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
140 retval = bilateral<int16NDArray> (im, sigma_d, sigma_r);
313
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
141 }
331
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
142 else if (args (0).is_int32_type ())
313
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
143 {
331
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
144 const int32NDArray im = args (0).int32_array_value ();
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
145 retval = bilateral<int32NDArray> (im, sigma_d, sigma_r);
313
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
146 }
331
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
147 else if (args (0).is_int64_type ())
313
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
148 {
331
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
149 const int64NDArray im = args (0).int64_array_value ();
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
150 retval = bilateral<int64NDArray> (im, sigma_d, sigma_r);
313
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
151 }
331
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
152 else if (args (0).is_uint8_type ())
313
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
153 {
331
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
154 const uint8NDArray im = args (0).uint8_array_value ();
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
155 retval = bilateral<uint8NDArray> (im, sigma_d, sigma_r);
313
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
156 }
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
157 else if (args(0).is_uint16_type())
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
158 {
331
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
159 const uint16NDArray im = args (0).uint16_array_value ();
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
160 retval = bilateral<uint16NDArray> (im, sigma_d, sigma_r);
313
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
161 }
331
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
162 else if (args (0).is_uint32_type ())
313
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
163 {
331
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
164 const uint32NDArray im = args (0).uint32_array_value ();
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
165 retval = bilateral<uint32NDArray> (im, sigma_d, sigma_r);
313
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
166 }
331
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
167 else if (args (0).is_uint64_type ())
313
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
168 {
331
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
169 const uint64NDArray im = args (0).uint64_array_value ();
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
170 retval = bilateral<uint64NDArray> (im, sigma_d, sigma_r);
313
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
171 }
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
172 else
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
173 {
331
84404cf2842b Fix index bug
hauberg
parents: 326
diff changeset
174 error ("__bilateral__: first input should be a real or integer array");
313
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
175 return retval;
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
176 }
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
177
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
178 return retval;
242b7e14560a imsmooth: support for bilateral filtering
hauberg
parents:
diff changeset
179 }