00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef ENVISION_ENV_MT_CHANNEL_C_DEFINED
00039 #define ENVISION_ENV_MT_CHANNEL_C_DEFINED
00040
00041 #include "Envision/env_mt_channel.h"
00042
00043 #include "Envision/env_alloc.h"
00044 #include "Envision/env_c_math_ops.h"
00045 #include "Envision/env_image_ops.h"
00046 #include "Envision/env_job_server.h"
00047 #include "Envision/env_log.h"
00048 #include "Envision/env_params.h"
00049
00050
00051 struct env_ori_subjob_data
00052 {
00053 const struct env_params* envp;
00054 const struct env_math* imath;
00055 struct env_dims dims;
00056 const struct env_pyr* hipass9;
00057 env_size_t thetaidx;
00058 env_chan_status_func* status_func;
00059 void* status_userdata;
00060 struct env_image chanOut;
00061 char channame[17];
00062 };
00063
00064 static void env_ori_subjob_run(void* p)
00065 {
00066 struct env_ori_subjob_data* j = (struct env_ori_subjob_data*)(p);
00067
00068 env_chan_steerable
00069 (j->channame, j->envp, j->imath, j->dims,
00070 j->hipass9, j->thetaidx,
00071 j->status_func, j->status_userdata, &j->chanOut);
00072
00073 ENV_ASSERT(env_img_initialized(&j->chanOut));
00074 }
00075
00076
00077 void env_mt_chan_orientation(const char* tagName,
00078 const struct env_params* envp,
00079 const struct env_math* imath,
00080 const struct env_image* img,
00081 env_chan_status_func* status_func,
00082 void* status_userdata,
00083 struct env_image* result)
00084 {
00085 env_img_make_empty(result);
00086
00087 if (envp->num_orientations == 0)
00088 return;
00089
00090 struct env_pyr hipass9;
00091 env_pyr_init(&hipass9, env_max_pyr_depth(envp));
00092 env_pyr_build_hipass_9(img,
00093 envp->cs_lev_min,
00094 imath,
00095 &hipass9);
00096
00097 char buf[17] =
00098 {
00099 's', 't', 'e', 'e', 'r', 'a', 'b', 'l', 'e',
00100 '(', '_', '_',
00101 '/', '_', '_', ')', '\0'
00102 };
00103
00104 ENV_ASSERT(envp->num_orientations <= 99);
00105
00106 buf[13] = '0' + (envp->num_orientations / 10);
00107 buf[14] = '0' + (envp->num_orientations % 10);
00108
00109 struct env_job* jobs =
00110 env_allocate(envp->num_orientations * sizeof(struct env_job));
00111
00112 ENV_ASSERT2(jobs != 0, "env_allocate failed");
00113
00114 struct env_ori_subjob_data* jobdata =
00115 env_allocate(envp->num_orientations
00116 * sizeof(struct env_ori_subjob_data));
00117
00118 ENV_ASSERT2(jobdata != 0, "env_allocate failed");
00119
00120 for (env_size_t i = 0; i < envp->num_orientations; ++i)
00121 {
00122
00123
00124
00125 const env_size_t thetaidx =
00126 (ENV_TRIG_TABSIZ * i)
00127 / (2 * envp->num_orientations)
00128 + (ENV_TRIG_TABSIZ / 4);
00129
00130 ENV_ASSERT(thetaidx < ENV_TRIG_TABSIZ);
00131
00132 buf[10] = '0' + ((i+1) / 10);
00133 buf[11] = '0' + ((i+1) % 10);
00134
00135 jobdata[i].envp = envp;
00136 jobdata[i].imath = imath;
00137 jobdata[i].dims = img->dims;
00138 jobdata[i].hipass9 = &hipass9;
00139 jobdata[i].thetaidx = thetaidx;
00140 jobdata[i].status_func = status_func;
00141 jobdata[i].status_userdata = status_userdata;
00142 env_img_init_empty(&jobdata[i].chanOut);
00143 for (env_size_t c = 0; c < sizeof(buf); ++c)
00144 jobdata[i].channame[c] = buf[c];
00145
00146 jobs[i].callback = &env_ori_subjob_run;
00147 jobs[i].userdata = &jobdata[i];
00148 }
00149
00150 env_run_jobs(&jobs[0], envp->num_orientations);
00151
00152 for (env_size_t i = 0; i < envp->num_orientations; ++i)
00153 {
00154 struct env_image* chanOut = &jobdata[i].chanOut;
00155
00156 if (!env_img_initialized(result))
00157 {
00158 env_img_resize_dims(result, chanOut->dims);
00159 env_c_image_div_scalar
00160 (env_img_pixels(chanOut),
00161 env_img_size(chanOut),
00162 (intg32) envp->num_orientations,
00163 env_img_pixelsw(result));
00164 }
00165 else
00166 {
00167 ENV_ASSERT(env_dims_equal(chanOut->dims,
00168 result->dims));
00169 env_c_image_div_scalar_accum
00170 (env_img_pixels(chanOut),
00171 env_img_size(chanOut),
00172 (intg32) envp->num_orientations,
00173 env_img_pixelsw(result));
00174 }
00175
00176 env_img_make_empty(chanOut);
00177 }
00178
00179 env_pyr_make_empty(&hipass9);
00180
00181 ENV_ASSERT(env_img_initialized(result));
00182
00183 env_max_normalize_inplace(result, INTMAXNORMMIN, INTMAXNORMMAX,
00184 envp->maxnorm_type,
00185 envp->range_thresh);
00186
00187 if (status_func)
00188 (*status_func)(status_userdata, tagName, result);
00189
00190 env_deallocate(jobdata);
00191 env_deallocate(jobs);
00192 }
00193
00194
00195 struct env_direction_job_data
00196 {
00197 const struct env_motion_channel* chan;
00198 env_size_t dir;
00199 const struct env_params* envp;
00200 const struct env_math* imath;
00201 struct env_dims inputdims;
00202 const struct env_pyr* unshiftedCur;
00203 env_chan_status_func* status_func;
00204 void* status_userdata;
00205 struct env_image chanOut;
00206 char channame[17];
00207 };
00208
00209 static void env_direction_job_run(void* p)
00210 {
00211 struct env_direction_job_data* j = (struct env_direction_job_data*)(p);
00212
00213 const env_size_t firstlevel = j->envp->cs_lev_min;
00214 const env_size_t depth = env_max_pyr_depth(j->envp);
00215
00216
00217 const env_size_t thetaidx =
00218 (j->dir * ENV_TRIG_TABSIZ) / j->chan->num_directions;
00219
00220 ENV_ASSERT(thetaidx < ENV_TRIG_TABSIZ);
00221
00222
00223 struct env_pyr shiftedCur;
00224 env_pyr_init(&shiftedCur, depth);
00225
00226
00227 for (env_size_t i = firstlevel; i < depth; ++i)
00228 {
00229 env_img_resize_dims(env_pyr_imgw(&shiftedCur, i),
00230 env_pyr_img(j->unshiftedCur, i)->dims);
00231 env_shift_image(env_pyr_img(j->unshiftedCur, i),
00232 j->imath->costab[thetaidx],
00233 -j->imath->sintab[thetaidx],
00234 ENV_TRIG_NBITS,
00235 env_pyr_imgw(&shiftedCur, i));
00236 }
00237
00238 env_chan_direction(j->channame, j->envp, j->imath,
00239 j->inputdims,
00240 &j->chan->unshifted_prev, j->unshiftedCur,
00241 &j->chan->shifted_prev[j->dir], &shiftedCur,
00242 j->status_func, j->status_userdata, &j->chanOut);
00243
00244 env_pyr_swap(&j->chan->shifted_prev[j->dir], &shiftedCur);
00245 env_pyr_make_empty(&shiftedCur);
00246 }
00247
00248
00249 void env_mt_motion_channel_input_and_consume_pyr(
00250 struct env_motion_channel* chan,
00251 const char* tagName,
00252 const struct env_params* envp,
00253 const struct env_math* imath,
00254 const struct env_dims inputdims,
00255 struct env_pyr* unshiftedCur,
00256 env_chan_status_func* status_func,
00257 void* status_userdata,
00258 struct env_image* result)
00259 {
00260 env_img_make_empty(result);
00261
00262 if (chan->num_directions != envp->num_motion_directions)
00263 {
00264 env_motion_channel_destroy(chan);
00265 env_motion_channel_init(chan, envp);
00266 }
00267
00268 if (chan->num_directions == 0)
00269 return;
00270
00271 char buf[17] =
00272 {
00273 'r', 'e', 'i', 'c', 'h', 'a', 'r', 'd', 't',
00274 '(', '_', '_',
00275 '/', '_', '_', ')', '\0'
00276 };
00277
00278 ENV_ASSERT(chan->num_directions <= 99);
00279
00280 buf[13] = '0' + (chan->num_directions / 10);
00281 buf[14] = '0' + (chan->num_directions % 10);
00282
00283 struct env_job* jobs =
00284 env_allocate(chan->num_directions * sizeof(struct env_job));
00285
00286 ENV_ASSERT2(jobs != 0, "env_allocate failed");
00287
00288 struct env_direction_job_data* jobdata =
00289 env_allocate(chan->num_directions
00290 * sizeof(struct env_direction_job_data));
00291
00292 ENV_ASSERT2(jobdata != 0, "env_allocate failed");
00293
00294
00295 for (env_size_t dir = 0; dir < chan->num_directions; ++dir)
00296 {
00297 buf[10] = '0' + ((dir+1) / 10);
00298 buf[11] = '0' + ((dir+1) % 10);
00299
00300 jobdata[dir].chan = chan;
00301 jobdata[dir].dir = dir;
00302 jobdata[dir].envp = envp;
00303 jobdata[dir].imath = imath;
00304 jobdata[dir].inputdims = inputdims;
00305 jobdata[dir].unshiftedCur = unshiftedCur;
00306 jobdata[dir].status_func = status_func;
00307 jobdata[dir].status_userdata = status_userdata;
00308 env_img_init_empty(&jobdata[dir].chanOut);
00309 for (env_size_t c = 0; c < sizeof(buf); ++c)
00310 jobdata[dir].channame[c] = buf[c];
00311
00312 jobs[dir].callback = &env_direction_job_run;
00313 jobs[dir].userdata = &jobdata[dir];
00314 }
00315
00316 env_run_jobs(&jobs[0], chan->num_directions);
00317
00318 for (env_size_t dir = 0; dir < chan->num_directions; ++dir)
00319 {
00320 struct env_image* chanOut = &jobdata[dir].chanOut;
00321
00322 if (env_img_initialized(chanOut))
00323 {
00324 if (!env_img_initialized(result))
00325 {
00326 env_img_resize_dims(result, chanOut->dims);
00327 env_c_image_div_scalar
00328 (env_img_pixels(chanOut),
00329 env_img_size(chanOut),
00330 (intg32) chan->num_directions,
00331 env_img_pixelsw(result));
00332 }
00333 else
00334 {
00335 ENV_ASSERT
00336 (env_dims_equal(chanOut->dims,
00337 result->dims));
00338 env_c_image_div_scalar_accum
00339 (env_img_pixels(chanOut),
00340 env_img_size(chanOut),
00341 (intg32) chan->num_directions,
00342 env_img_pixelsw(result));
00343 }
00344 }
00345
00346 env_img_make_empty(chanOut);
00347 }
00348
00349 if (env_img_initialized(result))
00350 {
00351 env_max_normalize_inplace(result,
00352 INTMAXNORMMIN, INTMAXNORMMAX,
00353 envp->maxnorm_type,
00354 envp->range_thresh);
00355 if (status_func)
00356 (*status_func)(status_userdata, tagName, result);
00357 }
00358
00359 env_pyr_swap(unshiftedCur, &chan->unshifted_prev);
00360 env_pyr_make_empty(unshiftedCur);
00361
00362 env_deallocate(jobdata);
00363 env_deallocate(jobs);
00364 }
00365
00366
00367
00368
00369
00370
00371
00372
00373 #endif // ENVISION_ENV_MT_CHANNEL_C_DEFINED