1 #include "../lib/common.h" 2 #include "../lib/args.h" 3 #include "../lib/json.h" 4 #include "../lib/dataset.h" 5 #include "../lib/intrinsics.h" 6 #include "../lib/misc.h" 7 #include "../lib/assert.h" 39 position(pos), variance(var) { }
41 explicit operator bool ()
const {
return ! std::isnan(variance); }
47 real count = samples.size();
48 for(
const auto& kv : samples) mean += kv.second;
52 for(
const auto& kv : samples) {
53 const vec2& pos = kv.second;
54 variance +=
sq(pos[0] - mean[0]) +
sq(pos[1] - mean[1]);
57 real stddev = std::sqrt(variance);
64 int main(
int argc,
const char* argv[]) {
65 get_args(argc, argv,
"dataset_parameters.json cors.json intr.json R.json straight_depths.json out_rcpos.json [out_sample_positions.txt] [out_final_positions.txt]");
80 std::cout <<
"collecting all view indices and all reference view indices" << std::endl;
86 using target_camera_position_samples = std::map<std::string, vec2>;
87 auto get_target_camera_position_samples = [&](
92 ) -> target_camera_position_samples
96 target_camera_position_samples samples;
98 for(
const auto& kv : target_fpoints.
points) {
99 const std::string& feature_name = kv.first;
103 if(! ref_fpoints.has_feature(feature_name))
continue;
104 const feature_point& reference_fpoint = ref_fpoints.points.at(feature_name);
108 if(depths.find(shrt_feature_name) == depths.end())
continue;
109 real straight_d = depths.at(shrt_feature_name).
depth;
112 vec2 straight_target_pos =
mul_h(unrotate, target_pos);
115 vec2 straight_reference_pos =
mul_h(unrotate, reference_pos);
117 vec2 feature_target_camera_pos;
118 feature_target_camera_pos[0] = (straight_target_pos[0] - straight_reference_pos[0]) * straight_d / intr.
fx();
119 feature_target_camera_pos[1] = (straight_target_pos[1] - straight_reference_pos[1]) * straight_d / intr.
fy();
121 samples[shrt_feature_name] = feature_target_camera_pos;
128 std::set<std::string> bad_features;
130 std::cout <<
"finding bad features" << std::endl;
131 struct feature_evalation {
132 real average_error = 0.0;
133 int samples_count = 0;
135 std::map<std::string, feature_evalation> feature_evaluations;
137 #pragma omp parallel for 138 for(std::ptrdiff_t ref_ifx_i = 0; ref_ifx_i < ref_vws.size(); ++ref_ifx_i) {
139 const view_index& ref_idx = ref_vws[ref_ifx_i];
141 std::cout <<
" reference view " << ref_idx << std::endl;
146 if(target_idx == ref_idx)
continue;
147 target_camera_position_samples samples = get_target_camera_position_samples(target_idx, ref_idx, ref_cors, ref_fpoints);
149 for(
const auto& kv : samples) mean += kv.second;
150 mean /=
real(samples.size());
151 for(
const auto& kv : samples) {
152 const std::string& shrt_feature_name = kv.first;
153 const vec2& pos = kv.second;
154 real mean_sq_dist =
sq(mean[0] - pos[0]) +
sq(mean[1] - pos[1]);
157 feature_evaluations[shrt_feature_name].samples_count++;
158 feature_evaluations[shrt_feature_name].average_error += mean_sq_dist;
164 std::vector<std::string> worst_features;
165 for(
auto& kv : feature_evaluations) {
166 const std::string& shrt_feature_name = kv.first;
167 feature_evalation& eval = kv.second;
168 eval.average_error /= eval.samples_count;
169 worst_features.push_back(shrt_feature_name);
172 auto worst_features_bad_end = worst_features.begin() + bad_count;
174 worst_features.begin(),
175 worst_features.begin() + bad_count,
176 worst_features.end(),
177 [&feature_evaluations](
const std::string& a,
const std::string& b) {
178 real err_a = feature_evaluations.at(a).average_error;
179 real err_b = feature_evaluations.at(b).average_error;
180 return (err_a > err_b);
183 bad_features = std::set<std::string>(worst_features.begin(), worst_features_bad_end);
184 std::cout <<
" bad features:" << std::endl;
185 for(
const std::string& shrt_feature_name : bad_features) {
186 real err = feature_evaluations.at(shrt_feature_name).average_error;
187 std::cout <<
" " << shrt_feature_name <<
" (avg error: " << err <<
")" << std::endl;
191 std::cout <<
"estimating target camera positions, from each reference" << std::endl;
194 std::ofstream out_sample_positions_stream, out_final_positions_stream;
195 if(! out_sample_positions_filename.empty()) {
196 out_sample_positions_stream.open(out_sample_positions_filename);
197 out_sample_positions_stream <<
"x y feature_name target_idx_x target_idx_y ref_idx_x ref_idx_y\n";
198 out_sample_positions_stream << std::setprecision(10);
200 if(! out_final_positions_filename.empty()) {
201 out_final_positions_stream.open(out_final_positions_filename);
202 out_final_positions_stream <<
"x y target_idx_x target_idx_y ref_idx_x ref_idx_y\n";
203 out_final_positions_stream << std::setprecision(10);
206 #pragma omp parallel for 207 for(std::ptrdiff_t ref_ifx_i = 0; ref_ifx_i < ref_vws.size(); ++ref_ifx_i) {
208 const view_index& ref_idx = ref_vws[ref_ifx_i];
210 int final_relative_views_count = 0;
221 target_camera_position_samples samples;
223 if(target_idx == ref_idx) {
228 samples = get_target_camera_position_samples(target_idx, ref_idx, ref_cors, ref_fpoints);
230 for(
const std::string& shrt_bad_feature_name : bad_features) samples.erase(shrt_bad_feature_name);
236 ++final_relative_views_count;
242 if(out_final_positions_stream.is_open())
243 out_final_positions_stream <<
246 target_idx.
x <<
' ' <<
247 target_idx.
y <<
' ' <<
251 for(
const auto& kv : samples) {
252 const std::string& shrt_feature_name = kv.first;
253 const vec2& pos = kv.second;
255 if(out_sample_positions_stream.is_open() && print_sample)
256 out_sample_positions_stream <<
259 std::stoi(shrt_feature_name.substr(4))+1000 <<
' ' <<
260 target_idx.
x <<
' ' <<
261 target_idx.
y <<
' ' <<
270 std::cout <<
" reference view " << ref_idx <<
": final relative positions for " << final_relative_views_count <<
" views" << std::endl;
273 std::cout <<
"checking for which views there is a position" << std::endl;
275 auto really_all_target_views = datas.
indices();
276 for(
const view_index& target_idx : really_all_target_views) {
277 if(tpos.find(target_idx) == tpos.end()) {
278 std::cout <<
"no camera position for " << target_idx << std::endl;
283 std::cout <<
"saving relative camera positions" << std::endl;
Numeric sq(Numeric n)
Compute square of a number.
target_reference_positions_type to_target_reference_positions() const
std::string short_feature_name(const std::string &full_feature_name)
constexpr real features_inlier_percentile
constexpr std::size_t minimal_samples_count
std::vector< view_index > get_all_views(const image_correspondences &cors)
image_correspondences image_correspondences_with_reference(const image_correspondences &cors, const view_index &reference_view)
Set of features, each on set of views.
Points of different features, on one view.
std::map< std::string, feature_point > points
vec3 mul_h(const mat44 &mat, const vec3 &vec)
feature_points feature_points_for_view(const image_correspondences &cors, view_index idx, bool is_distorted)
cv::Mat_< real > decode_mat(const json &j)
std::string out_filename_opt_arg(const std::string &def)
intrinsics intrinsics_arg()
distortion_parameters distortion
std::vector< view_index > get_reference_views(const relative_camera_positions &rcpos)
cv::Matx< real, 3, 3 > mat33
std::map< std::string, straight_depth > straight_depths
void export_json_file(const json &j, const std::string &filename, bool compact)
image_correspondences image_correspondences_arg()
vec2 & position(const reference_view_index &ref_idx, const target_view_index &target_idx)
straight_depths straight_depths_arg()
std::string out_filename_arg()
constexpr real maximal_position_stddev
target_camera_position_result(const vec2 &pos, real var)
constexpr bool find_bad_features
target_camera_position_result compute_target_camera_position(const std::map< std::string, vec2 > &samples)
constexpr bool print_all_sample_positions
int main(int argc, const char *argv[])
std::vector< view_index > indices() const
json encode_relative_camera_positions(const relative_camera_positions &rcpos)
void get_args(int argc, const char *argv[], const std::string &usage)