1 #ifndef boxm2_update_using_quality_functor_h 2 #define boxm2_update_using_quality_functor_h 3 //: 4 // \file 5 #include <vector> 6 #include <limits> 7 #include <iostream> 8 #include <cmath> 9 #include <boxm2/cpp/algo/boxm2_cast_ray_function.h> 10 #include <boxm2/cpp/algo/boxm2_mog3_grey_processor.h> 11 #include <boxm2/cpp/algo/boxm2_gauss_grey_processor.h> 12 #include <vil/vil_image_view.h> 13 #ifdef _MSC_VER 14 # include <vcl_msvc_warnings.h> 15 #endif 16 17 template <boxm2_data_type APM_TYPE> 18 class boxm2_update_using_quality_pass2_functor 19 { 20 public: 21 //: "default" constructor 22 boxm2_update_using_quality_pass2_functor() = default; 23 init_data(std::vector<boxm2_data_base * > & datas,vil_image_view<float> * pre_img,vil_image_view<float> * vis_img,vil_image_view<float> * norm_img,vil_image_view<float> * quality_img)24 bool init_data(std::vector<boxm2_data_base*> & datas, 25 vil_image_view<float> * pre_img,vil_image_view<float> * vis_img, 26 vil_image_view<float> * norm_img, vil_image_view<float> * quality_img) 27 { 28 aux_data_=new boxm2_data<BOXM2_AUX>(datas[0]->data_buffer(),datas[0]->buffer_length(),datas[0]->block_id()); 29 alpha_data_=new boxm2_data<BOXM2_ALPHA>(datas[1]->data_buffer(),datas[1]->buffer_length(),datas[1]->block_id()); 30 mog3_data_=new boxm2_data<APM_TYPE>(datas[2]->data_buffer(),datas[2]->buffer_length(),datas[2]->block_id()); 31 pre_img_=pre_img; 32 vis_img_=vis_img; 33 norm_img_=norm_img; 34 quality_img_ = quality_img; 35 return true; 36 } 37 38 inline bool step_cell(float seg_len,int index,unsigned i,unsigned j, float abs_depth=0.0f) 39 { 40 boxm2_data<BOXM2_AUX>::datatype & aux=aux_data_->data()[index]; 41 if (aux[0]<1e-10f)return true; 42 float mean_obs=aux[1]/aux[0]; 43 float PI=boxm2_processor_type<APM_TYPE>::type::prob_density(mog3_data_->data()[index], mean_obs); 44 45 //if (PI==std::numeric_limits<float>::infinity()) 46 float vis=(*vis_img_)(i,j); 47 float pre=(*pre_img_)(i,j); 48 boxm2_data<BOXM2_ALPHA>::datatype alpha=alpha_data_->data()[index]; 49 float omega=(1-std::exp(-seg_len*alpha)); 50 if ((*norm_img_)(i,j)>1e-10f) 51 { 52 aux[2]+=( ((pre+vis*PI)*(*quality_img_)(i,j) + (1.0f - (*quality_img_)(i,j)) ) / ((*norm_img_)(i,j)*(*quality_img_)(i,j) + (1.0f - (*quality_img_)(i,j))) * seg_len); 53 //aux[3]+=vis*(*quality_img_)(i,j)*seg_len; 54 aux[3] += ( (pre+vis*PI)*(*quality_img_)(i,j) / ( (pre+vis*PI)*(*quality_img_)(i,j) + (1.0f - (*quality_img_)(i,j)) ) )*seg_len; 55 } 56 pre+=vis*omega*PI; 57 vis=vis*(1-omega); 58 (*vis_img_)(i,j)=vis; 59 (*pre_img_)(i,j)=pre; 60 return true; 61 } 62 private: 63 boxm2_data<BOXM2_AUX> * aux_data_; 64 boxm2_data<BOXM2_ALPHA> * alpha_data_; 65 boxm2_data<APM_TYPE> * mog3_data_; 66 vil_image_view<float> * pre_img_; 67 vil_image_view<float> * vis_img_; 68 vil_image_view<float> * norm_img_; 69 vil_image_view<float> * quality_img_; 70 }; 71 72 template <boxm2_data_type APM_TYPE> 73 class boxm2_update_using_quality_functor 74 { 75 public: 76 //: "default" constructor 77 boxm2_update_using_quality_functor() = default; 78 init_data(std::vector<boxm2_data_base * > & datas,float block_len,int max_levels)79 bool init_data(std::vector<boxm2_data_base*> & datas, float block_len, int max_levels) 80 { 81 aux_data_=new boxm2_data<BOXM2_AUX>(datas[0]->data_buffer(),datas[0]->buffer_length(),datas[0]->block_id()); 82 alpha_data_=new boxm2_data<BOXM2_ALPHA>(datas[1]->data_buffer(),datas[1]->buffer_length(),datas[1]->block_id()); 83 mog3_data_=new boxm2_data<APM_TYPE>(datas[2]->data_buffer(),datas[2]->buffer_length(),datas[2]->block_id()); 84 nobs_data_=new boxm2_data<BOXM2_NUM_OBS>(datas[3]->data_buffer(),datas[3]->buffer_length(),datas[3]->block_id()); 85 alpha_min_ = -std::log(1.f-0.0001f)/float(block_len/max_levels); 86 return true; 87 } process_cell(int index)88 inline bool process_cell(int index) 89 { 90 boxm2_data<BOXM2_AUX>::datatype & aux=aux_data_->data()[index]; 91 92 if (aux[0]>1e-8f) 93 { 94 float beta=aux[2]/aux[0]; 95 float vis =aux[3]/aux[0]; 96 float mean_obs=aux[1]/aux[0]; 97 98 boxm2_data<BOXM2_ALPHA>::datatype & alpha=alpha_data_->data()[index]; 99 100 alpha=std::max(alpha_min_,alpha*beta); 101 typename boxm2_data<APM_TYPE>::datatype & mog3=mog3_data_->data()[index]; 102 boxm2_data<BOXM2_NUM_OBS>::datatype & nobs=nobs_data_->data()[index]; 103 vnl_vector_fixed<float,4> nobs_float; 104 nobs_float[0]=(float)nobs[0]; 105 nobs_float[1]=(float)nobs[1]; 106 nobs_float[2]=(float)nobs[2]; 107 //: converting flot to short 108 nobs_float[3]=((float)nobs[3])/100.0f; 109 //boxm2_processor_type<BOXM2_MOG3_GREY>::type::update_gauss_mixture_3(mog3,nobs_float, mean_obs,vis,0.09f, 0.03f); 110 //boxm2_processor_type<APM_TYPE>::type::update_gauss_mixture_3(mog3,nobs_float, mean_obs,vis,0.09f, 0.03f); 111 112 //update only if not classified as shadow 113 //float TMATCH = 2.5f; 114 //float tsq = TMATCH*TMATCH; 115 //if (mean_obs*mean_obs >= shadow_sigma_*shadow_sigma_*tsq) { // shadow mean is always zero 116 boxm2_processor_type<APM_TYPE>::type::update_app_model(mog3,nobs_float, mean_obs,vis,0.09f, 0.03f); 117 //} 118 nobs[0]=(unsigned short)nobs_float[0]; 119 nobs[1]=(unsigned short)nobs_float[1]; 120 nobs[2]=(unsigned short)nobs_float[2]; 121 nobs[3]=(unsigned short)(nobs_float[3]*100.0f); 122 aux[0]=0.0; 123 aux[1]=0.0; 124 aux[2]=0.0; 125 aux[3]=0.0; 126 } 127 return true; 128 } 129 private: 130 boxm2_data<BOXM2_AUX> * aux_data_; 131 boxm2_data<BOXM2_ALPHA> * alpha_data_; 132 boxm2_data<APM_TYPE> * mog3_data_; 133 boxm2_data<BOXM2_NUM_OBS> * nobs_data_; 134 float alpha_min_; 135 float shadow_sigma_; 136 }; 137 138 #endif // boxm2_update_using_quality_functor_h 139