licornea_tools
grabber.cc
Go to the documentation of this file.
1 #ifdef LICORNEA_WITH_LIBFREENECT2
2 
3 #include "grabber.h"
4 #include <cassert>
5 #include <iostream>
6 
7 namespace tlz {
8 
9 using namespace libfreenect2;
10 
11 int grabber::freenect2_frame_types_() const {
12  int types = 0;
13  if(has_(color) || has_(registered_color)) types |= Frame::Color;
14  if(has_(ir)) types |= Frame::Ir;
15  if(has_(depth) || has_(bigdepth) || has_(registered_color)) types |= Frame::Depth;
16  return types;
17 }
18 
19 grabber::grabber(int frame_types) :
20  frame_types_(frame_types),
21  released_(true),
22  context_(),
23  pipeline_(new CpuPacketPipeline()),
24  listener_(freenect2_frame_types_()),
25  frames_(),
26  undistorted_depth_(512, 424, 4),
27  undistorted_ir_(512, 424, 4),
28  registered_color_(512, 424, 4),
29  bigdepth_(1920, 1082, 4)
30 {
31  setGlobalLogger(nullptr);
32 
33  int device_count = context_.enumerateDevices();
34  if(device_count == 0) throw std::runtime_error("Kinect not found");
35 
36  std::string serial = context_.getDefaultDeviceSerialNumber();
37  device_ = context_.openDevice(serial, pipeline_);
38  if(! device_) throw std::runtime_error("could not open device");
39 
40  std::cout << "Kinect serial number: " << serial << std::endl;
41 
42  if(has_(color) || has_(registered_color))
43  device_->setColorFrameListener(&listener_);
44  if(has_(registered_color) || has_(depth) || has_(depth) || has_(bigdepth) || has_(ir))
45  device_->setIrAndDepthFrameListener(&listener_);
46 
47  bool ok = device_->start();
48  if(! ok) throw std::runtime_error("could not start device");
49 
50  Freenect2Device::ColorCameraParams color = device_->getColorCameraParams();
51  Freenect2Device::IrCameraParams ir = device_->getIrCameraParams();
52  registration_ = std::make_unique<Registration>(ir, color);
53 }
54 
55 
57  // don't delete pipeline (would segfault, bug in Freenect2?)
58  if(! released_) listener_.release(frames_);
59  registration_.reset();
60  device_->stop();
61  device_->close();
62 }
63 
64 
65 bool grabber::grab() {
66  const int max_wait_ms = 5000;
67  bool ok = listener_.waitForNewFrame(frames_, max_wait_ms);
68  if(! ok) return false;
69  released_ = false;
70 
71  if(has_(registered_color) || has_(bigdepth)) {
72  Frame* raw_color = frames_[Frame::Color];
73  Frame* raw_depth = frames_[Frame::Depth];
74  registration_->apply(raw_color, raw_depth, &undistorted_depth_, &registered_color_, true, &bigdepth_);
75  } else if(has_(depth)) {
76  Frame* raw_depth = frames_[Frame::Depth];
77  registration_->undistortDepth(raw_depth, &undistorted_depth_);
78  }
79  if(has_(ir)) {
80  Frame* raw_ir = frames_[Frame::Ir];
81  registration_->undistortDepth(raw_ir, &undistorted_ir_);
82  }
83 
84  return true;
85 }
86 
87 
88 void grabber::release() {
89  if(! released_) listener_.release(frames_);
90  released_ = true;
91 }
92 
93 
94 
95 cv::Mat_<cv::Vec3b> grabber::get_color_frame() {
96  assert(has_(color));
97  Frame* raw_color = frames_[Frame::Color];
98  cv::Mat_<cv::Vec4b> color_orig(1080, 1920, reinterpret_cast<cv::Vec4b*>(raw_color->data));
99  cv::Mat_<cv::Vec3b> color;
100  cv::cvtColor(color_orig, color, CV_BGRA2BGR);
101  return color;
102 }
103 
104 
105 cv::Mat_<cv::Vec3b> grabber::get_registered_color_frame() {
106  assert(has_(registered_color));
107  cv::Mat_<cv::Vec4b> color_orig(424, 512, reinterpret_cast<cv::Vec4b*>(registered_color_.data));
108  cv::Mat_<cv::Vec3b> color;
109  cv::cvtColor(color_orig, color, CV_BGRA2BGR);
110  return color;
111 }
112 
113 
114 cv::Mat_<uchar> grabber::get_ir_frame(float min_ir, float max_ir, bool undistorted) {
115  assert(has_(ir));
116  Frame* raw_ir = frames_[Frame::Ir];
117  cv::Mat_<float> ir_orig(424, 512, reinterpret_cast<float*>(undistorted ? undistorted_ir_.data : raw_ir->data));
118  float alpha = 255.0f / (max_ir - min_ir);
119  float beta = -alpha * min_ir;
120  cv::Mat_<uchar> ir;
121  cv::convertScaleAbs(ir_orig, ir, alpha, beta);
122  ir.setTo(0, (ir_orig < min_ir));
123  ir.setTo(255, (ir_orig > max_ir));
124  ir.setTo(0, (ir_orig == 0));
125  return ir;
126 }
127 
128 
129 cv::Mat_<ushort> grabber::get_original_ir_frame(bool undistorted) {
130  assert(has_(ir));
131  Frame* raw_ir = frames_[Frame::Ir];
132  cv::Mat_<float> ir_orig(424, 512, reinterpret_cast<float*>(undistorted ? undistorted_ir_.data : raw_ir->data));
133  return ir_orig;
134 }
135 
136 
137 cv::Mat_<float> grabber::get_depth_frame(bool undistorted) {
138  assert(has_(depth));
139  Frame* raw_depth = frames_[Frame::Depth];
140  cv::Mat_<float> depth = cv::Mat_<float>(424, 512, reinterpret_cast<float*>(undistorted ? undistorted_depth_.data : raw_depth->data));
141  return depth;
142 }
143 
144 
145 cv::Mat_<float> grabber::get_bigdepth_frame() {
146  cv::Mat_<float> depth_orig(1082, 1920, reinterpret_cast<float*>(bigdepth_.data));
147  return depth_orig.rowRange(1, 1081);
148 }
149 
150 
151 kinect_internal_parameters grabber::internal_parameters() {
152  auto color = device_->getColorCameraParams();
153  auto ir = device_->getIrCameraParams();
154  return from_freenect2(color, ir);
155 }
156 
157 
158 }
159 
160 #endif
cv::Mat_< uchar > get_ir_frame(float min_ir=0, float max_ir=0xffff, bool undistorted=false)
cv::Mat_< cv::Vec3b > get_color_frame()
kinect_internal_parameters from_freenect2(const freenect2_color_params &, const freenect2_ir_params &)
kinect_internal_parameters internal_parameters()
cv::Mat_< ushort > get_original_ir_frame(bool undistorted=false)
cv::Mat_< cv::Vec3b > get_registered_color_frame()
cv::Mat_< float > get_depth_frame(bool undistorted=false)
void release()
cv::Mat_< float > get_bigdepth_frame()
grabber(int frame_types)