JeVoisBase  1.22
JeVois Smart Embedded Machine Vision Toolkit Base Modules
Share this page:
Loading...
Searching...
No Matches
env_channel.c
Go to the documentation of this file.
1/*!@file 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. */
49static 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// ######################################################################
72static 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// ######################################################################
92static 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// ######################################################################
124void 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// ######################################################################
208void 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// ######################################################################
218void 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
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// ######################################################################
269void 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// ######################################################################
313void 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// ######################################################################
339void 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// ######################################################################
404void 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// ######################################################################
442void 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// ######################################################################
472void 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
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_c_image_div_scalar(const intg32 *const a, const env_size_t sz, intg32 val, intg32 *const dst)
result = a / val
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.
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.
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.
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.
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.
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.
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.
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.
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)
void() env_chan_status_func(void *userdata, const char *tagName, const struct env_image *img)
Definition env_channel.h:55
void env_img_swap(struct env_image *img1, struct env_image *img2)
Definition env_image.c:48
void env_img_resize_dims(struct env_image *img, const struct env_dims d)
Definition env_image.c:64
#define env_img_initializer
Definition env_image.h:49
void env_img_make_empty(struct env_image *img)
Definition env_image.c:56
void env_img_init(struct env_image *img, const struct env_dims d)
Definition env_image.c:41
#define INTMAXNORMMAX
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.
void env_rescale(const struct env_image *src, struct env_image *result)
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 *result)
void env_pyr_build_hipass_9(const struct env_image *image, env_size_t firstlevel, const struct env_math *imath, struct env_pyr *result)
#define INTMAXNORMMIN
void env_center_surround(const struct env_image *center, const struct env_image *surround, const int absol, struct env_image *result)
void env_downsize_9_inplace(struct env_image *src, const env_size_t depth, const struct env_math *imath)
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.
void env_max_normalize_inplace(struct env_image *src, intg32 min, intg32 max, enum env_maxnorm_type typ, const intg32 rangeThresh)
#define ENV_ASSERT(expr)
Definition env_log.h:63
#define ENV_TRIG_TABSIZ
Definition env_math.h:44
#define ENV_TRIG_NBITS
Definition env_math.h:45
env_size_t env_max_cs_index(const struct env_params *envp)
Definition env_params.c:73
env_size_t env_max_pyr_depth(const struct env_params *envp)
Definition env_params.c:79
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
#define env_pyr_initializer
Definition env_pyr.h:51
void env_pyr_make_empty(struct env_pyr *dst)
Definition env_pyr.c:51
#define ENV_MAX(a, b)
Definition env_types.h:93
ENV_INTG32_TYPE intg32
32-bit signed integer
Definition env_types.h:52
unsigned long env_size_t
Definition env_types.h:71
result
Definition demo.py:74
A simple struct to hold a pair of width/height dimensions.
Definition env_types.h:81
env_size_t w
The width.
Definition env_types.h:82
env_size_t h
The height.
Definition env_types.h:83
Basic image class.
Definition env_image.h:44
struct env_dims dims
Definition env_image.h:45
const intg16 * costab
Definition env_math.h:52
const intg16 * sintab
Definition env_math.h:51
env_size_t nbits
Definition env_math.h:49
void * user_data_postnorm
Definition env_params.h:81
env_size_t cs_del_max
Definition env_params.h:57
void * user_data_preproc
Definition env_params.h:80
int(* submapPostProc)(const char *tagName, struct env_image *cmap, void *user_data)
Definition env_params.h:77
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
env_size_t cs_del_min
Definition env_params.h:56
intg32 range_thresh
Definition env_params.h:47
env_size_t output_map_level
the pyramid level at which the feature map is taken
Definition env_params.h:58
void * user_data_postproc
Definition env_params.h:82
env_size_t scale_bits
Definition env_params.h:48
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
enum env_maxnorm_type maxnorm_type
Definition env_params.h:46
env_size_t cs_lev_min
Definition env_params.h:54
env_size_t cs_lev_max
Definition env_params.h:55
byte flicker_thresh
Definition env_params.h:51
byte motion_thresh
Definition env_params.h:50
env_size_t num_orientations
number of Gabor subchannels
Definition env_params.h:53
This class implements a set of images, often used as a dyadic pyramid.
Definition env_pyr.h:46
env_size_t depth
Definition env_pyr.h:48
RGB pixel class.
Definition env_types.h:75