licornea_tools
view_syn.cc
Go to the documentation of this file.
1 #include "../lib/common.h"
2 #include "../lib/assert.h"
3 #include "../lib/args.h"
4 #include "../lib/dataset.h"
5 #include "../lib/camera.h"
6 #include "../lib/image_io.h"
7 #include "../lib/opencv.h"
8 #include "../lib/viewer.h"
9 #include <iostream>
10 
11 using namespace tlz;
12 
13 cv::Mat_<cv::Vec3b> view_synthesis(
14  const cv::Mat_<cv::Vec3b>& ref_img,
15  const cv::Mat_<cv::Vec3b>& tg_img, const cv::Mat_<ushort>& tg_depth,
16  const camera& ref_cam, const camera& tg_cam,
17  real z_near, real z_far,
18  real opacity, real darken_background
19 ) {
20  cv::Size sz = ref_img.size();
21  Assert(tg_img.size() == sz);
22  Assert(tg_depth.size() == sz);
23 
24 
25  real z_diff = z_far - z_near;
26 
27  real alpha = -z_near / z_diff;
28  real beta = z_near*z_far / z_diff;
29 
30  mat44 P_ref = {
31  ref_cam.intrinsic(0,0), 0.0, ref_cam.intrinsic(0,2), 0.0,
32  0.0, ref_cam.intrinsic(1,1), ref_cam.intrinsic(1,2), 0.0,
33  0.0, 0.0, alpha, beta,
34  0.0, 0.0, 1.0, 0.0
35  };
36  mat44 P_tg = {
37  tg_cam.intrinsic(0,0), 0.0, tg_cam.intrinsic(0,2), 0.0,
38  0.0, tg_cam.intrinsic(1,1), tg_cam.intrinsic(1,2), 0.0,
39  0.0, 0.0, alpha, beta,
40  0.0, 0.0, 1.0, 0.0
41  };
42 
43  mat44 H = P_ref * ref_cam.extrinsic() * tg_cam.extrinsic_inv() * P_tg.inv();
44 
45  cv::Mat_<cv::Vec3b> out_img(sz);
46  ref_img.copyTo(out_img);
47  out_img *= darken_background;
48 
49  cv::Mat_<real> out_img_zbuffer(sz);
50  out_img_zbuffer.setTo(0.0);
51 
52  #pragma omp parallel shared(out_img, ref_img, tg_img, tg_depth)
53  {
54  cv::Mat_<real> local_out_img_zbuffer(sz);
55  local_out_img_zbuffer.setTo(0.0);
56 
57  cv::Mat_<cv::Vec3b> local_out_img(sz);
58 
59  #pragma omp for
60  for(int x = 0; x < sz.width; ++x) for(int y = 0; y < sz.height; ++y) {
61  cv::Vec3b tg_col = tg_img(y, x);
62  ushort d_int = tg_depth(y, x);
63  if(d_int == 0) continue;
64  real d = d_int;
65 
66  real disp = alpha + beta/d;
67 
68  vec4 tg_pos_h(x, y, disp, 1.0);
69  vec4 ref_pos_h = H * tg_pos_h;
70 
71  vec2 ref_pos(ref_pos_h[0]/ref_pos_h[3], ref_pos_h[1]/ref_pos_h[3]);
72  real ref_disp = ref_pos_h[2]/ref_pos_h[3];
73  int ref_x = ref_pos[0], ref_y = ref_pos[1];
74  if(ref_x < 0 || ref_x >= sz.width || ref_y < 0 || ref_y >= sz.height) continue;
75 
76  real& out_z = local_out_img_zbuffer(ref_y, ref_x);
77  cv::Vec3b& out_col = local_out_img(ref_y, ref_x);
78 
79  cv::Vec3b ref_col = ref_img(ref_y, ref_x);
80  if(out_z < ref_disp) {
81  out_z = ref_disp;
82  out_col = (1-opacity)*ref_col + opacity*tg_col;
83  }
84  }
85 
86  #pragma omp critical
87  {
88  cv::Mat_<uchar> mask = (local_out_img_zbuffer > out_img_zbuffer);
89  local_out_img.copyTo(out_img, mask);
90  local_out_img_zbuffer.copyTo(out_img_zbuffer, mask);
91  }
92  }
93 
94 
95  return out_img;
96 }
97 
98 
99 int main(int argc, const char* argv[]) {
100  get_args(argc, argv, "dataset_parameters.json cameras.json [dataset_group]");
101  dataset datas = dataset_arg();
102  camera_array cams = cameras_arg();
103  std::string dataset_group_name = string_opt_arg();
104 
105  auto cams_map = cameras_map(cams);
106 
107  dataset_group datag = datas.group(dataset_group_name);
108 
109  viewer view("View Synthesis", datag.image_size_with_border(), true);
110  auto& slider_ref_x = view.add_int_slider("ref X", datas.x_mid(), datas.x_min(), datas.x_max(), datas.x_step());
111  auto& slider_ref_y = view.add_int_slider("ref Y", datas.y_mid(), datas.y_min(), datas.y_max(), datas.y_step());
112  auto& slider_tg_x = view.add_int_slider("tg X", datas.x_mid(), datas.x_min(), datas.x_max(), datas.x_step());
113  auto& slider_tg_y = view.add_int_slider("tg Y", datas.y_mid(), datas.y_min(), datas.y_max(), datas.y_step());
114  auto& slider_opacity = view.add_real_slider("opacity", 0.5, 0.0, 1.0);
115  auto& slider_darken_background = view.add_real_slider("darken", 0.3, 0.0, 1.0);
116 
117  real z_near = 400.0;
118  real z_far = 2000.0;
119 
120  view.update_callback = [&]() {
121  view.clear();
122  try {
123  view_index ref_idx(slider_ref_x, slider_ref_y);
124  view_index tg_idx(slider_tg_x, slider_tg_y);
125  if(! datas.valid(ref_idx) || ! datas.valid(tg_idx)) return;
126 
127  cv::Mat_<cv::Vec3b> ref_image = load_texture(datag.view(ref_idx).image_filename());
128  cv::Mat_<cv::Vec3b> tg_image = load_texture(datag.view(tg_idx).image_filename());
129  cv::Mat_<ushort> tg_depth = load_depth(datag.view(tg_idx).depth_filename());
130  camera ref_cam = cams_map.at(datas.view(ref_idx).camera_name());
131  camera tg_cam = cams_map.at(datas.view(tg_idx).camera_name());
132 
133  cv::Mat_<cv::Vec3b> out_image = view_synthesis(
134  ref_image, tg_image, tg_depth, ref_cam, tg_cam, z_near, z_far, slider_opacity, 1.0-slider_darken_background);
135 
136  view.draw(cv::Point(0,0), out_image);
137  } catch(const std::exception&) { }
138  };
139 
140  view.show_modal();
141 }
int main(int argc, const char *argv[])
Definition: view_syn.cc:99
cv::Size image_size_with_border() const
Definition: dataset.cc:101
mat33 intrinsic
Definition: camera.h:15
int x_step() const
Definition: dataset.cc:173
cv::Vec< real, 4 > vec4
Definition: common.h:24
std::string image_filename() const
Definition: dataset.cc:64
int x_max() const
Definition: dataset.cc:169
int x_min() const
Definition: dataset.cc:165
std::map< std::string, camera > cameras_map(const camera_array &arr)
Definition: camera.cc:112
cv::Mat_< ushort > load_depth(const std::string &filename)
Definition: image_io.cc:35
mat44 extrinsic_inv() const
Definition: camera.cc:34
dataset_view view(int x) const
Definition: dataset.cc:105
int x_mid() const
Definition: dataset.cc:186
cv::Vec< real, 2 > vec2
Definition: common.h:22
cv::Mat_< cv::Vec3b > load_texture(const std::string &filename)
Definition: image_io.cc:6
camera_array cameras_arg()
Definition: camera.cc:107
dataset_view view(int x) const
Definition: dataset.cc:243
bool valid(view_index) const
Definition: dataset.cc:231
std::string depth_filename() const
Definition: dataset.cc:68
mat44 extrinsic() const
Definition: camera.cc:24
dataset dataset_arg()
Definition: dataset.cc:297
double real
Definition: common.h:16
int y_step() const
Definition: dataset.cc:206
std::string camera_name() const
Definition: dataset.cc:60
#define Assert
Definition: assert.h:40
int y_max() const
Definition: dataset.cc:201
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< camera > camera_array
Definition: camera.h:26
int y_min() const
Definition: dataset.cc:196
dataset_group group(const std::string &grp) const
Definition: dataset.cc:265
cv::Mat_< cv::Vec3b > view_synthesis(const cv::Mat_< cv::Vec3b > &ref_img, const cv::Mat_< cv::Vec3b > &tg_img, const cv::Mat_< ushort > &tg_depth, const camera &ref_cam, const camera &tg_cam, real z_near, real z_far, real opacity, real darken_background)
Definition: view_syn.cc:13
int y_mid() const
Definition: dataset.cc:226
cv::Matx< real, 4, 4 > mat44
Definition: common.h:27
std::string string_opt_arg(const std::string &def="")
Definition: args.h:36
void get_args(int argc, const char *argv[], const std::string &usage)
Definition: args.cc:49