2 #include "../../lib/string.h" 3 #include "../../lib/assert.h" 12 int binary_cors_magic_ = 0x2D1111C0;
18 if(
has(j_feat,
"reference_view"))
21 const json& j_pts = j_feat[
"points"];
22 for(
auto it = j_pts.begin(); it != j_pts.end(); ++it) {
32 json j_feat = json::object();
36 json j_points = json::object();
37 for(
const auto& kv : feat.
points) {
42 j_feat[
"points"] = j_points;
49 if(
has(j_cors,
"dataset_group")) cors.
dataset_group = j_cors[
"dataset_group"];
50 const json& j_features = j_cors[
"features"];
51 for(
auto it = j_features.begin(); it != j_features.end(); ++it) {
52 std::string feature_name = it.key();
53 const json& j_feature = it.value();
61 json j_cors = json::object();
63 json j_features = json::object();
64 for(
const auto& kv : cors.
features) {
65 const std::string& feature_name = kv.first;
69 j_cors[
"features"] = j_features;
75 std::ofstream str(filename, std::ios_base::binary);
77 auto write = [&str](
const auto& val) {
78 const auto* ptr =
reinterpret_cast<const std::ostream::char_type*
>(&val);
79 str.write(ptr,
sizeof(val));
81 auto write_buffer = [&str](
const void* buf, std::size_t sz) {
82 str.write(static_cast<const std::ostream::char_type*>(buf), sz);
85 auto uint8 = [&write](std::uint8_t val) { write(val); };
86 auto int32 = [&write](std::int32_t val) { write(val); };
87 auto float64 = [&write](
double val) { write(val); };
89 auto short_string = [&](
const std::string& str) {
90 Assert(str.length() <= 255);
92 write_buffer(str.data(), str.length());
99 int32(binary_cors_magic_);
102 for(
const auto& kv : cors.
features) {
103 const std::string& feature_name = kv.first;
105 short_string(feature_name);
107 int32(feature.
points.size());
108 for(
const auto& kv2 : feature.
points) {
114 float64(fpoint.
depth);
122 std::ifstream str(filename, std::ios_base::binary);
124 auto read = [&str](
auto& val) {
125 auto* ptr =
reinterpret_cast<std::ostream::char_type*
>(&val);
126 str.read(ptr,
sizeof(val));
128 auto read_buffer = [&str](
void* buf, std::size_t sz) {
129 str.read(static_cast<std::ostream::char_type*>(buf), sz);
132 auto uint8 = [&read]() { std::uint8_t val; read(val);
return val; };
133 auto int32 = [&read]() { std::int32_t val; read(val);
return val; };
134 auto float64 = [&read]() {
double val; read(val);
return val; };
136 auto short_string = [&]() {
138 std::size_t sz = uint8();
139 read_buffer(&
string, sz);
140 return std::string(
string, sz);
142 auto view_idx = [&]() {
150 if(magic != binary_cors_magic_)
throw std::runtime_error(
"binary cors file does not have magic number");
152 std::size_t features_count = int32();
153 for(
int i = 0; i < features_count; ++i) {
154 std::string feature_name = short_string();
158 std::size_t points_count = int32();
159 for(
int j = 0; j < points_count; ++j) {
164 fpoint.
depth = float64();
165 fpoint.
weight = float64();
175 std::cout <<
"exporting image correspondences to JSON" << std::endl;
178 std::cout <<
"exporting image correspondences to binary" << std::endl;
181 throw std::runtime_error(
"unknown filename extension for image correspondences (need .json or .bin)");
188 else throw std::runtime_error(
"unknown filename extension for image correspondences (need .json or .bin)");
193 std::set<view_index> reference_views_set;
195 reference_views_set.insert(kv.second.reference_view);
196 return reference_views_set;
202 return std::vector<view_index>(reference_views_set.begin(), reference_views_set.end());
207 std::set<view_index> views_set;
209 for(
const auto& kv2 : kv.second.points)
210 views_set.insert(kv2.first);
217 return std::vector<view_index>(views_set.begin(), views_set.end());
223 return std::set<std::string>(feature_names.begin(), feature_names.end());
228 std::vector<std::string> feature_names;
230 feature_names.push_back(kv.first);
231 return feature_names;
236 auto pos = full_feature_name.find_first_of(
'#');
237 if(pos == std::string::npos)
return full_feature_name;
238 else return full_feature_name.substr(0, pos);
245 for(
const auto& kv : cors.
features) {
248 out_cors.
features[kv.first] = feature;
257 std::vector<vec2> dist_points;
258 std::vector<vec2*> undist_points_ptrs;
262 for(
const auto& kv : cors.
features) {
263 const std::string& feature_name = kv.first;
266 for(
const auto& kv2 : feature.
points) {
271 undist_points_ptrs.push_back(&out_pt.
position);
277 for(std::ptrdiff_t i = 0; i < undist_points.size(); ++i)
278 *undist_points_ptrs[i] = undist_points[i];
285 cv::Mat_<cv::Vec3b> img;
286 back_img.copyTo(img);
288 bool is_2d = feature.
points.begin()->first.is_2d();
292 cv::Point2f center_point_cv(bord.
left + center_point[0], bord.
top + center_point[1]);
293 cv_aa_circle(img, center_point_cv, 10, cv::Scalar(col), 2);
296 std::vector<cv::Point> trail_points;
297 for(
const auto& kv : feature.
points) {
298 vec2 pt = kv.second.position;
299 pt[0] += bord.
left; pt[1] += bord.
top;
300 trail_points.emplace_back(pt[0], pt[1]);
303 std::vector<std::vector<cv::Point>> polylines = { trail_points };
304 cv::polylines(img, polylines,
false, cv::Scalar(col), 2);
308 for(
const auto& kv : feature.
points) {
309 vec2 pt = kv.second.position;
310 pt[0] += bord.
left; pt[1] += bord.
top;
312 cv::Point2f pt_cv(pt[0], pt[1]);
314 if(dot_radius <= 1) {
315 if(cv::Rect(cv::Point(), img.size()).contains(pt_cv)) img(pt_cv) = col;
317 cv_aa_circle(img, pt_cv, dot_radius, cv::Scalar(col), -1);
327 real y_min = +INFINITY, y_max = -INFINITY, x_min = +INFINITY, x_max = -INFINITY;
328 for(
const auto& kv : feature.
points) {
329 vec2 pos = kv.second.position;
330 if(pos[0] > x_max) x_max = pos[0];
331 if(pos[0] < x_min) x_min = pos[0];
332 if(pos[1] > y_max) y_max = pos[1];
333 if(pos[1] < y_min) y_min = pos[1];
335 real scale = std::min({ img.cols/(x_max-x_min), img.rows/(y_max-y_min) });
338 cv::Rect roi(x_min+bord.
left, y_min+bord.
top, x_max-x_min, y_max-y_min);
340 cv::Mat_<cv::Vec3b> out_img;
341 cv::resize(cv::Mat(img, roi), out_img, cv::Size(0,0), scale, scale, cv::INTER_CUBIC);
343 cv::Mat_<cv::Vec3b> out_img_with_dots;
344 out_img.copyTo(out_img_with_dots);
346 for(
const auto& kv : feature.
points) {
348 cv::Point2f pt_cv = vec2_to_point2f(kv.second.position);
354 if(ref_idx && idx == ref_idx) {
355 cv_aa_circle(out_img_with_dots, pt_cv, 5, cv::Scalar(cv::Vec3b(0,0,255)), -1);
356 cv_aa_circle(out_img, pt_cv, 5, cv::Scalar(cv::Vec3b(0,0,255)), -1);
359 cv_aa_circle(out_img_with_dots, pt_cv, 2, cv::Scalar(col), -1);
362 cv::addWeighted(out_img_with_dots, dots_opacity, out_img, 1.0-dots_opacity, 0.0, out_img);
369 std::cout <<
"loading image correspondences" << std::endl;
cv::Mat_< cv::Vec3b > visualize_view_points(const image_correspondence_feature &feature, const cv::Mat_< cv::Vec3b > &back_img, const cv::Vec3b &col, int dot_radius, const border &bord)
bool has(const json &j, const std::string &key)
std::string short_feature_name(const std::string &full_feature_name)
std::set< std::string > get_feature_names_set(const image_correspondences &cors)
std::set< view_index > get_all_views_set(const image_correspondences &cors)
cv::Mat_< cv::Vec3b > visualize_view_points_closeup(const image_correspondence_feature &feature, const cv::Mat_< cv::Vec3b > &img, const cv::Vec3b &col, const view_index &ref_idx, real dots_opacity, const border &bord)
std::string encode_view_index(view_index idx)
std::vector< view_index > get_all_views(const image_correspondences &cors)
json encode_image_correspondence_feature(const image_correspondence_feature &feat)
std::string in_filename_arg()
image_correspondences import_image_correspondences(const std::string &filename)
image_correspondences image_correspondences_with_reference(const image_correspondences &cors, const view_index &reference_view)
Set of features, each on set of views.
feature_point decode_feature_point(const json &j_pt)
image_correspondence_feature decode_image_correspondence_feature(const json &j_feat)
std::map< std::string, image_correspondence_feature > features
std::string dataset_group
distortion_parameters distortion
json encode_feature_point(const feature_point &pt)
std::vector< view_index > get_reference_views(const relative_camera_positions &rcpos)
std::vector< std::string > get_feature_names(const image_correspondences &cors)
image_correspondences decode_image_correspondences(const json &j_cors)
void export_json_file(const json &j, const std::string &filename, bool compact)
view_index reference_view
void export_binary_image_correspondences(const image_correspondences &cors, const std::string &filename)
image_correspondences image_correspondences_arg()
feature_points undistort(const feature_points &dist_fpoints, const intrinsics &intr)
std::set< view_index > get_reference_views_set(const image_correspondences &cors)
Feature on set of views. Optionally one view is "reference".
std::vector< vec2 > undistort_points(const intrinsics &intr, const std::vector< vec2 > &distorted)
view_index decode_view_index(const std::string &key)
std::string file_name_extension(const std::string &filename)
void export_image_corresponcences(const image_correspondences &cors, const std::string &filename)
image_correspondences import_binary_image_correspondences(const std::string &filename)
json encode_image_correspondences(const image_correspondences &cors)
json import_json_file(const std::string &filename)
std::map< view_index, feature_point > points
void cv_aa_circle(cv::Mat &mat, const cv::Point2f ¢er, float rad, cv::Scalar col, int thickness)