vil_sobel_1x3.cxx
Go to the documentation of this file.
1 //:
2 // \file
3 // \brief Apply gradient operator to 2D planes of data
4 // \author Tim Cootes
5 
6 #include "vil_sobel_1x3.h"
7 
8 //: Compute gradients of single plane of 2D data using 1x3 Sobel filters
9 // Computes both i and j gradients of an ni x nj plane of data
10 template <>
11 void vil_sobel_1x3_1plane(const unsigned char* src,
12  std::ptrdiff_t s_istep, std::ptrdiff_t s_jstep,
13  float* gi, std::ptrdiff_t gi_istep, std::ptrdiff_t gi_jstep,
14  float* gj, std::ptrdiff_t gj_istep, std::ptrdiff_t gj_jstep,
15  unsigned ni, unsigned nj)
16 {
17  const unsigned char* s_data = src;
18  float *gi_data = gi;
19  float *gj_data = gj;
20 
21  if (ni==0 || nj==0) return;
22  if (ni==1)
23  {
24  // Zero the elements in the column
25  for (unsigned j=0;j<nj;++j)
26  {
27  *gi_data = 0;
28  *gj_data = 0;
29  gi_data += gi_jstep;
30  gj_data += gj_jstep;
31  }
32  return;
33  }
34  if (nj==1)
35  {
36  // Zero the elements in the column
37  for (unsigned i=0;i<ni;++i)
38  {
39  *gi_data = 0;
40  *gj_data = 0;
41  gi_data += gi_istep;
42  gj_data += gj_istep;
43  }
44  return;
45  }
46 
47  // Compute relative grid positions
48  // o2
49  // o4 o5
50  // o7
51  const std::ptrdiff_t o2 = s_jstep;
52  const std::ptrdiff_t o4 = -s_istep;
53  const std::ptrdiff_t o5 = s_istep;
54  const std::ptrdiff_t o7 = -s_jstep;
55 
56  const unsigned ni1 = ni-1;
57  const unsigned nj1 = nj-1;
58 
59  s_data += s_istep + s_jstep;
60  gi_data += gi_jstep;
61  gj_data += gj_jstep;
62 
63  for (unsigned j=1;j<nj1;++j)
64  {
65  const unsigned char* s = s_data;
66  float* pgi = gi_data;
67  float* pgj = gj_data;
68 
69  // Zero the first elements in the rows
70  *pgi = 0; pgi+=gi_istep;
71  *pgj = 0; pgj+=gj_istep;
72 
73  for (unsigned i=1;i<ni1;++i)
74  {
75  // Compute gradient in i
76  // Note: Multiply each element individually
77  // to ensure conversion to float before addition
78  *pgi = 0.5f*s[o5] - 0.5f*s[o4];
79  // Compute gradient in j
80  *pgj = 0.5f*s[o2] - 0.5f*s[o7];
81 
82  s+=s_istep;
83  pgi += gi_istep;
84  pgj += gj_istep;
85  }
86 
87  // Zero the last elements in the rows
88  *pgi = 0;
89  *pgj = 0;
90 
91  // Move to next row
92  s_data += s_jstep;
93  gi_data += gi_jstep;
94  gj_data += gj_jstep;
95  }
96 
97  // Zero the first and last rows
98  for (unsigned i=0;i<ni;++i)
99  {
100  *gi=0; gi+=gi_istep;
101  *gj=0; gj+=gj_istep;
102  *gi_data = 0; gi_data+=gi_istep;
103  *gj_data = 0; gj_data+=gj_istep;
104  }
105 }
106 
107 //: Compute gradients of single plane of 2D data using 1x3 Sobel filters
108 // Computes both i and j gradients of an ni x nj plane of data
109 template <>
110 void vil_sobel_1x3_1plane(const unsigned char* src,
111  std::ptrdiff_t s_istep, std::ptrdiff_t s_jstep,
112  double* gi, std::ptrdiff_t gi_istep, std::ptrdiff_t gi_jstep,
113  double* gj, std::ptrdiff_t gj_istep, std::ptrdiff_t gj_jstep,
114  unsigned ni, unsigned nj)
115 {
116  const unsigned char* s_data = src;
117  double *gi_data = gi;
118  double *gj_data = gj;
119 
120  if (ni==0 || nj==0) return;
121  if (ni==1)
122  {
123  // Zero the elements in the column
124  for (unsigned j=0;j<nj;++j)
125  {
126  *gi_data = 0;
127  *gj_data = 0;
128  gi_data += gi_jstep;
129  gj_data += gj_jstep;
130  }
131  return;
132  }
133  if (nj==1)
134  {
135  // Zero the elements in the column
136  for (unsigned i=0;i<ni;++i)
137  {
138  *gi_data = 0;
139  *gj_data = 0;
140  gi_data += gi_istep;
141  gj_data += gj_istep;
142  }
143  return;
144  }
145 
146  // Compute relative grid positions
147  // o2
148  // o4 o5
149  // o7
150  const std::ptrdiff_t o2 = s_jstep;
151  const std::ptrdiff_t o4 = -s_istep;
152  const std::ptrdiff_t o5 = s_istep;
153  const std::ptrdiff_t o7 = -s_jstep;
154 
155  const unsigned ni1 = ni-1;
156  const unsigned nj1 = nj-1;
157 
158  s_data += s_istep + s_jstep;
159  gi_data += gi_jstep;
160  gj_data += gj_jstep;
161 
162  for (unsigned j=1;j<nj1;++j)
163  {
164  const unsigned char* s = s_data;
165  double* pgi = gi_data;
166  double* pgj = gj_data;
167 
168  // Zero the first elements in the rows
169  *pgi = 0; pgi+=gi_istep;
170  *pgj = 0; pgj+=gj_istep;
171 
172  for (unsigned i=1;i<ni1;++i)
173  {
174  // Compute gradient in i
175  // Note: Multiply each element individually
176  // to ensure conversion to double before addition
177  *pgi = 0.5*s[o5] - 0.5*s[o4];
178  // Compute gradient in j
179  *pgj = 0.5*s[o2] - 0.5*s[o7];
180 
181  s+=s_istep;
182  pgi += gi_istep;
183  pgj += gj_istep;
184  }
185 
186  // Zero the last elements in the rows
187  *pgi = 0;
188  *pgj = 0;
189 
190  // Move to next row
191  s_data += s_jstep;
192  gi_data += gi_jstep;
193  gj_data += gj_jstep;
194  }
195 
196  // Zero the first and last rows
197  for (unsigned i=0;i<ni;++i)
198  {
199  *gi=0; gi+=gi_istep;
200  *gj=0; gj+=gj_istep;
201  *gi_data = 0; gi_data+=gi_istep;
202  *gj_data = 0; gj_data+=gj_istep;
203  }
204 }
205 
206 //: Compute gradients of single plane of 2D data using 1x3 Sobel filters
207 // Computes both x and j gradients of an nx x nj plane of data
208 template <>
209 void vil_sobel_1x3_1plane(const float* src,
210  std::ptrdiff_t s_istep, std::ptrdiff_t s_jstep,
211  float* gi, std::ptrdiff_t gi_istep, std::ptrdiff_t gi_jstep,
212  float* gj, std::ptrdiff_t gj_istep, std::ptrdiff_t gj_jstep,
213  unsigned ni, unsigned nj)
214 {
215  const float* s_data = src;
216  float *gi_data = gi;
217  float *gj_data = gj;
218 
219  if (ni==0 || nj==0) return;
220  if (ni==1)
221  {
222  // Zero the elements in the column
223  for (unsigned j=0;j<nj;++j)
224  {
225  *gi_data = 0;
226  *gj_data = 0;
227  gi_data += gi_jstep;
228  gj_data += gj_jstep;
229  }
230  return;
231  }
232  if (nj==1)
233  {
234  // Zero the elements in the column
235  for (unsigned i=0;i<ni;++i)
236  {
237  *gi_data = 0;
238  *gj_data = 0;
239  gi_data += gi_istep;
240  gj_data += gj_istep;
241  }
242  return;
243  }
244 
245  // Compute relative grid positions
246  // o2
247  // o4 o5
248  // o7
249  const std::ptrdiff_t o2 = s_jstep;
250  const std::ptrdiff_t o4 = -s_istep;
251  const std::ptrdiff_t o5 = s_istep;
252  const std::ptrdiff_t o7 = -s_jstep;
253 
254  const unsigned ni1 = ni-1;
255  const unsigned nj1 = nj-1;
256 
257  s_data += s_istep + s_jstep;
258  gi_data += gi_jstep;
259  gj_data += gj_jstep;
260 
261  for (unsigned j=1;j<nj1;++j)
262  {
263  const float* s = s_data;
264  float* pgi = gi_data;
265  float* pgj = gj_data;
266 
267  // Zero the first elements in the rows
268  *pgi = 0; pgi+=gi_istep;
269  *pgj = 0; pgj+=gj_istep;
270 
271  for (unsigned i=1;i<ni1;++i)
272  {
273  // Compute gradient in i
274  *pgi = 0.5f*(s[o5]-s[o4]);
275  // Compute gradient in j
276  *pgj = 0.5f*(s[o2]-s[o7]);
277 
278  s+=s_istep;
279  pgi += gi_istep;
280  pgj += gj_istep;
281  }
282 
283  // Zero the last elements in the rows
284  *pgi = 0;
285  *pgj = 0;
286 
287  // Move to next row
288  s_data += s_jstep;
289  gi_data += gi_jstep;
290  gj_data += gj_jstep;
291  }
292 
293  // Zero the first and last rows
294  for (unsigned i=0;i<ni;++i)
295  {
296  *gi=0; gi+=gi_istep;
297  *gj=0; gj+=gj_istep;
298  *gi_data = 0; gi_data+=gi_istep;
299  *gj_data = 0; gj_data+=gj_istep;
300  }
301 }
302 
303 //: Compute gradients of single plane of 2D data using 1x3 Sobel filters
304 // Computes both x and j gradients of an nx x nj plane of data
305 template <>
306 void vil_sobel_1x3_1plane(const double* src,
307  std::ptrdiff_t s_istep, std::ptrdiff_t s_jstep,
308  double* gi, std::ptrdiff_t gi_istep, std::ptrdiff_t gi_jstep,
309  double* gj, std::ptrdiff_t gj_istep, std::ptrdiff_t gj_jstep,
310  unsigned ni, unsigned nj)
311 {
312  const double* s_data = src;
313  double *gi_data = gi;
314  double *gj_data = gj;
315 
316  if (ni==0 || nj==0) return;
317  if (ni==1)
318  {
319  // Zero the elements in the column
320  for (unsigned j=0;j<nj;++j)
321  {
322  *gi_data = 0;
323  *gj_data = 0;
324  gi_data += gi_jstep;
325  gj_data += gj_jstep;
326  }
327  return;
328  }
329  if (nj==1)
330  {
331  // Zero the elements in the column
332  for (unsigned i=0;i<ni;++i)
333  {
334  *gi_data = 0;
335  *gj_data = 0;
336  gi_data += gi_istep;
337  gj_data += gj_istep;
338  }
339  return;
340  }
341 
342  // Compute relative grid positions
343  // o2
344  // o4 o5
345  // o7
346  const std::ptrdiff_t o2 = s_jstep;
347  const std::ptrdiff_t o4 = -s_istep;
348  const std::ptrdiff_t o5 = s_istep;
349  const std::ptrdiff_t o7 = -s_jstep;
350 
351  const unsigned ni1 = ni-1;
352  const unsigned nj1 = nj-1;
353 
354  s_data += s_istep + s_jstep;
355  gi_data += gi_jstep;
356  gj_data += gj_jstep;
357 
358  for (unsigned j=1;j<nj1;++j)
359  {
360  const double* s = s_data;
361  double* pgi = gi_data;
362  double* pgj = gj_data;
363 
364  // Zero the first elements in the rows
365  *pgi = 0; pgi+=gi_istep;
366  *pgj = 0; pgj+=gj_istep;
367 
368  for (unsigned i=1;i<ni1;++i)
369  {
370  // Compute gradient in i
371  *pgi = 0.5*(s[o5]-s[o4]);
372  // Compute gradient in j
373  *pgj = 0.5*(s[o2]-s[o7]);
374 
375  s+=s_istep;
376  pgi += gi_istep;
377  pgj += gj_istep;
378  }
379 
380  // Zero the last elements in the rows
381  *pgi = 0;
382  *pgj = 0;
383 
384  // Move to next row
385  s_data += s_jstep;
386  gi_data += gi_jstep;
387  gj_data += gj_jstep;
388  }
389 
390  // Zero the first and last rows
391  for (unsigned i=0;i<ni;++i)
392  {
393  *gi=0; gi+=gi_istep;
394  *gj=0; gj+=gj_istep;
395  *gi_data = 0; gi_data+=gi_istep;
396  *gj_data = 0; gj_data+=gj_istep;
397  }
398 }
void vil_sobel_1x3_1plane(const unsigned char *src, std::ptrdiff_t s_istep, std::ptrdiff_t s_jstep, float *gi, std::ptrdiff_t gi_istep, std::ptrdiff_t gi_jstep, float *gj, std::ptrdiff_t gj_istep, std::ptrdiff_t gj_jstep, unsigned ni, unsigned nj)
Compute gradients of single plane of 2D data using 1x3 Sobel filters.
Apply 1x3 sobel operator to image data.