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