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