vision
KinectFusionImpl.hpp
1 // -*- mode:C++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil -*-
2 
3 #ifndef __KINECT_FUSION_IMPL_HPP__
4 #define __KINECT_FUSION_IMPL_HPP__
5 
6 #include "KinectFusion.hpp"
7 
8 #include <mutex>
9 #include <type_traits>
10 
11 #include <yarp/os/LogStream.h>
12 #include <yarp/cv/Cv.h>
13 
14 #include "LogComponent.hpp"
15 
16 namespace roboticslab
17 {
18 
19 template <typename T>
21 {
22 public:
23  KinectFusionImpl(const cv::Ptr<T> & other) : handle(other)
24  {
25  cv::setUseOptimized(true);
26  }
27 
28  void getCloud(yarp::sig::PointCloudXYZNormalRGBA & cloudWithNormals) const override
29  {
30  cv::UMat points, normals;
31 
32  mtx.lock();
33  handle->getCloud(points, normals);
34  mtx.unlock();
35 
36  cv::Mat _points = points.getMat(cv::ACCESS_FAST); // no memcpy
37  cv::Mat _normals = normals.getMat(cv::ACCESS_FAST); // no memcpy
38 
39  cloudWithNormals.resize(points.rows);
40 
41  for (auto i = 0; i < points.rows; i++)
42  {
43  const auto & point = _points.at<cv::Vec4f>(i);
44  const auto & normal = _normals.at<cv::Vec4f>(i);
45  cloudWithNormals(i) = {{point[0], point[1], point[2]}, {normal[0], normal[1], normal[2]}, 0};
46  }
47  }
48 
49  void getPoints(yarp::sig::PointCloudXYZ & cloud) const override
50  {
51  cv::UMat points;
52 
53  mtx.lock();
54  handle->getPoints(points);
55  mtx.unlock();
56 
57  cv::Mat _points = points.getMat(cv::ACCESS_FAST); // no memcpy
58  auto data = const_cast<const char *>(reinterpret_cast<char *>(_points.data));
59 
60  cloud.fromExternalPC(data, yarp::sig::PointCloudBasicType::PC_XYZ_DATA, _points.rows, 1);
61  }
62 
63  void getPose(yarp::sig::Matrix & pose) const override
64  {
65  mtx.lock();
66  const auto & affine = handle->getPose().matrix;
67  mtx.unlock();
68 
69  pose.resize(4, 4);
70 
71  for (int i = 0; i < 4; i++)
72  {
73  for (int j = 0; j < 4; j++)
74  {
75  pose(i, j) = affine(i, j);
76  }
77  }
78  }
79 
80  bool update(const yarp::sig::ImageOf<yarp::sig::PixelFloat> & depthFrame, const yarp::sig::FlexImage & colorFrame) override
81  {
82  // Cast away constness so that toCvMat accepts the YARP image. This function
83  // does not alter the inner structure of PixelFloat images anyway.
84  auto & nonConstDepthFrame = const_cast<yarp::sig::ImageOf<yarp::sig::PixelFloat> &>(depthFrame);
85  cv::Mat mat = yarp::cv::toCvMat(nonConstDepthFrame);
86 
87  cv::UMat umat;
88  mat.convertTo(umat, mat.type(), 1000.0); // OpenCV uses milimeters
89 
90  std::lock_guard lock(mtx);
91  return handle->update(umat);
92  }
93 
94  void reset() override
95  {
96  std::lock_guard lock(mtx);
97  handle->reset();
98  }
99 
100  void render(yarp::sig::FlexImage & image) const override
101  {
102  cv::UMat umat;
103 
104  mtx.lock();
105  handle->render(umat);
106  mtx.unlock();
107 
108  cv::Mat mat = umat.getMat(cv::ACCESS_FAST); // no memcpy
109  const auto & bgr = yarp::cv::fromCvMat<yarp::sig::PixelBgra>(mat); // no conversion
110  image.copy(bgr); // bgra to grayscale/rgb (single step convert+assign)
111  }
112 
113 private:
114  cv::Ptr<T> handle;
115  mutable std::mutex mtx;
116 };
117 
118 template <typename T>
119 T getValue(const yarp::os::Value & v)
120 {
121  if constexpr (std::is_integral_v<T>)
122  {
123  return v.asInt32();
124  }
125  else if constexpr (std::is_floating_point_v<T>)
126  {
127  return v.asFloat64();
128  }
129  else
130  {
131  // https://stackoverflow.com/a/64354296/10404307
132  static_assert(!sizeof(T), "Unsupported type");
133  }
134 }
135 
136 template <typename TParams, typename TRet>
137 void updateParam(TParams & params, TRet TParams::* param, const yarp::os::Searchable & config,
138  const std::string & name, const std::string & description)
139 {
140  auto && log = yCInfo(KINFU);
141  log << name + ":";
142 
143  if (config.check(name, description))
144  {
145  params.*param = getValue<TRet>(config.find(name));
146  }
147  else
148  {
149  log << "(DEFAULT):";
150  }
151 
152  log << params.*param;
153 }
154 
155 } // namespace roboticslab
156 
157 #endif // __KINECT_FUSION_IMPL_HPP__
Definition: KinectFusionImpl.hpp:21
Definition: KinectFusion.hpp:18
The main, catch-all namespace for Robotics Lab UC3M.
Definition: groups.dox:5