1 #include "../lib/common.h" 2 #include "../lib/args.h" 3 #include "../lib/json.h" 4 #include "../lib/camera.h" 5 #include "../lib/dataset.h" 6 #include "../lib/intrinsics.h" 7 #include "../lib/misc.h" 8 #include "../lib/assert.h" 24 int main(
int argc,
const char* argv[]) {
25 get_args(argc, argv,
"dataset_parameters.json refgrid.json rcpos.json intr.json R.json out_cameras.json [out_camera_centers.txt]");
39 std::cout <<
"computing relative positions of reference views" << std::endl;
41 vec2 displacements_sum = 0.0;
42 real displacements_weights_sum = 0.0;
43 std::map<view_index, vec2> ref_a_target_camera_positions;
45 if(reference_target_camera_positions.find(ref_a) != reference_target_camera_positions.end())
46 for(
const auto& p : reference_target_camera_positions.at(ref_a)) {
48 const vec2& camera_position = p.second;
49 ref_a_target_camera_positions[target] = camera_position;
52 if(reference_target_camera_positions.find(ref_b) != reference_target_camera_positions.end())
53 for(
const auto& p : reference_target_camera_positions.at(ref_b)) {
55 auto ref_a_pos_it = ref_a_target_camera_positions.find(target);
56 if(ref_a_pos_it != ref_a_target_camera_positions.end()) {
57 vec2 ref_a_pos = ref_a_pos_it->second;
58 vec2 ref_b_pos = p.second;
60 displacements_sum += (ref_a_pos - ref_b_pos);
61 displacements_weights_sum += 1.0;
65 if(displacements_weights_sum == 0.0)
68 return displacements_sum / displacements_weights_sum;
72 std::map<view_index, vec2> absolute_reference_camera_positions;
74 std::cout <<
" stitching position of reference view " << ref_b <<
" onto " << ref_a << std::endl;
75 vec2 displacement = reference_camera_displacement(ref_a, ref_b);
76 std::cout <<
" ref" << ref_b <<
" = " << displacement <<
" + ref" << ref_a << std::endl;
77 absolute_reference_camera_positions[ref_b] = absolute_reference_camera_positions.at(ref_a) + displacement;
80 int mid_col = rgrid.
cols() / 2, mid_row = rgrid.
rows()/2;
81 absolute_reference_camera_positions[rgrid.
view(mid_col, mid_row)] =
vec2(0.0, 0.0);
82 for(
int col = mid_col-1; col >= 0; col--) {
83 add_reference_camera_position(rgrid.
view(col+1, mid_row), rgrid.
view(col, mid_row));
84 for(
int row = mid_row-1; row >= 0; row--) add_reference_camera_position(rgrid.
view(col, row+1), rgrid.
view(col, row));
85 for(
int row = mid_row+1; row < rgrid.
rows(); row++) add_reference_camera_position(rgrid.
view(col, row-1), rgrid.
view(col, row));
87 for(
int col = mid_col+1; col < rgrid.
cols(); col++) {
88 add_reference_camera_position(rgrid.
view(col-1, mid_row), rgrid.
view(col, mid_row));
89 for(
int row = mid_row-1; row >= 0; row--) add_reference_camera_position(rgrid.
view(col, row+1), rgrid.
view(col, row));
90 for(
int row = mid_row+1; row < rgrid.
rows(); row++) add_reference_camera_position(rgrid.
view(col, row-1), rgrid.
view(col, row));
94 std::ofstream out_camera_centers_stream;
95 if(! out_camera_centers_filename.empty()) {
96 out_camera_centers_stream.open(out_camera_centers_filename);
97 out_camera_centers_stream <<
"x y idx_x idx_y chosen\n";
98 out_camera_centers_stream << std::setprecision(10);
101 std::map<view_index, vec2> absolute_target_camera_positions;
102 if(absolute_reference_camera_positions.size() == 1) {
103 for(
const auto& p : reference_target_camera_positions.begin()->second) {
105 const vec2& pos = p.second;
106 absolute_target_camera_positions[p.first] = pos;
107 if(out_camera_centers_stream.is_open())
108 out_camera_centers_stream << pos[0] <<
' ' << pos[1] <<
' ' << target_idx.
x <<
' ' << target_idx.
y <<
" 1\n";
112 reference_target_camera_positions.clear();
115 std::vector<real> overlap_radii;
117 std::cout <<
"stitching camera positions from different reference views" << std::endl;
118 for(
const view_index& target_idx : all_target_vws) {
119 auto target_positions_it = target_reference_camera_positions.find(target_idx);
120 if(target_positions_it == target_reference_camera_positions.end())
continue;
128 position(pos), target_idx(tg), ref_idx(rf) { }
130 int idx_dist()
const {
131 return sq(ref_idx.
x - target_idx.
x) +
sq(ref_idx.
y - target_idx.
y);
134 std::ptrdiff_t chosen_sample_i = -1;
135 std::vector<sample> samples;
137 for(
const auto& p : target_positions_it->second) {
140 const vec2& pos = p.second;
141 if(absolute_reference_camera_positions.find(ref_idx) == absolute_reference_camera_positions.end())
continue;
142 const vec2& absolute_reference_pos = absolute_reference_camera_positions.at(ref_idx);
144 vec2 abs_pos = absolute_reference_pos + pos;
146 samples.emplace_back(abs_pos, target_idx, ref_idx);
148 if(chosen_sample_i == -1) chosen_sample_i = samples.size()-1;
149 else if(samples.back().idx_dist() < samples.at(chosen_sample_i).idx_dist()) chosen_sample_i = samples.size()-1;
152 for(
const sample& samp : samples) {
153 bool chosen = (&samp == &samples.at(chosen_sample_i));
155 absolute_target_camera_positions[samp.target_idx] = samp.position;
157 if(out_camera_centers_stream.is_open())
158 out_camera_centers_stream << samp.position[0] <<
' ' << samp.position[1] <<
' ' << samp.target_idx.
x <<
' ' << samp.target_idx.y <<
' ' << (chosen ?
'1' :
'0') <<
'\n';
161 if(samples.size() > 1) {
163 for(
const sample& samp : samples) mean += samp.position;
164 mean /=
real(samples.size());
166 for(
const sample& samp : samples) max_dist = std::max(max_dist, cv::norm(samp.position, mean));
167 overlap_radii.push_back(max_dist);
171 real overlap_radii_avg = 0.0;
172 for(
real overlap_radius : overlap_radii) overlap_radii_avg += overlap_radius;
173 overlap_radii_avg /= overlap_radii.size();
174 std::sort(overlap_radii.begin(), overlap_radii.end());
175 std::cout <<
" overlapping positions (more = better): " << overlap_radii.size() << std::endl;
176 std::cout <<
" average radius (smaller = better): " << overlap_radii_avg << std::endl;
177 std::cout <<
" median radius: " << overlap_radii[overlap_radii.size()/2] << std::endl;
178 std::cout <<
" maximum radius: " << overlap_radii.back() << std::endl;
182 std::cout <<
"computing camera array" << std::endl;
184 auto really_all_target_views = datas.
indices();
185 for(
const view_index& target_idx : really_all_target_views) {
186 auto it = absolute_target_camera_positions.find(target_idx);
187 if(it == absolute_target_camera_positions.end()) {
188 std::cout <<
"no camera position for " << target_idx << std::endl;
190 const vec2& camera_position = it->second;
196 cam.
translation = R *
vec3(camera_position[0], camera_position[1], 0.0);
197 cameras.push_back(cam);
201 std::cout <<
"saving cameras" << std::endl;
204 std::cout <<
"done" << std::endl;
void export_cameras_file(const camera_array &cameras, const std::string &filename)
Numeric sq(Numeric n)
Compute square of a number.
target_reference_positions_type to_target_reference_positions() const
std::vector< view_index > get_target_views(const relative_camera_positions &rcpos)
std::string encode_view_index(view_index idx)
dataset_view view(int x) const
cv::Mat_< real > decode_mat(const json &j)
std::string out_filename_opt_arg(const std::string &def)
intrinsics intrinsics_arg()
references_grid references_grid_arg()
relative_camera_positions relative_camera_positions_arg()
distortion_parameters distortion
cv::Matx< real, 3, 3 > mat33
view_index view(std::ptrdiff_t col, std::ptrdiff_t row) const
std::string camera_name() const
std::string out_filename_arg()
std::vector< camera > camera_array
reference_target_positions_type to_reference_target_positions() const
int main(int argc, const char *argv[])
std::vector< view_index > indices() const
void get_args(int argc, const char *argv[], const std::string &usage)