32 #include <sensor_msgs/Image.h>
34 #include <opencv2/core/core.hpp>
35 #include <opencv2/highgui/highgui.hpp>
65 void handle_stereo(
double time0,
double time1, cv::Mat img0, cv::Mat img1);
68 int main(
int argc,
char **argv) {
71 std::string config_path =
"unset_path.txt";
73 config_path = argv[1];
78 auto nh = std::make_shared<ros::NodeHandle>(
"~");
79 nh->param<std::string>(
"config_path", config_path, config_path);
82 auto parser = std::make_shared<ov_core::YamlParser>(config_path,
false);
83 parser->set_node_handler(nh);
86 std::string verbosity =
"DEBUG";
87 parser->parse_config(
"verbosity", verbosity);
91 std::string topic_camera0, topic_camera1;
92 nh->param<std::string>(
"topic_camera0", topic_camera0,
"/cam0/image_raw");
93 nh->param<std::string>(
"topic_camera1", topic_camera1,
"/cam1/image_raw");
94 parser->parse_external(
"relative_config_imucam",
"cam" + std::to_string(0),
"rostopic", topic_camera0);
95 parser->parse_external(
"relative_config_imucam",
"cam" + std::to_string(1),
"rostopic", topic_camera1);
98 std::string path_to_bag;
99 nh->param<std::string>(
"path_bag", path_to_bag,
"/home/patrick/datasets/euroc_mav/V1_01_easy.bag");
101 PRINT_INFO(
"ros bag path is: %s\n", path_to_bag.c_str());
105 double bag_start, bag_durr;
106 nh->param<
double>(
"bag_start", bag_start, 0);
107 nh->param<
double>(
"bag_durr", bag_durr, -1);
115 cv::setNumThreads(4);
119 int num_aruco = 1024;
120 int fast_threshold = 20;
123 int min_px_dist = 10;
124 double knn_ratio = 0.70;
125 bool do_downsizing =
false;
126 bool use_stereo =
false;
127 parser->parse_config(
"max_cameras",
max_cameras,
false);
128 parser->parse_config(
"num_pts", num_pts,
false);
129 parser->parse_config(
"num_aruco", num_aruco,
false);
130 parser->parse_config(
"clone_states",
clone_states,
false);
131 parser->parse_config(
"fast_threshold", fast_threshold,
false);
132 parser->parse_config(
"grid_x", grid_x,
false);
133 parser->parse_config(
"grid_y", grid_y,
false);
134 parser->parse_config(
"min_px_dist", min_px_dist,
false);
135 parser->parse_config(
"knn_ratio", knn_ratio,
false);
136 parser->parse_config(
"do_downsizing", do_downsizing,
false);
137 parser->parse_config(
"use_stereo", use_stereo,
false);
141 std::string histogram_method_str =
"HISTOGRAM";
142 parser->parse_config(
"histogram_method", histogram_method_str,
false);
143 if (histogram_method_str ==
"NONE") {
145 }
else if (histogram_method_str ==
"HISTOGRAM") {
147 }
else if (histogram_method_str ==
"CLAHE") {
150 printf(
RED "invalid feature histogram specified:\n" RESET);
152 printf(
RED "\t- HISTOGRAM\n" RESET);
154 std::exit(EXIT_FAILURE);
162 PRINT_DEBUG(
"grid size: %d x %d\n", grid_x, grid_y);
163 PRINT_DEBUG(
"fast threshold: %d\n", fast_threshold);
164 PRINT_DEBUG(
"min pixel distance: %d\n", min_px_dist);
165 PRINT_DEBUG(
"downsize aruco image: %d\n", do_downsizing);
169 std::unordered_map<size_t, std::shared_ptr<CamBase>> cameras;
170 for (
int i = 0; i < 2; i++) {
171 Eigen::Matrix<double, 8, 1> cam0_calib;
172 cam0_calib << 1, 1, 0, 0, 0, 0, 0, 0;
173 std::shared_ptr<CamBase> camera_calib = std::make_shared<CamRadtan>(100, 100);
174 camera_calib->set_value(cam0_calib);
175 cameras.insert({i, camera_calib});
179 extractor =
new TrackKLT(cameras, num_pts, num_aruco, use_stereo, method, fast_threshold, grid_x, grid_y, min_px_dist);
205 view.
addQuery(bag, time_init, time_finish);
208 if (view.
size() == 0) {
218 bool has_left =
false;
219 bool has_right =
false;
221 double time0 = time_init.
toSec();
222 double time1 = time_init.
toSec();
232 sensor_msgs::Image::ConstPtr s0 = m.instantiate<sensor_msgs::Image>();
233 if (s0 !=
nullptr && m.getTopic() == topic_camera0) {
244 cv::equalizeHist(cv_ptr->image, img0);
246 time0 = cv_ptr->header.stamp.toSec();
250 sensor_msgs::Image::ConstPtr s1 = m.instantiate<sensor_msgs::Image>();
251 if (s1 !=
nullptr && m.getTopic() == topic_camera1) {
262 cv::equalizeHist(cv_ptr->image, img1);
264 time1 = cv_ptr->header.stamp.toSec();
268 if (has_left && has_right) {
284 void handle_stereo(
double time0,
double time1, cv::Mat img0, cv::Mat img1) {
288 cv::Mat mask = cv::Mat::zeros(cv::Size(img0.cols, img0.rows), CV_8UC1);
289 static cv::Point2f ball_center;
290 static cv::Point2f ball_velocity;
291 if (ball_velocity.x == 0 || ball_velocity.y == 0) {
292 ball_center.x = (float)img0.cols / 2.0f;
293 ball_center.y = (
float)img0.rows / 2.0f;
294 ball_velocity.x = 2.5;
295 ball_velocity.y = 2.5;
297 ball_center += ball_velocity;
298 if (ball_center.x < 0 || (
int)ball_center.x > img0.cols)
299 ball_velocity.x *= -1;
300 if (ball_center.y < 0 || (
int)ball_center.y > img0.rows)
301 ball_velocity.y *= -1;
302 cv::circle(mask, ball_center, 100, cv::Scalar(255), cv::FILLED);
308 message.
images.push_back(img0);
309 message.
masks.push_back(mask);
312 message.
images.push_back(img1);
313 message.
masks.push_back(mask);
318 cv::Mat img_active, img_history;
323 cv::imshow(
"Active Tracks", img_active);
324 cv::imshow(
"Track History", img_history);
329 std::vector<std::shared_ptr<Feature>> feats_lost = database->features_not_containing_newer(time0);
333 for (
size_t i = 0; i < feats_lost.size(); i++) {
336 for (
auto const &pair : feats_lost[i]->timestamps) {
337 total_meas += (int)pair.second.size();
341 feats_lost[i]->to_delete =
true;
352 std::vector<std::shared_ptr<Feature>> feats_marg = database->features_containing(margtime);
355 for (
size_t i = 0; i < feats_marg.size(); i++) {
356 feats_marg[i]->to_delete =
true;
374 PRINT_DEBUG(
"fps = %.2f | lost_feats/frame = %.2f | track_length/lost_feat = %.2f | marg_tracks/frame = %.2f\n", fps, lpf, fpf, mpf);