ed_sensor_integration
renderer.cpp
Go to the documentation of this file.
1 #include "ed/kinect/renderer.h"
2 
3 #include <ed/entity.h>
4 #include <rgbd/view.h>
5 
6 #include <geolib/Shape.h>
7 
8 #include <opencv2/highgui/highgui.hpp>
9 
10 // ----------------------------------------------------------------------------------------------------
11 
12 namespace
13 {
14 
15 class SampleRenderResult : public geo::RenderResult
16 {
17 
18 public:
19 
20  SampleRenderResult(cv::Mat& z_buffer, std::vector<unsigned int>& pixels)
21  : geo::RenderResult(z_buffer.cols, z_buffer.rows), z_buffer_(z_buffer), pixels_(pixels)
22  {
23  }
24 
25  void renderPixel(int x, int y, float depth, int /*i_triangle*/)
26  {
27  float old_depth = z_buffer_.at<float>(y, x);
28  if (old_depth == 0)
29  {
30  z_buffer_.at<float>(y, x) = depth;
31  pixels_.push_back(y * z_buffer_.cols + x);
32  }
33  else if (depth < old_depth)
34  {
35  z_buffer_.at<float>(y, x) = depth;
36  }
37  }
38 
39 protected:
40  cv::Mat& z_buffer_; // Depth image
41  std::vector<unsigned int>& pixels_; // Maps index of occupied pixels to actual pixel position
42 
43 };
44 
45 }
46 
47 // ----------------------------------------------------------------------------------------------------
48 
49 void fitZRP(const geo::Shape& shape, const geo::Pose3D& shape_pose, const rgbd::Image& image,
50  const geo::Pose3D& sensor_pose, geo::Pose3D& updated_sensor_pose)
51 {
52  rgbd::View view(image, 80);
53 
54  const geo::DepthCamera& rasterizer = view.getRasterizer();
55 
56  unsigned int width = view.getWidth();
57  unsigned int height = view.getHeight();
58 
60  pixels.reserve(width * height);
61 
62  // Create a resized version of the sensor depth image
63  cv::Mat sensor_depth_img(height, width, CV_32FC1, 0.0);
64  for (uint y = 0; y < height; ++y)
65  for (uint x = 0; x < width; ++x)
66  sensor_depth_img.at<float>(y, x) = view.getDepth(x, y);
67 
68  double min_error = 1e9; // TODO
69 
70  for(double droll = -0.0; droll <= 0.0; droll += 0.005)
71  {
72  for(double dpitch = -0.0; dpitch <= 0.0; dpitch += 0.005)
73  {
74  geo::Matrix3 m;
75  m.setRPY(droll, dpitch, 0);
76 
77  geo::Pose3D test_pose;
78  test_pose.t = sensor_pose.t;
79  test_pose.R = m * sensor_pose.R;
80 
81  for(double dz = -0.05; dz < 0.05; dz += 0.005)
82  {
83  test_pose.t.z = sensor_pose.t.z + dz;
84 
85  // Render shape, given the test_pose as sensor_pose
86  cv::Mat model(height, width, CV_32FC1, 0.0);
87  SampleRenderResult res(model, pixels);
89  opt.setMesh(shape.getMesh(), test_pose.inverse() * shape_pose);
90  rasterizer.render(opt, res);
91 
92 // cv::imshow("sample", model / 10);
93 // cv::waitKey(3);
94 
95  int n = 0;
96  double total_error = 0;
97  for(std::vector<unsigned int>::const_iterator it = pixels.cbegin(); it != pixels.cend(); ++it)
98  {
99  unsigned int p_idx = *it;
100 
101  float ds = sensor_depth_img.at<float>(p_idx);
102 
103  if (ds > 0)
104  {
105  float dm = model.at<float>(p_idx);
106  float diff = std::abs(dm - ds);
107  if (diff > 0.01)
108  total_error += 0.1;
109  else
110  total_error += diff * diff;
111 // float err = std::min<float>(0.01, diff);
112 // total_error += (err * err);
113  ++n;
114  }
115  }
116 
117  if (n > 0)
118  {
119  double avg_error = total_error / n;
120  if (avg_error < min_error)
121  {
122  min_error = avg_error;
123  updated_sensor_pose = test_pose;
124  }
125  }
126 
127  } // sample z
128  } // sample pitch
129  } // sample roll
130 
131 }
geo::RenderOptions::setMesh
void setMesh(const geo::Mesh &mesh, const geo::Pose3D &pose=geo::Pose3D::identity())
fitZRP
void fitZRP(const geo::Shape &shape, const geo::Pose3D &shape_pose, const rgbd::Image &image, const geo::Pose3D &sensor_pose, geo::Pose3D &updated_sensor_pose)
Definition: renderer.cpp:49
geo
std::vector::reserve
T reserve(T... args)
std::vector< unsigned int >
rgbd::View::getWidth
const int & getWidth() const
Shape.h
geo::DepthCamera::render
void render(const RenderOptions &opt, RenderResult &res) const
rgbd::View::getDepth
const float & getDepth(int x, int y) const
geo::Transform3T
geo::Shape::getMesh
virtual const Mesh & getMesh() const
image
cv::Mat image
geo::Transform3T::inverse
Transform3T inverse() const
rgbd::Image
rgbd::View::getRasterizer
const geo::DepthCamera & getRasterizer() const
geo::RenderResult
geo::RenderOptions
rgbd::View::getHeight
const int & getHeight() const
geo::Transform3T::t
Vec3T< T > t
geo::Mat3T
view.h
diff
IMETHOD Twist diff(const Frame &F_a_b1, const Frame &F_a_b2, double dt=1)
std::vector::cbegin
T cbegin(T... args)
geo::Transform3T::R
Mat3T< T > R
geo::Vec3T::z
T z
geo::DepthCamera
std::vector::cend
T cend(T... args)
entity.h
renderer.h
geo::Mat3T::setRPY
void setRPY(T roll, T pitch, T yaw)
rgbd::View
geo::Shape
geo::RenderResult::renderPixel
virtual void renderPixel(int x, int y, float depth, int i_triangle)=0