JeVoisBase  1.3
JeVois Smart Embedded Machine Vision Toolkit Base Modules
Share this page:
env_channel.c
Go to the documentation of this file.
1 /*!@file Envision/env_channel.c Base class for channels that will use integer math */
2 
3 // //////////////////////////////////////////////////////////////////// //
4 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005 //
5 // by the University of Southern California (USC) and the iLab at USC. //
6 // See http://iLab.usc.edu for information about this project. //
7 // //////////////////////////////////////////////////////////////////// //
8 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
9 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
10 // in Visual Environments, and Applications'' by Christof Koch and //
11 // Laurent Itti, California Institute of Technology, 2001 (patent //
12 // pending; application number 09/912,225 filed July 23, 2001; see //
13 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). //
14 // //////////////////////////////////////////////////////////////////// //
15 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. //
16 // //
17 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can //
18 // redistribute it and/or modify it under the terms of the GNU General //
19 // Public License as published by the Free Software Foundation; either //
20 // version 2 of the License, or (at your option) any later version. //
21 // //
22 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope //
23 // that it will be useful, but WITHOUT ANY WARRANTY; without even the //
24 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //
25 // PURPOSE. See the GNU General Public License for more details. //
26 // //
27 // You should have received a copy of the GNU General Public License //
28 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write //
29 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, //
30 // Boston, MA 02111-1307 USA. //
31 // //////////////////////////////////////////////////////////////////// //
32 //
33 // Primary maintainer for this file: Rob Peters <rjpeters at usc dot edu>
34 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Envision/env_channel.c $
35 // $Id: env_channel.c 9830 2008-06-18 18:50:22Z lior $
36 //
37 
39 
44 
45 #ifndef ENV_NO_DEBUG
46 
47 //! Check whether the pyramid is dyadic.
48 /*! A dyadic pyramid is one in which each level is one half the width and one half the height of the preceding level. */
49 static int is_dyadic(const struct env_pyr* pyr, const env_size_t first, const env_size_t last)
50 {
51  if (first == last) return 0;
52 
53  for (env_size_t i = first + 1; i < last; ++i)
54  {
55  const struct env_dims prevdims = env_pyr_img(pyr, i-1)->dims;
56  const struct env_dims curdims = env_pyr_img(pyr, i)->dims;
57 
58  // make sure we don't go below 1
59  const env_size_t pw2 = ENV_MAX(prevdims.w/2,((env_size_t) 1));
60  const env_size_t ph2 = ENV_MAX(prevdims.h/2,((env_size_t) 1));
61 
62  if (curdims.w != pw2) return 0;
63  if (curdims.h != ph2) return 0;
64  }
65 
66  return 1;
67 }
68 
69 #endif
70 
71 // ######################################################################
72 static void abs_diff_thresh(const struct env_image* b, const struct env_image* c,
73  const intg32 thresh, struct env_image* result)
74 {
75  ENV_ASSERT(env_dims_equal(b->dims, c->dims));
76  ENV_ASSERT(env_dims_equal(b->dims, result->dims));
77 
78  const intg32* const bptr = env_img_pixels(b);
79  const intg32* const cptr = env_img_pixels(c);
80  intg32* const dptr = env_img_pixelsw(result);
81 
82  const env_size_t sz = env_img_size(b);
83 
84  for (env_size_t i = 0; i < sz; ++i)
85  {
86  dptr[i] = (bptr[i] < cptr[i]) ? cptr[i] - bptr[i] : bptr[i] - cptr[i];
87  if (dptr[i] < thresh) dptr[i] = 0;
88  }
89 }
90 
91 // ######################################################################
92 static void abs_diff_thresh_pyr(const struct env_pyr* b, const struct env_pyr* c,
93  const intg32 thresh, struct env_pyr* result)
94 {
95  ENV_ASSERT(env_pyr_depth(b) == env_pyr_depth(c));
96  ENV_ASSERT(env_pyr_depth(c) == env_pyr_depth(result));
97 
98  const env_size_t n = env_pyr_depth(b);
99 
100  if (env_pyr_depth(result) != n)
101  {
102  env_pyr_make_empty(result);
103  env_pyr_init(result, n);
104  }
105 
106  for (env_size_t i = 0; i < n; ++i)
107  {
108  const struct env_image* bimg = env_pyr_img(b, i);
109 
110  if (!env_img_initialized(bimg)) continue;
111 
112  // else...
113 
114  const struct env_image* cimg = env_pyr_img(c, i);
115  struct env_image* rimg = env_pyr_imgw(result, i);
116 
117  env_img_resize_dims(rimg, bimg->dims);
118 
119  abs_diff_thresh(bimg, cimg, thresh, rimg);
120  }
121 }
122 
123 // ######################################################################
124 void env_chan_process_pyr(const char* tagName, const struct env_dims inputDims, const struct env_pyr* pyr,
125  const struct env_params* envp, const struct env_math* imath, const int takeAbs,
126  const int normalizeOutput, struct env_image* result)
127 {
128  const struct env_dims mapDims =
129  { ENV_MAX(inputDims.w / (1 << envp->output_map_level), 1),
130  ENV_MAX(inputDims.h / (1 << envp->output_map_level), 1) };
131 
132  if (env_pyr_depth(pyr) == 0)
133  // OK, our pyramid wasn't ready to give us any output yet, so just return an empty output image:
134  {
135  env_img_make_empty(result);
136  return;
137  }
138 
139  // We only want dyadic pyramids here:
140  ENV_ASSERT(is_dyadic(pyr, envp->cs_lev_min, env_max_pyr_depth(envp)));
141 
142  env_img_resize_dims(result, mapDims);
143 
144  {
145  const env_size_t mapSize = mapDims.w * mapDims.h;
146  intg32* const rptr = env_img_pixelsw(result);
147  for (env_size_t i = 0; i < mapSize; ++i)
148  rptr[i] = 0;
149  }
150 
151  // compute max-normalized weighted sum of center-surround at all levels:
152  for (env_size_t clev = envp->cs_lev_min; clev <= envp->cs_lev_max; ++clev)
153  for (env_size_t delta = envp->cs_del_min; delta <= envp->cs_del_max; ++delta)
154  {
155  const env_size_t slev = clev + delta;
156 
157  // submap is computed from a center-surround difference:
158  struct env_image submap;
159  env_img_init(&submap, env_pyr_img(pyr, clev)->dims);
160  env_center_surround(env_pyr_img(pyr, clev), env_pyr_img(pyr, slev), takeAbs, &submap);
161 
162  if (envp->submapPreProc != 0)
163  (*envp->submapPreProc)(tagName, clev, slev, &submap, env_pyr_img(pyr, clev), env_pyr_img(pyr, slev),
164  envp->user_data_preproc );
165 
166  // resize submap to fixed scale if necessary:
167  if (submap.dims.w > mapDims.w || submap.dims.h > mapDims.h)
168  {
169  // how many levels to we need to downscale the current submap to get to the output map resolution?
170  const env_size_t n = envp->output_map_level - clev;
171 
172  env_downsize_9_inplace(&submap, n, imath);
173  }
174  else if (submap.dims.w < mapDims.w || submap.dims.h < mapDims.h)
175  {
176  struct env_image tmp;
177  env_img_init(&tmp, mapDims);
178  env_rescale(&submap, &tmp);
179  env_img_swap(&submap, &tmp);
180  }
181 
182  // make sure that the resizing came out precisely:
183  ENV_ASSERT(env_dims_equal(submap.dims, mapDims));
184 
185  // first normalize the submap to a fixed dynamic range and then apply spatial competition for salience to the
186  // submap:
188 
189  if (envp->submapPostNormProc != 0)
190  (*envp->submapPostNormProc)(tagName, clev, slev, &submap, env_pyr_img(pyr, clev), env_pyr_img(pyr, slev),
191  envp->user_data_postnorm);
192 
193  // add submap to our sum
194  env_c_image_div_scalar_accum(env_img_pixels(&submap), env_img_size(&submap), (intg32) env_max_cs_index(envp),
195  env_img_pixelsw(result));
196 
197  env_img_make_empty(&submap);
198  }
199 
200  if (envp->submapPostProc != 0) (*envp->submapPostProc)(tagName, result, envp->user_data_postproc);
201 
202  // apply max-normalization on the result as needed:
203  if (normalizeOutput)
205 }
206 
207 // ######################################################################
208 void env_chan_intensity(const char* tagName, const struct env_params* envp, const struct env_math* imath,
209  const struct env_dims inputdims, const struct env_pyr* lowpass5, const int normalizeOutput,
210  env_chan_status_func* status_func, void* status_userdata, struct env_image* result)
211 {
212  env_chan_process_pyr(tagName, inputdims, lowpass5, envp, imath, 1 /* takeAbs */, normalizeOutput, result);
213 
214  if (status_func) (*status_func)(status_userdata, tagName, result);
215 }
216 
217 // ######################################################################
218 void env_chan_color(const char* tagName, const struct env_params* envp, const struct env_math* imath,
219  const struct env_rgb_pixel* const colimg,
220  const struct env_dims dims, env_chan_status_func* status_func, void* status_userdata,
221  struct env_image* result)
222 {
223  struct env_image rg; env_img_init(&rg, dims);
224  struct env_image by; env_img_init(&by, dims);
225 
226  const intg32 lumthresh = (3*255) / 10;
227  env_get_rgby(colimg, dims.w * dims.h, &rg, &by, lumthresh, imath->nbits);
228 
229  const env_size_t firstlevel = envp->cs_lev_min;
230  const env_size_t depth = env_max_pyr_depth(envp);
231 
232  {
233  struct env_pyr rgpyr;
234  env_pyr_init(&rgpyr, depth);
235  env_pyr_build_lowpass_5(&rg, firstlevel, imath, &rgpyr);
236 
237  env_chan_intensity("red/green", envp, imath, rg.dims, &rgpyr, 0, status_func, status_userdata, result);
238 
239  env_pyr_make_empty(&rgpyr);
240  }
241 
242  struct env_image byOut = env_img_initializer;
243 
244  {
245  struct env_pyr bypyr;
246  env_pyr_init(&bypyr, depth);
247  env_pyr_build_lowpass_5(&by, firstlevel, imath, &bypyr);
248 
249  env_chan_intensity("blue/yellow", envp, imath, by.dims, &bypyr, 0, status_func, status_userdata, &byOut);
250  env_pyr_make_empty(&bypyr);
251  }
252 
253  env_img_make_empty(&rg);
254  env_img_make_empty(&by);
255 
256  const intg32* const byptr = env_img_pixels(&byOut);
257  intg32* const dptr = env_img_pixelsw(result);
258  const env_size_t sz = env_img_size(result);
259 
260  for (env_size_t i = 0; i < sz; ++i) dptr[i] = (dptr[i] / 2) + (byptr[i] / 2);
261 
263  if (status_func) (*status_func)(status_userdata, tagName, result);
264 
265  env_img_make_empty(&byOut);
266 }
267 
268 // ######################################################################
269 void env_chan_color_rgby(const char* tagName, const struct env_params* envp, const struct env_math* imath,
270  const struct env_image *rg, const struct env_image *by,
271  env_chan_status_func* status_func, void* status_userdata,
272  struct env_image* result)
273 {
274  ENV_ASSERT(env_dims_equal(rg->dims, by->dims));
275 
276  const env_size_t firstlevel = envp->cs_lev_min;
277  const env_size_t depth = env_max_pyr_depth(envp);
278 
279  {
280  struct env_pyr rgpyr;
281  env_pyr_init(&rgpyr, depth);
282  env_pyr_build_lowpass_5(rg, firstlevel, imath, &rgpyr);
283 
284  env_chan_intensity("red/green", envp, imath, rg->dims, &rgpyr, 0, status_func, status_userdata, result);
285 
286  env_pyr_make_empty(&rgpyr);
287  }
288 
289  struct env_image byOut = env_img_initializer;
290 
291  {
292  struct env_pyr bypyr;
293  env_pyr_init(&bypyr, depth);
294  env_pyr_build_lowpass_5(by, firstlevel, imath, &bypyr);
295 
296  env_chan_intensity("blue/yellow", envp, imath, by->dims, &bypyr, 0, status_func, status_userdata, &byOut);
297  env_pyr_make_empty(&bypyr);
298  }
299 
300  const intg32* const byptr = env_img_pixels(&byOut);
301  intg32* const dptr = env_img_pixelsw(result);
302  const env_size_t sz = env_img_size(result);
303 
304  for (env_size_t i = 0; i < sz; ++i) dptr[i] = (dptr[i] + byptr[i]) >> 1;
305 
307  if (status_func) (*status_func)(status_userdata, tagName, result);
308 
309  env_img_make_empty(&byOut);
310 }
311 
312 // ######################################################################
313 void env_chan_steerable(const char* tagName, const struct env_params* envp, const struct env_math* imath,
314  const struct env_dims inputdims, const struct env_pyr* hipass9, const env_size_t thetaidx,
315  env_chan_status_func* status_func, void* status_userdata, struct env_image* result)
316 {
317  const env_size_t kdenombits = ENV_TRIG_NBITS;
318 
319  // spatial_freq = 2.6 / (2*pi) ~= 0.41380285203892792 ~= 2069/5000
320 
321  const intg32 sfnumer = 2069;
322  const intg32 sfdenom = 5000;
323 
324  const intg32 kxnumer = ((intg32) (sfnumer * imath->costab[thetaidx] * ENV_TRIG_TABSIZ)) / sfdenom;
325  const intg32 kynumer = ((intg32) (sfnumer * imath->sintab[thetaidx] * ENV_TRIG_TABSIZ)) / sfdenom;
326 
327  // Compute our pyramid:
328  struct env_pyr pyr = env_pyr_initializer;
329  env_pyr_build_steerable_from_hipass_9(hipass9, kxnumer, kynumer, kdenombits, imath, &pyr);
330 
331  env_chan_process_pyr(tagName, inputdims, &pyr, envp, imath, 0 /* takeAbs */, 1 /* normalizeOutput */, result);
332 
333  if (status_func) (*status_func)(status_userdata, tagName, result);
334 
335  env_pyr_make_empty(&pyr);
336 }
337 
338 // ######################################################################
339 void env_chan_orientation(const char* tagName, const struct env_params* envp, const struct env_math* imath,
340  const struct env_image* img, env_chan_status_func* status_func,
341  void* status_userdata, struct env_image* result)
342 {
343  env_img_make_empty(result);
344 
345  if (envp->num_orientations == 0) return;
346 
347  struct env_pyr hipass9;
348  env_pyr_init(&hipass9, env_max_pyr_depth(envp));
349  env_pyr_build_hipass_9(img, envp->cs_lev_min, imath, &hipass9);
350 
351  struct env_image chanOut = env_img_initializer;
352 
353  char buf[17] =
354  {
355  's', 't', 'e', 'e', 'r', 'a', 'b', 'l', 'e', // 0--8
356  '(', '_', '_', // 9--11
357  '/', '_', '_', ')', '\0' // 12--16
358  };
359 
360  ENV_ASSERT(envp->num_orientations <= 99);
361 
362  buf[13] = '0' + (envp->num_orientations / 10);
363  buf[14] = '0' + (envp->num_orientations % 10);
364 
365  for (env_size_t i = 0; i < envp->num_orientations; ++i)
366  {
367  // theta = (180.0 * i) / envp->num_orientations + 90.0, where ENV_TRIG_TABSIZ is equivalent to 360.0 or 2*pi
368  const env_size_t thetaidx = (ENV_TRIG_TABSIZ * i) / (2 * envp->num_orientations) + (ENV_TRIG_TABSIZ / 4);
369 
370  ENV_ASSERT(thetaidx < ENV_TRIG_TABSIZ);
371 
372  buf[10] = '0' + ((i+1) / 10);
373  buf[11] = '0' + ((i+1) % 10);
374 
375  env_chan_steerable(buf, envp, imath, img->dims, &hipass9, thetaidx, status_func, status_userdata, &chanOut);
376 
377  ENV_ASSERT(env_img_initialized(&chanOut));
378 
379  if (!env_img_initialized(result))
380  {
381  env_img_resize_dims(result, chanOut.dims);
382  env_c_image_div_scalar(env_img_pixels(&chanOut), env_img_size(&chanOut), (intg32) envp->num_orientations,
383  env_img_pixelsw(result));
384  }
385  else
386  {
387  ENV_ASSERT(env_dims_equal(chanOut.dims, result->dims));
388  env_c_image_div_scalar_accum(env_img_pixels(&chanOut), env_img_size(&chanOut),
389  (intg32) envp->num_orientations, env_img_pixelsw(result));
390  }
391  }
392 
393  env_img_make_empty(&chanOut);
394  env_pyr_make_empty(&hipass9);
395 
396  ENV_ASSERT(env_img_initialized(result));
397 
399 
400  if (status_func) (*status_func)(status_userdata, tagName, result);
401 }
402 
403 // ######################################################################
404 void env_chan_flicker(const char* tagName, const struct env_params* envp, const struct env_math* imath,
405  const struct env_image* prev, const struct env_image* cur, env_chan_status_func* status_func,
406  void* status_userdata, struct env_image* result)
407 {
408  // If this is the first time the flicker channel has seen input, then prev will be uninitialized; obviously we can't
409  // compute any flicker with only one frame, so we just store the current input as the next iteration's previous input
410  if (!env_img_initialized(prev))
411  {
412  env_img_make_empty(result);
413  }
414  else
415  {
416  const intg32 lowthresh = (envp->scale_bits > 8) ? (envp->flicker_thresh << (envp->scale_bits - 8))
417  : (envp->flicker_thresh >> (8 - envp->scale_bits));
418 
419  // take thresholded abs difference between current and previous frame:
420  struct env_image fli;
421  env_img_init(&fli, prev->dims);
422  abs_diff_thresh(cur, prev, lowthresh, &fli);
423 
424  const env_size_t firstlevel = envp->cs_lev_min;
425  const env_size_t depth = env_max_pyr_depth(envp);
426 
427  // Compute our pyramid:
428  struct env_pyr pyr;
429  env_pyr_init(&pyr, depth);
430  env_pyr_build_lowpass_5(&fli, firstlevel, imath, &pyr);
431 
432  env_chan_process_pyr(tagName, fli.dims, &pyr, envp, imath, 1 /* takeAbs */, 1 /* normalizeOutput */, result);
433 
434  if (status_func) (*status_func)(status_userdata, tagName, result);
435 
436  env_img_make_empty(&fli);
437  env_pyr_make_empty(&pyr);
438  }
439 }
440 
441 // ######################################################################
442 void env_chan_msflicker(const char* tagName, const struct env_params* envp, const struct env_math* imath,
443  const struct env_dims inputDims, const struct env_pyr* prev_lowpass5,
444  const struct env_pyr* cur_lowpass5, env_chan_status_func* status_func,
445  void* status_userdata, struct env_image* result)
446 {
447  // If this is the first time the flicker channel has seen input, then prev will be uninitialized; obviously we can't
448  // compute any flicker with only one frame, so we just store the current input as the next iteration's previous input
449  if (env_pyr_depth(prev_lowpass5) == 0)
450  {
451  env_img_make_empty(result);
452  }
453  else
454  {
455  const intg32 lowthresh = (envp->scale_bits > 8) ? (envp->flicker_thresh << (envp->scale_bits - 8))
456  : (envp->flicker_thresh >> (8 - envp->scale_bits));
457 
458  // take thresholded abs difference between current and previous frame:
459  struct env_pyr fli;
460  env_pyr_init(&fli, env_pyr_depth(cur_lowpass5));
461  abs_diff_thresh_pyr(cur_lowpass5, prev_lowpass5, lowthresh, &fli);
462 
463  env_chan_process_pyr(tagName, inputDims, &fli, envp, imath, 1 /* takeAbs */, 1 /* normalizeOutput */, result);
464 
465  if (status_func) (*status_func)(status_userdata, tagName, result);
466 
467  env_pyr_make_empty(&fli);
468  }
469 }
470 
471 // ######################################################################
472 void env_chan_direction(const char* tagName, const struct env_params* envp, const struct env_math* imath,
473  const struct env_dims inputdims, const struct env_pyr* unshiftedPrev,
474  const struct env_pyr* unshiftedCur, const struct env_pyr* shiftedPrev,
475  const struct env_pyr* shiftedCur, env_chan_status_func* status_func,
476  void* status_userdata, struct env_image* result)
477 {
478  const env_size_t firstlevel = envp->cs_lev_min;
479  const env_size_t depth = env_max_pyr_depth(envp);
480 
481  const env_size_t nshift = (imath->nbits+1)/2;
482 
483  if (env_pyr_depth(unshiftedPrev) == 0)
484  {
485  // it's our first time, so just return an empty image:
486  env_img_make_empty(result);
487  }
488  else
489  {
490  struct env_pyr pyr;
491  env_pyr_init(&pyr, depth);
492 
493  const intg32 lowthresh = (envp->scale_bits > 8) ? (envp->motion_thresh << (envp->scale_bits - 8))
494  : (envp->motion_thresh >> (8 - envp->scale_bits));
495 
496  // compute the Reichardt maps
497  for (env_size_t i = firstlevel; i < depth; i++)
498  {
499  env_img_resize_dims(env_pyr_imgw(&pyr, i), env_pyr_img(unshiftedCur, i)->dims);
500 
501  const intg32* const ucurr = env_img_pixels(env_pyr_img(unshiftedCur, i));
502  const intg32* const uprev = env_img_pixels(env_pyr_img(unshiftedPrev, i));
503  const intg32* const scurr = env_img_pixels(env_pyr_img(shiftedCur, i));
504  const intg32* const sprev = env_img_pixels(env_pyr_img(shiftedPrev, i));
505  intg32* const dptr = env_img_pixelsw(env_pyr_imgw(&pyr, i));
506 
507  const env_size_t sz = env_img_size(env_pyr_img(&pyr, i));
508 
509  for (env_size_t c = 0; c < sz; ++c)
510  {
511  dptr[c] = ((ucurr[c] >> nshift) * (sprev[c] >> nshift)) - ((uprev[c] >> nshift) * (scurr[c] >> nshift));
512 
513  if (dptr[c] < lowthresh) dptr[c] = 0;
514  }
515  }
516 
517  env_chan_process_pyr(tagName, inputdims, &pyr, envp, imath, 1 /* takeAbs */, 1 /* normalizeOutput */, result);
518 
519  if (status_func) (*status_func)(status_userdata, tagName, result);
520 
521  env_pyr_make_empty(&pyr);
522  }
523 }
524 
#define ENV_MAX(a, b)
Definition: env_types.h:93
int(* submapPreProc)(const char *tagName, env_size_t clev, env_size_t slev, struct env_image *submap, const struct env_image *center, const struct env_image *surround, void *user_data)
Definition: env_params.h:65
void env_rescale(const struct env_image *src, struct env_image *result)
#define INTMAXNORMMIN
Definition: env_image_ops.h:47
env_size_t w
The width.
Definition: env_types.h:82
void * user_data_preproc
Definition: env_params.h:80
const intg16 * sintab
Definition: env_math.h:51
env_size_t scale_bits
Definition: env_params.h:48
env_size_t cs_lev_min
Definition: env_params.h:54
void env_chan_process_pyr(const char *tagName, const struct env_dims inputDims, const struct env_pyr *pyr, const struct env_params *envp, const struct env_math *imath, const int takeAbs, const int normalizeOutput, struct env_image *result)
Definition: env_channel.c:124
void env_pyr_build_hipass_9(const struct env_image *image, env_size_t firstlevel, const struct env_math *imath, struct env_pyr *result)
void env_img_make_empty(struct env_image *img)
Definition: env_image.c:56
void env_img_swap(struct env_image *img1, struct env_image *img2)
Definition: env_image.c:48
byte flicker_thresh
Definition: env_params.h:51
void * user_data_postnorm
Definition: env_params.h:81
env_size_t cs_del_min
Definition: env_params.h:56
Basic image class.
Definition: env_image.h:43
#define ENV_TRIG_TABSIZ
Definition: env_math.h:44
env_size_t env_max_cs_index(const struct env_params *envp)
Definition: env_params.c:73
#define ENV_TRIG_NBITS
Definition: env_math.h:45
#define env_img_initializer
Definition: env_image.h:49
void env_max_normalize_inplace(struct env_image *src, const intg32 mi, const intg32 ma, const enum env_maxnorm_type normtyp, const intg32 rangeThresh)
void env_pyr_init(struct env_pyr *pyr, const env_size_t n)
Construct with a given number of empty images.
Definition: env_pyr.c:41
void env_c_image_div_scalar_accum(const intg32 *const a, const env_size_t sz, intg32 val, intg32 *const dst)
result += a / val
void env_chan_orientation(const char *tagName, const struct env_params *envp, const struct env_math *imath, const struct env_image *img, env_chan_status_func *status_func, void *status_userdata, struct env_image *result)
A composite channel with a set of steerable-filter subchannels.
Definition: env_channel.c:339
void env_img_init(struct env_image *img, const struct env_dims d)
Definition: env_image.c:41
void env_chan_msflicker(const char *tagName, const struct env_params *envp, const struct env_math *imath, const struct env_dims inputDims, const struct env_pyr *prev_lowpass5, const struct env_pyr *cur_lowpass5, env_chan_status_func *status_func, void *status_userdata, struct env_image *result)
A true multi-scale temporal flicker channel.
Definition: env_channel.c:442
void env_get_rgby(const struct env_rgb_pixel *const src, const env_size_t sz, struct env_image *rg, struct env_image *by, const intg32 thresh, const env_size_t inputbits)
Compute R-G and B-Y opponent color maps.
const intg16 * costab
Definition: env_math.h:52
struct env_dims dims
Definition: env_image.h:45
env_size_t depth
Definition: env_pyr.h:48
void env_chan_color_rgby(const char *tagName, const struct env_params *envp, const struct env_math *imath, const struct env_image *rg, const struct env_image *by, env_chan_status_func *status_func, void *status_userdata, struct env_image *result)
A double opponent color channel that combines r/g, b/y subchannels, with direct RG and BY inputs...
Definition: env_channel.c:269
int(* submapPostProc)(const char *tagName, struct env_image *cmap, void *user_data)
Definition: env_params.h:77
env_size_t h
The height.
Definition: env_types.h:83
void env_chan_color(const char *tagName, const struct env_params *envp, const struct env_math *imath, const struct env_rgb_pixel *const colimg, const struct env_dims dims, env_chan_status_func *status_func, void *status_userdata, struct env_image *result)
A double opponent color channel that combines r/g, b/y subchannels.
Definition: env_channel.c:218
#define INTMAXNORMMAX
Definition: env_image_ops.h:48
unsigned long env_size_t
Definition: env_types.h:71
env_size_t output_map_level
the pyramid level at which the feature map is taken
Definition: env_params.h:58
void env_pyr_make_empty(struct env_pyr *dst)
Definition: env_pyr.c:51
void * user_data_postproc
Definition: env_params.h:82
void env_chan_flicker(const char *tagName, const struct env_params *envp, const struct env_math *imath, const struct env_image *prev, const struct env_image *cur, env_chan_status_func *status_func, void *status_userdata, struct env_image *result)
A temporal flicker channel.
Definition: env_channel.c:404
RGB pixel class.
Definition: env_types.h:74
env_size_t env_max_pyr_depth(const struct env_params *envp)
Definition: env_params.c:79
void env_img_resize_dims(struct env_image *img, const struct env_dims d)
Definition: env_image.c:64
void env_chan_intensity(const char *tagName, const struct env_params *envp, const struct env_math *imath, const struct env_dims inputdims, const struct env_pyr *lowpass5, const int normalizeOutput, env_chan_status_func *status_func, void *status_userdata, struct env_image *result)
An intensity channel.
Definition: env_channel.c:208
ENV_INTG32_TYPE intg32
32-bit signed integer
Definition: env_types.h:52
#define env_pyr_initializer
Definition: env_pyr.h:51
void env_center_surround(const struct env_image *center, const struct env_image *surround, const int absol, struct env_image *result)
int(* submapPostNormProc)(const char *tagName, env_size_t clev, env_size_t slev, struct env_image *submap, const struct env_image *center, const struct env_image *surround, void *user_data)
Definition: env_params.h:71
void env_pyr_build_steerable_from_hipass_9(const struct env_pyr *hipass, const intg32 kxnumer, const intg32 kynumer, const env_size_t kdenombits, const struct env_math *imath, struct env_pyr *out)
void env_chan_steerable(const char *tagName, const struct env_params *envp, const struct env_math *imath, const struct env_dims inputdims, const struct env_pyr *hipass9, const env_size_t thetaidx, env_chan_status_func *status_func, void *status_userdata, struct env_image *result)
An orientation filtering channel.
Definition: env_channel.c:313
enum env_maxnorm_type maxnorm_type
Definition: env_params.h:46
env_size_t num_orientations
number of Gabor subchannels
Definition: env_params.h:53
A simple struct to hold a pair of width/height dimensions.
Definition: env_types.h:80
void env_chan_direction(const char *tagName, const struct env_params *envp, const struct env_math *imath, const struct env_dims inputdims, const struct env_pyr *unshiftedPrev, const struct env_pyr *unshiftedCur, const struct env_pyr *shiftedPrev, const struct env_pyr *shiftedCur, env_chan_status_func *status_func, void *status_userdata, struct env_image *result)
A motion sensitive channel with direction selectivity.
Definition: env_channel.c:472
This class implements a set of images, often used as a dyadic pyramid.
Definition: env_pyr.h:45
void env_pyr_build_lowpass_5(const struct env_image *image, env_size_t firstlevel, const struct env_math *imath, struct env_pyr *result)
Wrapper for _cpu or _cuda version.
intg32 range_thresh
Definition: env_params.h:47
byte motion_thresh
Definition: env_params.h:50
env_size_t nbits
Definition: env_math.h:49
void env_c_image_div_scalar(const intg32 *const a, const env_size_t sz, intg32 val, intg32 *const dst)
result = a / val
void( env_chan_status_func)(void *userdata, const char *tagName, const struct env_image *img)
Definition: env_channel.h:55
#define ENV_ASSERT(expr)
Definition: env_log.h:63
void env_downsize_9_inplace(struct env_image *src, const env_size_t depth, const struct env_math *imath)