1 #ifndef boxm2_change_detection_functor_h 2 #define boxm2_change_detection_functor_h 3 //: 4 // \file 5 6 #include <iostream> 7 #include <boxm2/boxm2_data_traits.h> 8 #include <boxm2/cpp/algo/boxm2_cast_ray_function.h> 9 #include <boxm2/cpp/algo/boxm2_mog3_grey_processor.h> 10 #include <vil/algo/vil_gauss_filter.h> 11 #ifdef DEBUG 12 #ifdef _MSC_VER 13 # include <vcl_msvc_warnings.h> 14 #endif 15 #endif 16 17 class boxm2_change_detection_functor 18 { 19 public: 20 //: "default" constructor 21 boxm2_change_detection_functor() = default; 22 init_data(std::vector<boxm2_data_base * > & datas,vil_image_view<float> * in_img,vil_image_view<float> * expected,vil_image_view<float> * vis_img)23 bool init_data(std::vector<boxm2_data_base*> & datas,vil_image_view<float> * in_img, vil_image_view<float> * expected, vil_image_view<float>* vis_img) 24 { 25 alpha_data_=new boxm2_data<BOXM2_ALPHA>(datas[0]->data_buffer(),datas[0]->buffer_length(),datas[0]->block_id()); 26 mog3_data_=new boxm2_data<BOXM2_MOG3_GREY>(datas[1]->data_buffer(),datas[1]->buffer_length(),datas[1]->block_id()); 27 expected_img_=expected; 28 vis_img_ =vis_img; 29 in_img_ =in_img; 30 return true; 31 } 32 33 inline bool step_cell(float seg_len,int index,unsigned i, unsigned j, float abs_depth=0.0) 34 { 35 boxm2_data<BOXM2_ALPHA>::datatype alpha=alpha_data_->data()[index]; 36 float vis=(*vis_img_)(i,j); 37 float exp_int=(*expected_img_)(i,j); 38 float intensity=(*in_img_)(i,j); 39 float curr_p=(1-std::exp(-alpha*seg_len))*vis; 40 exp_int+=curr_p*boxm2_processor_type<BOXM2_MOG3_GREY>::type::prob_density(mog3_data_->data()[index],intensity); 41 (*expected_img_)(i,j)=exp_int; 42 vis*=std::exp(-alpha*seg_len); 43 (*vis_img_)(i,j)=vis; 44 return true; 45 } 46 private: 47 boxm2_data<BOXM2_ALPHA> * alpha_data_; 48 boxm2_data<BOXM2_MOG3_GREY> * mog3_data_; 49 vil_image_view<float> *expected_img_; 50 vil_image_view<float> *vis_img_; 51 vil_image_view<float> *in_img_; 52 }; 53 54 //: Functor class to normalize expected image 55 class normalize_foreground_probability_density 56 { 57 public: 58 normalize_foreground_probability_density() = default; 59 operator()60 float operator()(float &pix) const 61 { 62 return 1.f/(1.f+pix)-0.5f*std::min(pix,1.f/pix); 63 } 64 }; 65 66 class boxm2_change_detection_with_uncertainity_functor 67 { 68 public: 69 70 //: "default" constructor boxm2_change_detection_with_uncertainity_functor(unsigned ni,unsigned nj)71 boxm2_change_detection_with_uncertainity_functor(unsigned ni, unsigned nj) 72 { 73 ni_=ni; 74 nj_=nj; 75 76 //: used only inside the functor. 77 vis_img_ =new vil_image_view<float>(ni_,nj_); 78 expected_img_ =new vil_image_view<float>(ni_,nj_); 79 dist_image_ =new vil_image_view<double>(ni_,nj_); 80 running_weight_=new vil_image_view<float>(ni_,nj_); 81 vis_img_->fill(1.0f); 82 expected_img_->fill(0.0f); 83 running_weight_->fill(0.0f); 84 dist_image_->fill(0.0f); 85 } 86 set_data(std::vector<boxm2_data_base * > & datas,vil_image_view<float> * in_img,vil_image_view<float> * change_image)87 bool set_data(std::vector<boxm2_data_base*> & datas, 88 vil_image_view<float> * in_img, 89 vil_image_view<float> * change_image) 90 { 91 alpha_data_ =new boxm2_data<BOXM2_ALPHA>(datas[0]->data_buffer(),datas[0]->buffer_length(),datas[0]->block_id()); 92 mog3_data_ =new boxm2_data<BOXM2_MOG3_GREY>(datas[1]->data_buffer(),datas[1]->buffer_length(),datas[1]->block_id()); 93 94 95 in_img_=in_img; 96 change_image_=change_image; 97 98 return true; 99 } 100 step_cell(float seg_len,int index,unsigned i,unsigned j,float abs_depth)101 inline bool step_cell(float seg_len,int index,unsigned i, unsigned j, float abs_depth) 102 { 103 boxm2_data<BOXM2_ALPHA>::datatype alpha=alpha_data_->data()[index]; 104 boxm2_data<BOXM2_MOG3_GREY>::datatype mog3=mog3_data_->data()[index]; 105 106 float vis=(*vis_img_)(i,j); 107 float curr_p=(1-std::exp(-alpha*seg_len))*vis; 108 109 vnl_vector_fixed<unsigned char,8> updated_exp_distribution((unsigned char)0); 110 111 (*expected_img_)(i,j)=(*expected_img_)(i,j)+boxm2_processor_type<BOXM2_MOG3_GREY>::type::expected_color(mog3)*curr_p; 112 (*change_image_)(i,j)=(*change_image_)(i,j)+boxm2_processor_type<BOXM2_MOG3_GREY>::type::prob_density(mog3,(*in_img_)(i,j))*curr_p; 113 //: representing 8 bytes of data aby double 114 unsigned img_index=j*ni_+i; 115 unsigned char * exp_distribution_array=reinterpret_cast<unsigned char *>(dist_image_->top_left_ptr()+img_index); 116 vnl_vector_fixed<unsigned char,8> exp_distribution(exp_distribution_array); 117 float w2=(*running_weight_)(i,j); 118 119 //: merge mixtures only if the weight is non zero. 120 if (w2<=0.0f) 121 updated_exp_distribution=mog3_data_->data()[index]; 122 else 123 boxm2_processor_type<BOXM2_MOG3_GREY>::type::merge_mixtures(mog3,curr_p,exp_distribution,w2,updated_exp_distribution); 124 #ifdef DEBUG 125 std::cout<<'['; 126 for (unsigned k=0;k<8;k++) 127 std::cout<<(int)exp_distribution[k]<<','; 128 std::cout<<"] *"<<w2<<" +\n["; 129 for (unsigned k=0;k<8;k++) 130 std::cout<<(int)mog3_data_->data()[index][k]<<','; 131 std::cout<<"]* "<<curr_p<<" =\n ["; 132 for (unsigned k=0;k<8;k++) 133 std::cout<<(int)updated_exp_distribution[k]<<','; 134 std::cout<<"]\n\n"; 135 #endif 136 (*running_weight_)(i,j)=curr_p+w2; 137 138 //: representing 8 bytes of data aby double 139 double * final=reinterpret_cast<double *>(updated_exp_distribution.data_block()); 140 (*dist_image_)(i,j)=(*final); 141 142 vis*=std::exp(-alpha*seg_len); 143 (*vis_img_)(i,j)=vis; 144 return true; 145 } 146 finish()147 void finish() 148 { 149 int count=-1; 150 float sigma =2.0f; 151 for (unsigned j=0;j<nj_;j++) 152 for (unsigned i=0;i<ni_;i++) 153 (*expected_img_)(i,j)+=(*vis_img_)(i,j)*0.5f; 154 155 vil_image_view<float> expblur(expected_img_->ni(), expected_img_->nj()); 156 vil_gauss_filter_2d((*expected_img_), expblur, sigma, (unsigned)(3*sigma+0.01f)); 157 158 for (unsigned j=0;j<nj_;j++) 159 for (unsigned i=0;i<ni_;i++) 160 { 161 float pb=(*change_image_)(i,j); 162 pb+=(*vis_img_)(i,j)*1.0f; 163 float bf=1.f/(1.f+pb)-0.5f*std::min(pb,1.f/pb); 164 165 ++count; 166 unsigned char * exp_distribution_array=reinterpret_cast<unsigned char *>(dist_image_->top_left_ptr()+count); 167 vnl_vector_fixed<unsigned char,8> exp_distribution(exp_distribution_array); 168 float pr=boxm2_processor_type<BOXM2_MOG3_GREY>::type::prob_density(exp_distribution,expblur(i,j)); 169 float br=pr/(1.f+pr)-0.5f*std::min(pr,1.f/pr); 170 171 (*change_image_)(i,j)=bf*br; 172 } 173 } 174 private: 175 boxm2_data<BOXM2_ALPHA> * alpha_data_; 176 boxm2_data<BOXM2_MOG3_GREY> * mog3_data_; 177 vil_image_view<float> *in_img_; 178 vil_image_view<float> *change_image_; 179 180 vil_image_view<float> *expected_img_; 181 vil_image_view<float> *vis_img_; 182 vil_image_view<double>* dist_image_; 183 vil_image_view<float> * running_weight_; 184 unsigned ni_; 185 unsigned nj_; 186 }; 187 188 189 #endif 190