licornea_tools
remapping_viewer.cc
Go to the documentation of this file.
1 #include "../lib/common.h"
2 #include "../lib/args.h"
3 #include "../lib/opencv.h"
4 #include "../lib/json.h"
5 #include "../lib/obj_img_correspondence.h"
6 #include "../lib/intrinsics.h"
7 #include "../lib/misc.h"
8 #include "../lib/viewer.h"
9 #include "lib/live/grabber.h"
10 #include "lib/live/checkerboard.h"
13 #include "lib/freenect2.h"
14 #include <libfreenect2/registration.h>
15 #include <string>
16 #include <cmath>
17 
18 using namespace tlz;
19 
20 int main(int argc, const char* argv[]) {
21  get_args(argc, argv, "internal.json reprojection.json");
22  std::string internal_parameters_filename = in_filename_arg();
23  std::string reprojection_parameters_filename = in_filename_arg();
24 
25  std::cout << "loading internal&reprojection parameters" << std::endl;
26  kinect_internal_parameters internal_parameters = decode_kinect_internal_parameters(import_json_file(internal_parameters_filename));
27  kinect_reprojection_parameters reprojection_parameters = decode_kinect_reprojection_parameters(import_json_file(reprojection_parameters_filename));
28 
29  std::pair<freenect2_color_params, freenect2_ir_params> freenect2_internal = to_freenect2(internal_parameters);
30  libfreenect2::Registration registration(freenect2_internal.second, freenect2_internal.first);
31 
33  kinect_reprojection reproj(reprojection_parameters);
34 
35  int h = 324;
36  int w = 576;
37  double scale = 0.3;
38 
39  viewer view(3*w, 20+h+30);
40  auto& superimpose = view.add_int_slider("superimpose (%)", 0, 0, 100);
41  auto& offset = view.add_int_slider("depth offset (-200 + ..) (mm)", 0, -200, 200);
42 
43  cv::Mat_<uchar> homography_mapping(h, w);
44  cv::Mat_<uchar> freenect2_mapping(h, w);
45  cv::Mat_<vec2> freenect2_mapping_coordinates(424, 512);
46  cv::Mat_<vec2> homography_mapping_coordinates(424, 512);
47  cv::Mat_<float> z_buffer(h, w);
48 
49  do {
50  int z_offset = offset.value();
51 
52  grab.grab();
53  view.clear();
54 
55  cv::Mat_<cv::Vec3b> color = grab.get_color_frame();
56  cv::Mat_<uchar> ir = grab.get_ir_frame();
57  cv::Mat_<float> depth = grab.get_depth_frame();
58 
59  cv::Mat_<uchar> undistorted_ir = grab.get_ir_frame(true);
60  cv::Mat_<float> undistorted_depth = grab.get_depth_frame(true);
61 
62  // IR+depth to color mapping using Freenect2 registration
63  z_buffer.setTo(INFINITY);
64  freenect2_mapping.setTo(0);
65  freenect2_mapping_coordinates.setTo(vec2(0,0));
66  for(int dy = 0; dy < 424; ++dy) for(int dx = 0; dx < 512; ++dx) {
67  float cx, cy;
68  float dz = undistorted_depth(dy, dx);
69  if(dz < 0.001) continue;
70  uchar value = undistorted_ir(dy, dx);
71  registration.apply(dx, dy, dz, cx, cy);
72 
73  int scx = cx * scale, scy = cy * scale;
74  if(scx < 0 || scx >= w || scy < 0 || scy >= h) continue;
75 
76  float& old_dz = z_buffer(scy, scx);
77  if(dz > old_dz) continue;
78  freenect2_mapping(scy, scx) = value;
79  freenect2_mapping_coordinates(dy, dx) = vec2(cx, cy);
80  old_dz = dz;
81  }
82 
83 
84  // IR+depth to color mapping using homography
85  homography_mapping.setTo(0);
86  homography_mapping_coordinates.setTo(vec2(0,0));
87  z_buffer.setTo(INFINITY);
88 
89  cv::Mat_<float> depth_off = depth + z_offset;
90  depth_off.setTo(0.0, (depth == 0.0));
91  auto color_samples = reproj.reproject_ir_to_color_samples<uchar>(ir, depth_off, true);
92  for(auto& samp : color_samples) {
93  real cx = samp.color_coordinates[0], cy = samp.color_coordinates[1];
94  int scx = cx*scale, scy = cy*scale;
95  if(scx < 0 || scx >= w || scy < 0 || scy >= h) continue;
96  float dz = samp.ir_depth;
97 
98  float& old_dz = z_buffer(scy, scx);
99  if(dz > old_dz) continue;
100  homography_mapping(scy, scx) = samp.value;
101  int dx = samp.ir_coordinates[0], dy = samp.ir_coordinates[1];
102  homography_mapping_coordinates(dy, dx) = samp.color_coordinates;
103  old_dz = dz;
104  }
105 
106  // draw images
107  view.draw(cv::Rect(0, 20, w, h), freenect2_mapping);
108  view.draw(cv::Rect(w, 20, w, h), color);
109  view.draw(cv::Rect(2*w, 20, w, h), homography_mapping);
110  if(superimpose.value() > 0) {
111  float blend = superimpose.value() / 100.0;
112  view.draw(cv::Rect(0, 20, w, h), color, blend);
113  view.draw(cv::Rect(2*w, 20, w, h), color, blend);
114  }
115 
116  grab.release();
117 
118 
119  // measure error
120  real sum = 0.0;
121  int count = 0;
122  for(int dy = 0; dy < 424; ++dy) for(int dx = 0; dx < 512; ++dx) {
123  vec2 freenect2_mapping_coord = freenect2_mapping_coordinates(dy, dx);
124  vec2 homography_mapping_coord = homography_mapping_coordinates(dy, dx);
125  if(freenect2_mapping_coord == vec2(0,0) || homography_mapping_coord == vec2(0,0)) continue;
126 
127  vec2 diff = freenect2_mapping_coord - homography_mapping_coord;
128  sum += sq(diff[0]) + sq(diff[1]);
129  count++;
130  }
131  real err = std::sqrt(sum / count);
132 
133 
134  view.draw_text(cv::Rect(0, 0, w, 20), "Freenect2 Registration", viewer::center);
135  view.draw_text(cv::Rect(2*w, 0, w, 20), "Homography", viewer::center);
136  view.draw_text(cv::Rect(0, 20+h, 3*w, 30), "rms error: " + std::to_string(err) + " pixel z offset: " + std::to_string(z_offset) + " mm", viewer::center);
137  } while(view.show());
138 }
Numeric sq(Numeric n)
Compute square of a number.
Definition: misc.h:17
int main(int argc, const char *argv[])
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_reprojection_parameters decode_kinect_reprojection_parameters(const json &j_parameters)
std::string in_filename_arg()
Definition: args.cc:98
void draw(const cv::Mat_< cv::Vec3b > &, real blend=1.0)
Definition: viewer.cc:119
kinect_internal_parameters decode_kinect_internal_parameters(const json &j)
cv::Vec< real, 2 > vec2
Definition: common.h:22
cv::Mat_< float > get_depth_frame(bool undistorted=false)
std::pair< freenect2_color_params, freenect2_ir_params > to_freenect2(const kinect_internal_parameters &)
bool show(int &keycode)
Definition: viewer.cc:218
double real
Definition: common.h:16
std::string to_string(const T &)
void release()
void draw_text(cv::Rect rect, const std::string &text, text_alignment=left)
Definition: viewer.cc:182
int_slider & add_int_slider(const std::string &caption, int default_val, int min_val, int max_val, int step=1)
Definition: viewer.cc:263
std::vector< sample< Value > > reproject_ir_to_color_samples(const cv::Mat_< Value > &distorted_ir_values, const cv::Mat_< Depth > &distorted_ir_z, bool distort_color=true) const
void clear(int width, int height)
Definition: viewer.cc:76
json import_json_file(const std::string &filename)
Definition: json.cc:24
void get_args(int argc, const char *argv[], const std::string &usage)
Definition: args.cc:49