1
2 #include "boxm2_vecf_appearance_extractor.h"
3 #include <boct/boct_bit_tree.h>
4 #include "boxm2_vecf_composite_head_parameters.h"
5 #include "vul/vul_timer.h"
reset(bool is_right)6 void boxm2_vecf_appearance_extractor::reset(bool is_right){
7 boxm2_vecf_orbit_scene orbit = is_right ? head_model_.right_orbit_ : head_model_.left_orbit_;
8 boxm2_scene_sptr scene = orbit.scene();
9
10 total_sclera_app_.fill(0); vis_sclera_ = 0.0f;
11 total_pupil_app_.fill(0); vis_pupil_ =0.0f;
12 total_iris_app_.fill(0); vis_iris_ = 0.0f;
13
14
15 std::vector<boxm2_block_id> blocks = scene->get_block_ids();
16 boxm2_data_base* gray_app_db = boxm2_cache::instance()->get_data_base(scene, blocks[0],gray_APM_prefix);
17 boxm2_data_base* color_app_db = boxm2_cache::instance()->get_data_base(scene, blocks[0], color_APM_prefix + "_" + (head_model_.color_apm_id_));
18 boxm2_block_metadata m_data = scene->get_block_metadata(blocks[0]);
19 gray_app_db->set_default_value(gray_APM_prefix, m_data);
20 color_app_db->set_default_value(color_APM_prefix, m_data);
21 }
extract_data(boxm2_scene_sptr scene,boxm2_block_id & block,float * & alpha,gray_APM * & gray_app,color_APM * & color_app)22 bool boxm2_vecf_appearance_extractor::extract_data(boxm2_scene_sptr scene,boxm2_block_id& block,float * &alpha,gray_APM* &gray_app, color_APM* &color_app){
23 boxm2_data_base* gray_app_db = boxm2_cache::instance()->get_data_base(scene, block,gray_APM_prefix);
24 boxm2_data_base* alpha_db = boxm2_cache::instance()->get_data_base(scene, block,"alpha");
25 boxm2_data_base* color_app_db = boxm2_cache::instance()->get_data_base(scene, block, color_APM_prefix + "_" + (head_model_.color_apm_id_));
26 gray_app = reinterpret_cast<gray_APM*>(gray_app_db->data_buffer());
27 color_app = reinterpret_cast<color_APM*>(color_app_db->data_buffer());
28 alpha = reinterpret_cast<boxm2_data_traits<BOXM2_ALPHA>::datatype*>(alpha_db->data_buffer());
29 if (gray_app && alpha && color_app)
30 return true;
31
32 return false;
33 }
extract_head_appearance()34 void boxm2_vecf_appearance_extractor::extract_head_appearance(){
35 vul_timer t;
36 boxm2_scene_sptr base_model = head_model_.scene();
37 // for each block of the target scene
38 boxm2_vecf_composite_head_parameters const& head_params = head_model_.get_params();
39 std::vector<boxm2_block_id> target_blocks = target_scene_->get_block_ids();
40 std::vector<boxm2_block_id> source_blocks = base_model->get_block_ids();
41
42 for (auto & source_block : source_blocks) {
43 boxm2_block * source_blk = boxm2_cache::instance()->get_block(base_model, source_block);
44 color_APM * source_color_data; gray_APM* source_app_data; float* source_alpha_data;
45
46 if(!this->extract_data(base_model,source_block,source_alpha_data,source_app_data,source_color_data)){
47 std::cout<<"Data extraction failed for scene "<< base_model << " in block "<<source_block<<std::endl;
48 return;
49 }
50
51 //3d array of trees
52 typedef boxm2_block::uchar16 uchar16;
53 const boxm2_array_3d<uchar16>& trees = source_blk->trees();
54 // for each block of the base model
55 for (auto & target_block : target_blocks) {
56 boxm2_block * target_blk = boxm2_cache::instance()->get_block(target_scene_, target_block);
57 color_APM * target_color_data; gray_APM* target_app_data; float* target_alpha_data;
58
59 if(!this->extract_data(target_scene_,target_block,target_alpha_data,target_app_data,target_color_data)){
60 std::cout<<"Data extraction failed for scene "<< target_scene_ << " in block "<<target_block<<std::endl;
61 return;
62 }
63
64 //iterate through each block, filtering the root level first
65 for (unsigned int x = 0; x < trees.get_row1_count(); ++x) {
66 for (unsigned int y = 0; y < trees.get_row2_count(); ++y) {
67 for (unsigned int z = 0; z < trees.get_row3_count(); ++z) {
68 //load current tree
69 uchar16 tree = trees(x, y, z);
70 boct_bit_tree bit_tree((unsigned char*) tree.data_block(), source_blk->max_level());
71
72 //FOR ALL LEAVES IN CURRENT TREE
73 std::vector<int> leafBits = bit_tree.get_leaf_bits();
74 std::vector<int>::iterator iter;
75 for (iter = leafBits.begin(); iter != leafBits.end(); ++iter) {
76 int bit_idx = (*iter);
77 int data_idx = bit_tree.get_data_index(bit_idx);
78
79 vgl_point_3d<double> cell_center_norm = bit_tree.cell_center( bit_idx );
80 double source_side_len = 1.0/(1 << bit_tree.depth_at(bit_idx));
81 // convert to global coordinates
82 vgl_vector_3d<double> subblk_dims = source_blk->sub_block_dim();
83 vgl_vector_3d<double> subblk_offset(x*subblk_dims.x(),
84 y*subblk_dims.y(),
85 z*subblk_dims.z());
86
87 vgl_vector_3d<double> cell_offset(cell_center_norm.x()*subblk_dims.x(),
88 cell_center_norm.y()*subblk_dims.y(),
89 cell_center_norm.z()*subblk_dims.z());
90
91 vgl_point_3d<double> cell_center = source_blk->local_origin() + subblk_offset + cell_offset;
92
93 // apply (inverse) scaling
94 vgl_point_3d<double> fwd_scaled_cell_center(cell_center.x() * head_params.head_scale_.x(),
95 cell_center.y() * head_params.head_scale_.y(),
96 cell_center.z() * head_params.head_scale_.z());
97
98 // retreive the correct cell from the source data
99 vgl_point_3d<double> local_tree_coords, target_cell_center;
100 double side_len;
101
102 if ( target_blk->contains( fwd_scaled_cell_center, local_tree_coords, target_cell_center, side_len )) {
103 unsigned target_data_idx;
104 target_blk->data_index( fwd_scaled_cell_center, target_data_idx);
105 float alpha = target_alpha_data[target_data_idx];
106 auto src_prob = static_cast<float>(1.0 - std::exp( - source_alpha_data[data_idx] * source_side_len));
107 //double prob = static_cast<float>(1.0 - std::exp(-alpha*side_len));
108 constexpr double prob_thresh = 0.0;
109
110 if (src_prob >= prob_thresh) {
111 // get data can copy from source to target
112 source_app_data[data_idx] = target_app_data[target_data_idx];
113 source_color_data[data_idx] = target_color_data[target_data_idx];
114 }
115 // get data can copy from source to target
116 source_app_data [data_idx] = target_app_data [target_data_idx];
117 source_color_data[data_idx] = target_color_data[target_data_idx];
118
119 }
120 }
121 }
122 }
123 }
124 } // for each source block
125 } // for each target block
126 std::cout<<"extracted head appearance model from target in "<<t.real()/1000<<" seconds"<<std::endl;
127 }
128
129
extract_orbit_appearance()130 void boxm2_vecf_appearance_extractor::extract_orbit_appearance(){
131
132 std::vector<boxm2_block_id> target_blocks = target_scene_->get_block_ids();
133 if (target_blocks.size()>1){
134 std::cout<< "visibility info cannot be used in current implementation if scene contains more than one block"<<std::endl;
135 current_vis_score_ = nullptr;
136 }else{
137 boxm2_data_base* vis_score_db = boxm2_cache::instance()->get_data_base(target_scene_,target_blocks[0],boxm2_data_traits<BOXM2_VIS_SCORE>::prefix(head_model_.color_apm_id_));
138 current_vis_score_ = reinterpret_cast<vis_score_t*>(vis_score_db->data_buffer());
139 }
140 this->reset(true);
141 this->reset(false);
142
143 //extract and compute the mean appearance of each anatomy label
144 this->extract_eye_appearance(true,true);
145 this->extract_eye_appearance(false,true);
146
147 this->extract_iris_appearance(true,true);
148 this->extract_iris_appearance(false,true);
149
150 this->extract_pupil_appearance(true,true);
151 this->extract_pupil_appearance(false,true);
152
153 this->extract_eyelid_crease_appearance(true,true);
154 this->extract_eyelid_crease_appearance(false,true);
155
156 this->extract_lower_lid_appearance(true,true);
157 this->extract_lower_lid_appearance(false,true);
158
159 this->extract_upper_lid_appearance(true,true);
160 this->extract_upper_lid_appearance(false,true);
161
162
163 // set the appearance of occluded eye voxels to the mean appearance
164 this->extract_eye_appearance(true,false);
165 this->extract_eye_appearance(false,false);
166
167 this->extract_iris_appearance(true,false);
168 this->extract_iris_appearance(false,false);
169
170 this->extract_pupil_appearance(true,false);
171 this->extract_pupil_appearance(false,false);
172
173 this->extract_eyelid_crease_appearance(true,false);
174 this->extract_eyelid_crease_appearance(false,false);
175
176 this->extract_lower_lid_appearance(true,false);
177 this->extract_lower_lid_appearance(false,false);
178
179 this->extract_upper_lid_appearance(true,false);
180 this->extract_upper_lid_appearance(false,false);
181
182
183 this->bump_up_vis_scores();
184
185 }
extract_iris_appearance(bool is_right,bool extract)186 void boxm2_vecf_appearance_extractor::extract_iris_appearance(bool is_right,bool extract){
187 vul_timer t;
188 boxm2_vecf_composite_head_parameters const& head_params = head_model_.get_params();
189 boxm2_vecf_orbit_scene orbit; boxm2_vecf_orbit_params orbit_params;
190 if (!is_right){
191 orbit = head_model_.left_orbit_;
192 orbit_params = head_params.l_orbit_params_;
193 }else{
194 orbit = head_model_.right_orbit_;
195 orbit_params = head_params.r_orbit_params_;
196 }
197
198 color_APM color =orbit.random_color();
199 vnl_vector_fixed<double, 3> Z(0.0, 0.0, 1.0);
200 vnl_vector_fixed<double, 3> to_dir(orbit_params.eye_pointing_dir_.x(),
201 orbit_params.eye_pointing_dir_.y(),
202 orbit_params.eye_pointing_dir_.z());
203
204 vgl_rotation_3d<double> rot(Z, to_dir);
205
206 float sum_vis = 0;
207 color_APM& curr_iris = is_right ? right_iris_app_ : left_iris_app_;
208 color_APM final_iris_app;
209
210 float8 weighted_sum; weighted_sum.fill(0);
211 if(!extract && vis_iris_!= 0 ){
212 float8 final_iris_app_f = total_iris_app_ / vis_iris_;
213 final_iris_app = to_apm_t(final_iris_app_f);
214 curr_iris = individual_appearance_ ? curr_iris : final_iris_app;
215 }
216
217
218 boxm2_scene_sptr source_model = orbit.scene();
219 std::vector<boxm2_block_id> source_blocks = source_model->get_block_ids();
220
221 auto n_source_cells = static_cast<unsigned>(orbit.iris_cell_centers_.size());
222 std::cout<<"iris cell centers: "<<n_source_cells<<std::endl;
223 for (auto & source_block : source_blocks) {
224 color_APM * source_color_data; gray_APM* source_app_data; float* source_alpha_data;
225 if(!this->extract_data(source_model,source_block,source_alpha_data,source_app_data,source_color_data)){
226 std::cout<<"Data extraction failed for scene "<< source_model << " in block "<<source_block<<std::endl;
227 return;
228 }
229
230 for(unsigned i = 0; i<n_source_cells; ++i){
231 vgl_point_3d<double> p = (orbit.iris_cell_centers_[i]);
232
233 if(!orbit.is_type_global(p, boxm2_vecf_orbit_scene::IRIS))
234 continue;
235 //is a sphere voxel cell so define the vector field
236 vgl_point_3d<double> mapped_p = rot * p + orbit_params.offset_ ;
237 // find closest sphere voxel cell
238 std::vector<boxm2_block_id> target_blocks = target_scene_->get_block_ids();
239
240 vgl_point_3d<double> local_tree_coords, target_cell_center; double target_side_len;
241 for (auto & target_block : target_blocks) {
242 boxm2_block *target_blk = boxm2_cache::instance()->get_block(target_scene_, target_block);
243 if ( target_blk->contains( mapped_p, local_tree_coords, target_cell_center, target_side_len )) {
244 color_APM * target_color_data; gray_APM* target_app_data; float* target_alpha_data; unsigned target_data_idx;
245 if(!this->extract_data(target_scene_,target_block,target_alpha_data,target_app_data,target_color_data)){
246 std::cout<<"Data extraction failed for scene "<< target_scene_ << " in block "<<target_block<<std::endl;
247 return ;
248 }
249 target_blk->data_index( mapped_p, target_data_idx);
250 unsigned source_data_idx = orbit.iris_cell_data_index_[i];
251
252 source_app_data[source_data_idx] = target_app_data[target_data_idx];
253 double prob =1 - exp (- target_alpha_data[target_data_idx] * target_side_len);
254 if(extract){
255 if (current_vis_score_ && prob > 0.8){
256 float8 curr_float_col = to_float8(target_color_data[target_data_idx]);
257 weighted_sum += curr_float_col * current_vis_score_[target_data_idx];
258 sum_vis += current_vis_score_[target_data_idx];
259 }
260 }else{
261 float8 appearance = to_float8(target_color_data[target_data_idx]) * current_vis_score_[target_data_idx] + to_float8(curr_iris) * (1 - current_vis_score_[target_data_idx]);
262 source_color_data[source_data_idx]= faux_ ? color : to_apm_t(appearance);
263 vis_cells_.push_back(target_data_idx); //need to set the vis of this index to 1
264 }
265 }
266 }
267 }
268 }
269 if(sum_vis != 0 && extract){
270 vis_iris_ += sum_vis;
271 total_iris_app_ +=weighted_sum;
272 weighted_sum /= sum_vis;
273 curr_iris = to_apm_t( weighted_sum );
274 }
275 // std::cout<<"Extracted iris appearance in "<<t.real()/1000<<" seconds"<<std::endl;
276
277 }
extract_pupil_appearance(bool is_right,bool extract)278 void boxm2_vecf_appearance_extractor::extract_pupil_appearance(bool is_right, bool extract){
279 vul_timer t;
280 boxm2_vecf_composite_head_parameters const& head_params = head_model_.get_params();
281 boxm2_vecf_orbit_scene orbit; boxm2_vecf_orbit_params orbit_params;
282 if (!is_right){
283 orbit = head_model_.left_orbit_;
284 orbit_params = head_params.l_orbit_params_;
285 }else{
286 orbit = head_model_.right_orbit_;
287 orbit_params = head_params.r_orbit_params_;
288 }
289
290
291 color_APM color =orbit.random_color();
292 vnl_vector_fixed<double, 3> Z(0.0, 0.0, 1.0);
293 vnl_vector_fixed<double, 3> to_dir(orbit_params.eye_pointing_dir_.x(),
294 orbit_params.eye_pointing_dir_.y(),
295 orbit_params.eye_pointing_dir_.z());
296
297 vgl_rotation_3d<double> rot(Z, to_dir);
298
299 float sum_vis = 0;
300 color_APM& curr_pupil = is_right ? right_pupil_app_ : left_pupil_app_;
301 float8 weighted_sum; weighted_sum.fill(0);
302
303 color_APM final_pupil_app;
304 if(!extract && vis_pupil_!= 0 ){
305 float8 final_pupil_app_f = total_pupil_app_ / vis_pupil_;
306 final_pupil_app = to_apm_t(final_pupil_app_f);
307 curr_pupil = individual_appearance_ ? curr_pupil : final_pupil_app;
308 }
309
310 boxm2_scene_sptr source_model = orbit.scene();
311 std::vector<boxm2_block_id> source_blocks = source_model->get_block_ids();
312
313
314 auto n_source_cells = static_cast<unsigned>(orbit.pupil_cell_centers_.size());
315 std::cout<<"pupil cell centers: "<<n_source_cells<<std::endl;
316 for (auto & source_block : source_blocks) {
317 color_APM * source_color_data; gray_APM* source_app_data; float* source_alpha_data;
318 if(!this->extract_data(source_model,source_block,source_alpha_data,source_app_data,source_color_data)){
319 std::cout<<"Data extraction failed for scene "<< source_model << " in block "<<source_block<<std::endl;
320 return;
321 }
322
323 for(unsigned i = 0; i<n_source_cells; ++i){
324 vgl_point_3d<double> p = (orbit.pupil_cell_centers_[i]);
325
326 if(!orbit.is_type_global(p, boxm2_vecf_orbit_scene::PUPIL))
327 continue;
328 //is a sphere voxel cell so define the vector field
329 vgl_point_3d<double> mapped_p = rot * p + orbit_params.offset_ ;
330 // find closest sphere voxel cell
331 std::vector<boxm2_block_id> target_blocks = target_scene_->get_block_ids();
332
333 vgl_point_3d<double> local_tree_coords, target_cell_center; double target_side_len;
334 for (auto & target_block : target_blocks) {
335 boxm2_block *target_blk = boxm2_cache::instance()->get_block(target_scene_, target_block);
336 if ( target_blk->contains( mapped_p, local_tree_coords, target_cell_center, target_side_len )) {
337 color_APM * target_color_data; gray_APM* target_app_data; float* target_alpha_data; unsigned target_data_idx;
338 if(!this->extract_data(target_scene_,target_block,target_alpha_data,target_app_data,target_color_data)){
339 std::cout<<"Data extraction failed for scene "<< target_scene_ << " in block "<<target_block<<std::endl;
340 return ;
341 }
342 target_blk->data_index( mapped_p, target_data_idx);
343 unsigned source_data_idx = orbit.pupil_cell_data_index_[i];
344 uchar8 appearance = faux_ ? color : target_color_data[target_data_idx];
345 source_app_data[source_data_idx] = target_app_data[target_data_idx];
346 double prob = 1 - exp (- target_alpha_data[target_data_idx] * target_side_len);
347 if(extract){
348 if (current_vis_score_ && prob > 0.8){
349 float8 curr_float_col = to_float8(target_color_data[target_data_idx]);
350 weighted_sum += curr_float_col * current_vis_score_[target_data_idx];
351 sum_vis += current_vis_score_[target_data_idx];
352 }
353 }else{
354 float8 appearance = to_float8(target_color_data[target_data_idx]) * current_vis_score_[target_data_idx]+
355 to_float8(curr_pupil) * (1 - current_vis_score_[target_data_idx]);
356 source_color_data[source_data_idx]= faux_ ? color : to_apm_t(appearance);
357 vis_cells_.push_back(target_data_idx); //need to set the vis of this index to 1
358 }
359 }
360 }
361 }
362 }
363 if(sum_vis != 0 && extract){
364 vis_pupil_ += sum_vis;
365 total_pupil_app_ +=weighted_sum;
366 weighted_sum /= sum_vis;
367 curr_pupil = to_apm_t( weighted_sum );
368 }
369 if(extract)
370 std::cout<<"Sum vis for current pupil is "<<sum_vis<<std::endl;
371 // std::cout<<"Extracted pupil appearance in "<<t.real()/1000<<" seconds"<<std::endl;
372
373 }
extract_eye_appearance(bool is_right,bool extract)374 void boxm2_vecf_appearance_extractor::extract_eye_appearance(bool is_right, bool extract){
375 vul_timer t;
376 boxm2_vecf_composite_head_parameters const& head_params = head_model_.get_params();
377 boxm2_vecf_orbit_scene orbit; boxm2_vecf_orbit_params orbit_params;
378 if (!is_right){
379 orbit = head_model_.left_orbit_;
380 orbit_params = head_params.l_orbit_params_;
381 }else{
382 orbit = head_model_.right_orbit_;
383 orbit_params = head_params.r_orbit_params_;
384 }
385 color_APM color =orbit.random_color();
386 vnl_vector_fixed<double, 3> Z(0.0, 0.0, 1.0);
387 vnl_vector_fixed<double, 3> to_dir(orbit_params.eye_pointing_dir_.x(),
388 orbit_params.eye_pointing_dir_.y(),
389 orbit_params.eye_pointing_dir_.z());
390 vgl_rotation_3d<double> rot(Z, to_dir);
391 std::vector<vgl_vector_3d<double> >vf;
392
393 float sum_vis = 0;
394 color_APM& curr_sclera = is_right ? right_sclera_app_ : left_sclera_app_;
395 float8 weighted_sum; weighted_sum.fill(0);
396
397 color_APM final_sclera_app;
398 if(!extract && vis_sclera_!= 0 ){
399 float8 final_sclera_app_f = total_sclera_app_ / vis_sclera_;
400 final_sclera_app = to_apm_t(final_sclera_app_f);
401 curr_sclera = individual_appearance_ ? curr_sclera : final_sclera_app;
402 }
403
404
405 boxm2_scene_sptr source_model = orbit.scene();
406
407 std::vector<boxm2_block_id> source_blocks = source_model->get_block_ids();
408 auto n_source_cells = static_cast<unsigned>(orbit.sphere_cell_centers_.size());
409 std::cout<<"sphere cell centers: "<<n_source_cells<<std::endl;
410 for (auto & source_block : source_blocks) {
411 color_APM * source_color_data; gray_APM* source_app_data; float* source_alpha_data;
412 if(!this->extract_data(source_model,source_block,source_alpha_data,source_app_data,source_color_data)){
413 std::cout<<"Data extraction failed for scene "<< source_model << " in block "<<source_block<<std::endl;
414 return;
415 }
416
417 for(unsigned i = 0; i<n_source_cells; ++i){
418 vgl_point_3d<double> p = (orbit.sphere_cell_centers_[i]);
419
420 if(!orbit.is_type_global(p, boxm2_vecf_orbit_scene::SPHERE) ||
421 orbit.is_type_global(p, boxm2_vecf_orbit_scene::IRIS ) ||
422 orbit.is_type_global(p, boxm2_vecf_orbit_scene::PUPIL ) )
423 continue;
424 //is a sphere voxel cell so define the vector field
425 vgl_point_3d<double> mapped_p = rot * p + orbit_params.offset_ ;
426 // find closest sphere voxel cell
427 std::vector<boxm2_block_id> target_blocks = target_scene_->get_block_ids();
428
429 vgl_point_3d<double> local_tree_coords, target_cell_center; double target_side_len;
430 for (auto & target_block : target_blocks) {
431 boxm2_block *target_blk = boxm2_cache::instance()->get_block(target_scene_, target_block);
432 if ( target_blk->contains( mapped_p, local_tree_coords, target_cell_center, target_side_len )) {
433 color_APM * target_color_data; gray_APM* target_app_data; float* target_alpha_data; unsigned target_data_idx;
434 if(!this->extract_data(target_scene_,target_block,target_alpha_data,target_app_data,target_color_data)){
435 std::cout<<"Data extraction failed for scene "<< target_scene_ << " in block "<<target_block<<std::endl;
436 return ;
437 }
438 target_blk->data_index( mapped_p, target_data_idx);
439 unsigned source_data_idx = orbit.sphere_cell_data_index_[i];
440 uchar8 appearance = faux_ ? color : target_color_data[target_data_idx];
441 source_app_data [source_data_idx] = target_app_data[target_data_idx];
442 double prob =1 - exp (- target_alpha_data[target_data_idx] * target_side_len);
443 if(extract){
444 if (current_vis_score_ && prob > 0.8){
445 float8 curr_float_col = to_float8(target_color_data[target_data_idx]);
446 weighted_sum += curr_float_col * current_vis_score_[target_data_idx];
447 sum_vis += current_vis_score_[target_data_idx];
448 }
449 }else{
450 float8 appearance = to_float8(target_color_data[target_data_idx]) * current_vis_score_[target_data_idx] +
451 to_float8(curr_sclera) * (1 - current_vis_score_[target_data_idx]);
452 source_color_data[source_data_idx]= faux_ ? color : to_apm_t(appearance);
453 //source_color_data[source_data_idx]= faux_ ? color : curr_sclera ;
454 vis_cells_.push_back(target_data_idx); //need to set the vis of this index to 1
455 }
456 }
457 }
458 }
459 }
460 if(sum_vis != 0 && extract){
461 vis_sclera_ += sum_vis;
462 total_sclera_app_ +=weighted_sum;
463 weighted_sum /= sum_vis;
464 curr_sclera = to_apm_t( weighted_sum );
465 }
466 // std::cout<<"Extracted eye sphere appearance in "<<t.real()/1000<<" seconds"<<std::endl;
467 }
extract_eyelid_crease_appearance(bool is_right,bool extract)468 void boxm2_vecf_appearance_extractor::extract_eyelid_crease_appearance(bool is_right, bool extract){
469 vul_timer t;
470 boxm2_vecf_composite_head_parameters const& head_params = head_model_.get_params();
471 boxm2_vecf_orbit_scene orbit; boxm2_vecf_orbit_params orbit_params;
472 if (!is_right){
473 orbit = head_model_.left_orbit_;
474 orbit_params = head_params.l_orbit_params_;
475 }else{
476 orbit = head_model_.right_orbit_;
477 orbit_params = head_params.r_orbit_params_;
478 }
479 color_APM color =orbit.random_color();
480 boxm2_scene_sptr source_model = orbit.scene();
481 float sum_vis = 0;
482 color_APM& curr_eyelid_crease = is_right ? right_eyelid_crease_app_ : left_eyelid_crease_app_ ;
483 float8 weighted_sum; weighted_sum.fill(0);
484 std::vector<boxm2_block_id> source_blocks = source_model->get_block_ids();
485 auto n_source_cells = static_cast<unsigned>(orbit.eyelid_crease_cell_centers_.size());
486 std::cout<<"eyelid crease cell centers "<<n_source_cells<<std::endl;
487
488 for (auto & source_block : source_blocks) {
489 color_APM * source_color_data; gray_APM* source_app_data; float* source_alpha_data;
490 if(!this->extract_data(source_model,source_block,source_alpha_data,source_app_data,source_color_data)){
491 std::cout<<"Data extraction failed for scene "<< source_model << " in block "<<source_block<<std::endl;
492 return;
493 }
494
495 for(unsigned i = 0; i<n_source_cells; ++i){
496 vgl_point_3d<double> p = (orbit.eyelid_crease_cell_centers_[i]);
497
498 if(!orbit.is_type_global(p, boxm2_vecf_orbit_scene::EYELID_CREASE))
499 continue;
500 //is a sphere voxel cell so define the vector field
501 vgl_point_3d<double> mapped_p = (p + orbit_params.offset_) ;
502 if (is_right){
503 vgl_vector_3d<double> flip(-2 * p.x(),0,0);
504 mapped_p = mapped_p + flip;
505 }
506
507 std::vector<boxm2_block_id> target_blocks = target_scene_->get_block_ids();
508
509 vgl_point_3d<double> local_tree_coords, target_cell_center; double target_side_len;
510 for (auto & target_block : target_blocks) {
511 boxm2_block *target_blk = boxm2_cache::instance()->get_block(target_scene_, target_block);
512 if ( target_blk->contains( mapped_p, local_tree_coords, target_cell_center, target_side_len )) {
513 color_APM * target_color_data; gray_APM* target_app_data; float* target_alpha_data; unsigned target_data_idx;
514 if(!this->extract_data(target_scene_,target_block,target_alpha_data,target_app_data,target_color_data)){
515 std::cout<<"Data extraction failed for scene "<< target_scene_ << " in block "<<target_block<<std::endl;
516 return ;
517 }
518 target_blk->data_index( mapped_p, target_data_idx);
519 unsigned source_data_idx = orbit.eyelid_crease_cell_data_index_[i];
520 double prob =1 - exp (- target_alpha_data[target_data_idx] * target_side_len);
521 source_app_data[source_data_idx] = target_app_data[target_data_idx];
522 if(extract){
523 if (current_vis_score_ && prob > 0.8){
524 float8 curr_float_col = to_float8(target_color_data[target_data_idx]);
525 weighted_sum += curr_float_col * current_vis_score_[target_data_idx];
526 sum_vis += current_vis_score_[target_data_idx];
527 }
528 }else{
529 float8 appearance = to_float8(target_color_data[target_data_idx]) * current_vis_score_[target_data_idx] +
530 to_float8(curr_eyelid_crease) * (1 - current_vis_score_[target_data_idx]);
531 source_color_data[source_data_idx]= faux_ ? color : to_apm_t(appearance);
532 vis_cells_.push_back(target_data_idx); //need to set the vis of this index to 1
533 }
534 }
535 }
536 }
537 }
538 if(sum_vis != 0 && extract)
539 weighted_sum /= sum_vis;
540 curr_eyelid_crease = to_apm_t( weighted_sum );
541 // std::cout<<"Extracted eyelid crease appearance in "<<t.real()/1000<<" seconds and sum_vis is "<<sum_vis<<std::endl;
542 }
543
extract_lower_lid_appearance(bool is_right,bool extract)544 void boxm2_vecf_appearance_extractor::extract_lower_lid_appearance(bool is_right,bool extract){
545 vul_timer t;
546 boxm2_vecf_composite_head_parameters const& head_params = head_model_.get_params();
547 boxm2_vecf_orbit_scene orbit; boxm2_vecf_orbit_params orbit_params;
548 color_APM& curr_lower_eyelid = is_right ? right_lower_lid_app_: left_lower_lid_app_;
549
550 if (!is_right){
551 orbit = head_model_.left_orbit_;
552 orbit_params = head_params.l_orbit_params_;
553 }else{
554 orbit = head_model_.right_orbit_;
555 orbit_params = head_params.r_orbit_params_;
556 }
557 color_APM color =orbit.random_color();
558 boxm2_scene_sptr source_model = orbit.scene();
559 float8 weighted_sum; weighted_sum.fill(0); float sum_vis =0.0f;
560 std::vector<boxm2_block_id> source_blocks = source_model->get_block_ids();
561
562 auto n_source_cells = static_cast<unsigned>(orbit.lower_eyelid_cell_centers_.size());
563 std::cout<<"lower lid cell centers "<<n_source_cells<<std::endl;
564 for (auto & source_block : source_blocks) {
565 color_APM * source_color_data; gray_APM* source_app_data; float* source_alpha_data;
566 if(!this->extract_data(source_model,source_block,source_alpha_data,source_app_data,source_color_data)){
567 std::cout<<"Data extraction failed for scene "<< source_model << " in block "<<source_block<<std::endl;
568 return;
569 }
570
571
572 for(unsigned i = 0; i< n_source_cells; ++i){
573 vgl_point_3d<double> p = (orbit.lower_eyelid_cell_centers_[i]);
574
575 if(!orbit.is_type_global(p, boxm2_vecf_orbit_scene::LOWER_LID))
576 continue;
577 //is a sphere voxel cell so define the vector field
578 vgl_point_3d<double> mapped_p = (p + orbit_params.offset_) ;
579 if (is_right){
580 vgl_vector_3d<double> flip(-2 * p.x(),0,0);
581 mapped_p = mapped_p + flip;
582 }
583
584 // find closest sphere voxel cell
585 std::vector<boxm2_block_id> target_blocks = target_scene_->get_block_ids();
586
587 vgl_point_3d<double> local_tree_coords, target_cell_center; double target_side_len;
588 for (auto & target_block : target_blocks) {
589 boxm2_block *target_blk = boxm2_cache::instance()->get_block(target_scene_, target_block);
590 if ( target_blk->contains( mapped_p, local_tree_coords, target_cell_center, target_side_len )) {
591 color_APM * target_color_data; gray_APM* target_app_data; float* target_alpha_data; unsigned target_data_idx;
592 if(!this->extract_data(target_scene_,target_block,target_alpha_data,target_app_data,target_color_data)){
593 std::cout<<"Data extraction failed for scene "<< target_scene_ << " in block "<<target_block<<std::endl;
594 return ;
595 }
596 target_blk->data_index( mapped_p, target_data_idx);
597 unsigned source_data_idx = orbit.lower_eyelid_cell_data_index_[i];
598 source_app_data[source_data_idx] = target_app_data[target_data_idx];
599
600 uchar8 appearance = faux_ ? color : target_color_data[target_data_idx];
601 source_color_data[source_data_idx] = appearance;
602 double prob = 1 - exp (- target_alpha_data[target_data_idx] * target_side_len);
603 if(extract){
604 if (current_vis_score_ && prob > 0.8){
605 float8 curr_float_col = to_float8(target_color_data[target_data_idx]);
606 weighted_sum += curr_float_col * current_vis_score_[target_data_idx];
607 sum_vis += current_vis_score_[target_data_idx];
608 }
609 }else{
610 float8 appearance = to_float8(target_color_data[target_data_idx]) * current_vis_score_[target_data_idx] +
611 to_float8(curr_lower_eyelid) * (1 - current_vis_score_[target_data_idx]);
612 source_color_data[source_data_idx]= faux_ ? color : to_apm_t(appearance);
613 vis_cells_.push_back(target_data_idx); //need to set the vis of this index to 1
614 }
615 }
616 }
617 }
618 }
619 if(sum_vis != 0 && extract){
620 weighted_sum /= sum_vis;
621 curr_lower_eyelid = to_apm_t( weighted_sum );
622 }
623 // std::cout<<"Extracted lower lid appearance in "<<t.real()/1000<<" seconds"<<std::endl;
624 }
625
extract_upper_lid_appearance(bool is_right,bool extract)626 void boxm2_vecf_appearance_extractor::extract_upper_lid_appearance(bool is_right,bool extract){
627 vul_timer t;
628 boxm2_vecf_composite_head_parameters const& head_params = head_model_.get_params();
629 boxm2_vecf_orbit_scene orbit; boxm2_vecf_orbit_params orbit_params;
630 uchar8 red,green; red.fill(0);green.fill(0); red[0] =255; green[1] = 255;
631 if (!is_right){
632 orbit = head_model_.left_orbit_;
633 orbit_params = head_params.l_orbit_params_;
634 }else{
635 orbit = head_model_.right_orbit_;
636 orbit_params = head_params.r_orbit_params_;
637 }
638 color_APM color =orbit.random_color();
639 color[0]=255; color[2]=0; color[4]=0;
640
641 double dt = 0.95;
642 color_APM eyelid_color = is_right? red : green;
643 color[0]=0; color[1]=0; color[2]=255;
644 float8 weighted_sum; weighted_sum.fill(0); float sum_vis =0.0f;
645 boxm2_scene_sptr source_model = orbit.scene();
646 color_APM& curr_lower_lid = is_right ? right_lower_lid_app_ : left_lower_lid_app_ ;
647 color_APM& curr_upper_lid = is_right ? right_upper_lid_app_ : left_upper_lid_app_ ;
648
649 std::vector<boxm2_block_id> source_blocks = source_model->get_block_ids();
650
651 for (auto & source_block : source_blocks) {
652 boxm2_block *source_blk = boxm2_cache::instance()->get_block(source_model, source_block);
653 auto n_source_cells = static_cast<unsigned>(orbit.eyelid_cell_centers_.size());
654 color_APM * source_color_data; gray_APM* source_app_data; float* source_alpha_data;
655 if(!this->extract_data(source_model,source_block,source_alpha_data,source_app_data,source_color_data)){
656 std::cout<<"Data extraction failed for scene "<< source_model << " in block "<<source_block<<std::endl;
657 return;
658 }
659
660 for(unsigned i = 0; i < n_source_cells; ++i){
661 bool skip = false;vgl_point_3d<double> loc_p;
662 vgl_point_3d<double> p = (orbit.eyelid_cell_centers_[i]);
663
664
665 if(!orbit.is_type_global(p, boxm2_vecf_orbit_scene::UPPER_LID) ){
666 //#if _DEBUG
667 if(is_right)
668 std::cout<<"this right eyelid point "<<p<<" was not ok w.r.t label type"<<std::endl;
669 else
670 std::cout<<"this left eyelid point "<<p<<" was not ok w.r.t label type"<<std::endl;
671 continue;
672 //#endif
673 }
674 if(!(source_blk->contains(p, loc_p) )){
675 #if _DEBUG
676 if(is_right)
677 std::cout<<"this right eyelid point "<<p<<" was not in bounds"<<std::endl;
678 else
679 std::cout<<"this left eyelid point "<<p<<" was not in bounds"<<std::endl;
680 #endif
681 continue;
682
683 }
684 //is a sphere voxel cell so define the vector field
685
686 double tc = orbit.eyelid_geo_.t(p.x(), p.y());
687 if(!orbit.eyelid_geo_.valid_t(tc)){
688 #if _DEBUG
689 std::cout<<"this eyelid point "<<p<<" was not ok w.r.t tc"<<std::endl;
690 continue;
691 #endif
692 }
693 // inverse field so negate dt
694 double ti = tc - dt;
695 if(!orbit.eyelid_geo_.valid_t(ti)){
696 skip = true;
697 }
698 vgl_point_3d<double> mapped_p = (p + orbit_params.offset_) ;
699 mapped_p += orbit.eyelid_geo_.vf(p.x(), tc, - dt);
700 if (is_right){
701 vgl_vector_3d<double> flip(-2 * mapped_p.x(),0,0);
702 mapped_p += flip;
703 }
704
705
706 // find closest sphere voxel cell
707 std::vector<boxm2_block_id> target_blocks = target_scene_->get_block_ids();
708
709 vgl_point_3d<double> local_tree_coords, target_cell_center; double target_side_len;
710 for (auto & target_block : target_blocks) {
711 boxm2_block *target_blk = boxm2_cache::instance()->get_block(target_scene_, target_block);
712 if ( target_blk->contains( mapped_p, local_tree_coords, target_cell_center, target_side_len )) {
713 color_APM * target_color_data; gray_APM* target_app_data; float* target_alpha_data; unsigned target_data_idx;
714 if(!this->extract_data(target_scene_,target_block,target_alpha_data,target_app_data,target_color_data)){
715 std::cout<<"Data extraction failed for scene "<< target_scene_ << " in block "<<target_block<<std::endl;
716 return ;
717 }
718
719 target_blk->data_index( mapped_p, target_data_idx);
720 unsigned source_data_idx = orbit.eyelid_cell_data_index_[i];
721 source_app_data [source_data_idx] = target_app_data [target_data_idx];
722
723 double prob = 1 - exp (- target_alpha_data[target_data_idx] * target_side_len);
724 if(extract){
725 if (current_vis_score_ && prob > 0.8 && !skip ){
726 float8 curr_float_col = to_float8(target_color_data[target_data_idx]);
727 weighted_sum += curr_float_col * current_vis_score_[target_data_idx];
728 sum_vis += current_vis_score_[target_data_idx];
729 }
730 }else{
731 float8 appearance = to_float8(target_color_data[target_data_idx]) * current_vis_score_[target_data_idx] +
732 to_float8(curr_lower_lid) * (1 - current_vis_score_[target_data_idx]);
733 source_color_data[source_data_idx]= faux_ ? color : to_apm_t(appearance);
734 if(skip)
735 source_color_data[source_data_idx]= faux_ ? color: curr_lower_lid;
736 vis_cells_.push_back(target_data_idx); //need to set the vis of this index to 1
737 }
738 }
739 }
740 }
741 }
742 if(sum_vis != 0 && extract){
743 weighted_sum /= sum_vis;
744 curr_upper_lid = to_apm_t( weighted_sum );
745 }
746 // std::cout<<"Extracted upper lid appearance in "<<t.real()/1000<<" seconds"<<std::endl;
747 }
bump_up_vis_scores()748 void boxm2_vecf_appearance_extractor::bump_up_vis_scores(){
749 // for (std::vector<unsigned>::iterator it =vis_cells_.begin() ; it != vis_cells_.end(); it++)
750 // current_vis_score_[*it] = 1;
751 }
752