1 // This is brl/bseg/brec/brec_part_gaussian.h 2 #ifndef brec_part_gaussian_h_ 3 #define brec_part_gaussian_h_ 4 //: 5 // \file 6 // \brief class to represent primitive parts as non-isotropic gaussian filters oriented in various ways 7 // 8 // \author Ozge C Ozcanli (ozge@lems.brown.edu) 9 // \date Oct 16, 2008 10 // 11 // \verbatim 12 // Modifications 13 // <none yet> 14 // \endverbatim 15 16 #include <vector> 17 #include <iostream> 18 #include "brec_part_base.h" 19 #ifdef _MSC_VER 20 # include <vcl_msvc_warnings.h> 21 #endif 22 #include "brec_part_gaussian_sptr.h" 23 24 #include <vnl/vnl_vector_fixed.h> 25 26 #include <vil/vil_image_resource_sptr.h> 27 #include <vil/vil_image_view.h> 28 #include <vbl/vbl_array_2d.h> 29 #include <bsta/bsta_weibull.h> 30 31 #include <vul/vul_psfile.h> 32 33 class brec_part_gaussian : public brec_part_instance 34 { 35 public: 36 37 brec_part_gaussian(float x, float y, float strength, float lambda0, float lambda1, float theta, bool bright, unsigned type); 38 39 //: the following constructor should only be used during parsing 40 brec_part_gaussian(); 41 42 bool mark_receptive_field(vil_image_view<vxl_byte>& img, unsigned plane) override; 43 bool mark_center(vil_image_view<vxl_byte>& img, unsigned plane) override; 44 bool mark_receptive_field(vil_image_view<float>& img, float val) override; 45 bool mark_center(vil_image_view<float>& img, float val) override; 46 47 vnl_vector_fixed<float,2> direction_vector(void) override; // return a unit vector that gives direction of this instance in the image 48 49 //: Print an ascii summary to the stream print_summary(std::ostream & os)50 void print_summary(std::ostream &os) const override 51 { 52 os << "x: " << x_ << " y: " << y_ << " strength: " << strength_ << std::endl 53 << "lambda0: " << lambda0_ << " lambda1: " << lambda1_ << " theta: " << theta_ << std::endl; 54 } 55 56 brec_part_gaussian* cast_to_gaussian(void) override; 57 58 bxml_data_sptr xml_element() override; 59 bool xml_parse_element(bxml_data_sptr data) override; 60 void initialize_mask(); 61 62 //: run the operator on \p mean_img and use the response to construct a response model for this operator 63 // The \p mean_img and the \p std_dev_img are float images with values in [0,1] range 64 // They are supposedly extracted from the background model of the scene 65 bool construct_bg_response_model(vil_image_view<float>& mean_img, vil_image_view<float>& std_dev_img, vil_image_view<float> &lambda_img, vil_image_view<float> &k_img); 66 bool construct_bg_response_model_gauss(vil_image_view<float>& mean_img, vil_image_view<float>& std_dev_img, vil_image_view<float> &mu_img, vil_image_view<float> &sigma_img); 67 68 //: collect operator responses from the input image 69 // Use responses from class regions to estimate lambda and k for the class response model 70 // Use responses from non-class regions to estimate lambda and k for the non-class response model 71 // Class and non-class regions are specified by the class_prob_img which is a float image with values in [0,1] range 72 bool construct_class_response_models(vil_image_view<float>& img, vil_image_view<float>& class_prob_img, 73 vil_image_view<bool>& mask_img, double &lambda, double &k, double &lambda_non_class, double &k_non_class); 74 75 //: collect operator responses from the input image's foreground regions 76 // The input \p img and the \p fg_prob_img (foreground probability image) are float images with values in [0,1] range 77 // Assumes histogram is initialized 78 bool update_response_hist(vil_image_view<float>& img, vil_image_view<float>& fg_prob_img, vil_image_view<bool>& mask_img, bsta_histogram<float>& fg_h) override; 79 //: for gaussian operators we use weibull distribution as the parametric model 80 bool fit_distribution_to_response_hist(bsta_histogram<float>& fg_h) override; 81 82 //: use the background \p mean_img and \p std_dev_img to construct response model for background and calculate posterior ratio of foreground and background 83 // Assumes that \p k_ and \p lambda_ for the foreground response model have already been set 84 bool update_foreground_posterior(vil_image_view<float>& inp, 85 vil_image_view<float>& fg_prob_img, 86 vil_image_view<bool>& mask, 87 vil_image_view<float>& mean_img, 88 vil_image_view<float>& std_dev_img) override; 89 90 //: run the operator on the input \p img rotated by the given angle and save the instances in the input vector 91 // Use the response models saved in the \p model_dir to set the operator response strength which is equivalent to posterior probability of this pixel being foreground given the operator response 92 // i.e. p(x in foreground | operator response) = p(operator response | x in foreground) / [p(operator response | x in foreground) + p(operator response | x in background)] 93 // \return all the instances which have a posterior larger than zero (--> no thresholding, return "all" the responses) 94 // \p fg_prob_img is the probability of being foreground for each pixel 95 // \p pb_zero is the constant required for the background response model (probability of zero response) 96 bool extract(vil_image_view<float>& img, vil_image_view<float>& fg_prob_img, float rot_angle, const std::string& model_dir, std::vector<brec_part_instance_sptr>& instances, float prior_class); 97 98 //: extract and set rho to class probability density of the response 99 // Assumes weibull parameters have already been fitted (i.e. fitted_weibull_ = true) 100 // This method is to be used during training and it returns an instance if class_prob >= 0.9 101 bool extract(vil_image_view<float>& img, vil_image_view<float>& class_prob_image, float rot_angle, std::vector<brec_part_instance_sptr>& instances); 102 103 //: find P(alpha in foreground): the probability that this operator alpha is in foreground 104 // P(alpha in foreground) = argmax_x_kl P(x_kl in foreground) where x_kl is in mask of operator alpha 105 float fg_prob_operator(vil_image_view<float>& fg_prob_img, unsigned i, unsigned j); 106 //: find P(alpha in background): the probability that this operator alpha is in background 107 // P(alpha in background) = 1-argmax_x_kl P(x_kl in foreground) where x_kl is in mask of operator alpha 108 float bg_prob_operator(vil_image_view<float>& fg_prob_img, unsigned i, unsigned j); 109 110 std::string string_identifier(); 111 112 public: 113 float lambda0_; // axis 114 float lambda1_; 115 float theta_; // orientation angle (in degrees) 116 bool bright_; 117 118 //: parameter to define how big a receptive field will be marked, default is 0.01 so 1% of the tails of the gaussian is cut off 119 float cutoff_percentage_; 120 121 vbl_array_2d<bool> mask_; 122 int rj_, ri_; 123 124 float lambda_, k_; // we fit Weibull distribution to Gaussian operators' response model 125 float lambda_non_class_, k_non_class_; // we fit Weibull distribution to Gaussian operators' response model 126 bool fitted_weibull_; 127 }; 128 129 //: extracts only one type of primitive and adds to the part vector 130 // Strength_threshold in [0,1] - min strength to declare the part as detected 131 bool extract_gaussian_primitives(const vil_image_resource_sptr& img, float lambda0, float lambda1, float theta, bool bright, float cutoff_percentage, float strength_threshold, unsigned type, std::vector<brec_part_instance_sptr>& parts); 132 133 bool draw_gauss_to_ps(vul_psfile& ps, const brec_part_gaussian_sptr& pi, float x, float y, float cr, float cg, float cb); 134 135 #endif // brec_part_gaussian_h_ 136