visual-tracking-control
VisualUpdateParticles.cpp
Go to the documentation of this file.
2 
3 #include <cmath>
4 #include <exception>
5 #include <functional>
6 #include <iostream>
7 #include <utility>
8 #include <vector>
9 
10 #include <opencv2/core/core.hpp>
11 #include <opencv2/core/cuda.hpp>
12 #include <opencv2/core/eigen.hpp>
13 #include <opencv2/cudaimgproc.hpp>
14 #include <opencv2/imgproc/imgproc.hpp>
15 
16 using namespace bfl;
17 using namespace cv;
18 using namespace Eigen;
19 
20 
21 VisualUpdateParticles::VisualUpdateParticles(std::unique_ptr<VisualProprioception> observation_model) noexcept :
22  VisualUpdateParticles(std::move(observation_model), 0.001, 1) { }
23 
24 
25 VisualUpdateParticles::VisualUpdateParticles(std::unique_ptr<VisualProprioception> observation_model, const double likelihood_gain) noexcept :
26  VisualUpdateParticles(std::move(observation_model), likelihood_gain, 1) { }
27 
28 
29 VisualUpdateParticles::VisualUpdateParticles(std::unique_ptr<VisualProprioception> observation_model, const double likelihood_gain, const int num_cuda_stream) noexcept :
30  observation_model_(std::move(observation_model)),
31  likelihood_gain_(likelihood_gain),
32  num_cuda_stream_(num_cuda_stream),
33  num_img_stream_(observation_model_->getOGLTilesNumber()),
34  cuda_stream_(std::vector<cuda::Stream>(num_cuda_stream))
35 {
36  int block_size = 16;
37  int bin_number = 9;
38  unsigned int img_width = observation_model_->getCamWidth();
39  unsigned int img_height = observation_model_->getCamHeight();
40  unsigned int ogl_tiles_cols = observation_model_->getOGLTilesCols();
41  unsigned int ogl_tiles_rows = observation_model_->getOGLTilesRows();
42  unsigned int feature_dim = (img_width/block_size*2-1) * (img_height/block_size*2-1) * bin_number * 4;
43 
44  cuda_hog_ = cuda::HOG::create(Size(img_width, img_height), Size(block_size, block_size), Size(block_size/2, block_size/2), Size(block_size/2, block_size/2), bin_number);
45  cuda_hog_->setDescriptorFormat(cuda::HOG::DESCR_FORMAT_ROW_BY_ROW);
46  cuda_hog_->setGammaCorrection(true);
47  cuda_hog_->setWinStride(Size(img_width, img_height));
48 
49  for (int s = 0; s < num_cuda_stream_; ++s)
50  {
51  hand_rendered_.emplace_back (Mat( Size(img_width * ogl_tiles_cols, img_height* ogl_tiles_rows), CV_8UC3));
52  cuda_img_.emplace_back (cuda::GpuMat(Size(img_width * ogl_tiles_cols, img_height* ogl_tiles_rows), CV_8UC3));
53  cuda_img_alpha_.emplace_back (cuda::GpuMat(Size(img_width * ogl_tiles_cols, img_height* ogl_tiles_rows), CV_8UC4));
54  cuda_descriptors_.emplace_back(cuda::GpuMat(Size(num_img_stream_, feature_dim), CV_32F ));
55  cpu_descriptors_.emplace_back (Mat( Size(num_img_stream_, feature_dim), CV_32F ));
56  }
57 }
58 
59 
61 
62 
63 void VisualUpdateParticles::innovation(const Ref<const MatrixXf>& pred_states, cv::InputArray measurements, Ref<MatrixXf> innovations)
64 {
65  for (int s = 0; s < num_cuda_stream_; ++s)
66  observation_model_->observe(pred_states.block(0, s * num_img_stream_, 7, num_img_stream_), hand_rendered_[s]);
67 
68  for (int s = 0; s < num_cuda_stream_; ++s)
69  {
70  cuda_img_[s].upload(hand_rendered_[s], cuda_stream_[s]);
71  cuda::cvtColor(cuda_img_[s], cuda_img_alpha_[s], COLOR_BGR2BGRA, 4, cuda_stream_[s]);
72  cuda_hog_->compute(cuda_img_alpha_[s], cuda_descriptors_[s], cuda_stream_[s]);
73  }
74 
75  for (int s = 0; s < num_cuda_stream_; ++s)
76  {
77  cuda_stream_[s].waitForCompletion();
78 
79  cuda_descriptors_[s].download(cpu_descriptors_[s], cuda_stream_[s]);
80 
81  for (int i = 0; i < num_img_stream_; ++i)
82  {
83  float sum_diff = 0;
84  {
85  auto it_cam = (static_cast<const std::vector<float>*>(measurements.getObj()))->begin();
86  auto it_cam_end = (static_cast<const std::vector<float>*>(measurements.getObj()))->end();
87  int j = 0;
88  while (it_cam < it_cam_end)
89  {
90  sum_diff += abs((*it_cam) - cpu_descriptors_[s].at<float>(i, j));
91 
92  ++it_cam;
93  ++j;
94  }
95  }
96 
97  innovations(s * num_img_stream_ + i, 0) = sum_diff;
98  }
99  }
100 }
101 
102 
103 double VisualUpdateParticles::likelihood(const Ref<const MatrixXf>& innovations)
104 {
105  return exp(-likelihood_gain_ * innovations.cast<double>().coeff(0, 0));
106 }
107 
108 
110 {
111  return *observation_model_;
112 }
113 
114 
115 void VisualUpdateParticles::setVisualObservationModel(std::unique_ptr<VisualObservationModel> visual_observation_model)
116 {
117  throw std::runtime_error("ERROR::VISUALUPDATEPARTICLES::SETVISUALOBSERVATIONMODEL\nERROR:\n\tClass under development. Do not invoke this method.");
118 
119  VisualObservationModel* tmp_observation_model = visual_observation_model.release();
120 
121  observation_model_ = std::unique_ptr<VisualProprioception>(dynamic_cast<VisualProprioception*>(tmp_observation_model));
122 }
123 
124 
125 void VisualUpdateParticles::correctStep(const Ref<const MatrixXf>& pred_states, const Ref<const VectorXf>& pred_weights, cv::InputArray measurements,
126  Ref<MatrixXf> cor_states, Ref<VectorXf> cor_weights)
127 {
128  VectorXf innovations(pred_states.cols());
129  innovation(pred_states, measurements, innovations);
130 
131  cor_states = pred_states;
132 
133  for (int i = 0; i < innovations.rows(); ++i)
134  {
135  cor_weights(i) = pred_weights(i) * likelihood(innovations.row(i));
136 
137  if (cor_weights(i) <= 0)
138  cor_weights(i) = std::numeric_limits<float>::min();
139  }
140 }
void innovation(const Eigen::Ref< const Eigen::MatrixXf > &pred_states, cv::InputArray measurements, Eigen::Ref< Eigen::MatrixXf > innovations) override
VisualUpdateParticles(std::unique_ptr< VisualProprioception > observation_model) noexcept
void correctStep(const Eigen::Ref< const Eigen::MatrixXf > &pred_states, const Eigen::Ref< const Eigen::VectorXf > &pred_weights, cv::InputArray measurements, Eigen::Ref< Eigen::MatrixXf > cor_states, Eigen::Ref< Eigen::VectorXf > cor_weights) override
void setVisualObservationModel(std::unique_ptr< bfl::VisualObservationModel > visual_observation_model) override
double likelihood(const Eigen::Ref< const Eigen::MatrixXf > &innovations) override
bfl::VisualObservationModel & getVisualObservationModel() override