39 std::exit(EXIT_FAILURE);
45 size_t num_images = message.
images.size();
46 parallel_for_(cv::Range(0, (
int)num_images),
LambdaBody([&](
const cv::Range &range) {
47 for (
int i = range.start; i < range.end; i++) {
48 perform_tracking(message.timestamp, message.images.at(i), message.sensor_ids.at(i), message.masks.at(i));
53 std::exit(EXIT_FAILURE);
59 void TrackAruco::perform_tracking(
double timestamp,
const cv::Mat &imgin,
size_t cam_id,
const cv::Mat &maskin) {
62 rT1 = boost::posix_time::microsec_clock::local_time();
65 std::lock_guard<std::mutex> lck(
mtx_feeds.at(cam_id));
70 cv::equalizeHist(imgin, img);
72 double eq_clip_limit = 10.0;
73 cv::Size eq_win_size = cv::Size(8, 8);
74 cv::Ptr<cv::CLAHE> clahe = cv::createCLAHE(eq_clip_limit, eq_win_size);
75 clahe->apply(imgin, img);
81 ids_aruco[cam_id].clear();
82 corners[cam_id].clear();
83 rejects[cam_id].clear();
88 cv::pyrDown(img, img0, cv::Size(img.cols / 2, img.rows / 2));
97 cv::aruco::detectMarkers(img0, aruco_dict, corners[cam_id], ids_aruco[cam_id], aruco_params, rejects[cam_id]);
98 rT2 = boost::posix_time::microsec_clock::local_time();
107 for (
size_t i = 0; i < corners[cam_id].size(); i++) {
108 for (
size_t j = 0; j < corners[cam_id].at(i).size(); j++) {
109 corners[cam_id].at(i).at(j).x *= 2;
110 corners[cam_id].at(i).at(j).y *= 2;
113 for (
size_t i = 0; i < rejects[cam_id].size(); i++) {
114 for (
size_t j = 0; j < rejects[cam_id].at(i).size(); j++) {
115 rejects[cam_id].at(i).at(j).x *= 2;
116 rejects[cam_id].at(i).at(j).y *= 2;
125 std::vector<size_t> ids_new;
126 std::vector<cv::KeyPoint> pts_new;
129 for (
size_t i = 0; i < ids_aruco[cam_id].size(); i++) {
134 assert(corners[cam_id].at(i).size() == 4);
135 for (
int n = 0; n < 4; n++) {
138 if (maskin.at<uint8_t>((
int)corners[cam_id].at(i).at(n).y, (int)corners[cam_id].at(i).at(n).x) > 127)
141 cv::Point2f npt_l =
camera_calib.at(cam_id)->undistort_cv(corners[cam_id].at(i).at(n));
143 size_t tmp_id = (size_t)ids_aruco[cam_id].at(i) + n *
max_tag_id;
144 database->update_feature(tmp_id, timestamp, cam_id, corners[cam_id].at(i).at(n).x, corners[cam_id].at(i).at(n).y, npt_l.x, npt_l.y);
147 kpt.pt = corners[cam_id].at(i).at(n);
148 ids_new.push_back(tmp_id);
149 pts_new.push_back(kpt);
161 rT3 = boost::posix_time::microsec_clock::local_time();
164 PRINT_ALL(
"[TIME-ARUCO]: %.4f seconds for detection\n", (
rT2 -
rT1).total_microseconds() * 1e-6);
165 PRINT_ALL(
"[TIME-ARUCO]: %.4f seconds for feature DB update (%d features)\n", (
rT3 -
rT2).total_microseconds() * 1e-6,
166 (
int)ids_new.size());
167 PRINT_ALL(
"[TIME-ARUCO]: %.4f seconds for total\n", (
rT3 -
rT1).total_microseconds() * 1e-6);
173 std::map<size_t, cv::Mat> img_last_cache, img_mask_last_cache;
179 auto ids_aruco_cache = ids_aruco;
180 auto corners_cache = corners;
181 auto rejects_cache = rejects;
186 for (
auto const &pair : img_last_cache) {
187 if (max_width < pair.second.cols)
188 max_width = pair.second.cols;
189 if (max_height < pair.second.rows)
190 max_height = pair.second.rows;
194 if (img_last_cache.empty() || max_width == -1 || max_height == -1)
198 bool is_small = (std::min(max_width, max_height) < 400);
202 bool image_new = ((int)img_last_cache.size() * max_width != img_out.cols || max_height != img_out.rows);
206 img_out = cv::Mat(max_height, (
int)img_last_cache.size() * max_width, CV_8UC3, cv::Scalar(0, 0, 0));
210 for (
auto const &pair : img_last_cache) {
214 cv::cvtColor(img_last_cache[pair.first], img_temp, cv::COLOR_GRAY2RGB);
216 img_temp = img_out(cv::Rect(max_width * index_cam, 0, max_width, max_height));
218 if (!ids_aruco_cache[pair.first].empty())
219 cv::aruco::drawDetectedMarkers(img_temp, corners_cache[pair.first], ids_aruco_cache[pair.first]);
220 if (!rejects_cache[pair.first].empty())
221 cv::aruco::drawDetectedMarkers(img_temp, rejects_cache[pair.first], cv::noArray(), cv::Scalar(100, 0, 255));
223 auto txtpt = (is_small) ? cv::Point(10, 30) : cv::Point(30, 60);
225 cv::putText(img_temp,
"CAM:" + std::to_string((
int)pair.first), txtpt, cv::FONT_HERSHEY_COMPLEX_SMALL, (is_small) ? 1.5 : 3.0,
226 cv::Scalar(0, 255, 0), 3);
228 cv::putText(img_temp, overlay, txtpt, cv::FONT_HERSHEY_COMPLEX_SMALL, (is_small) ? 1.5 : 3.0, cv::Scalar(0, 0, 255), 3);
231 cv::Mat mask = cv::Mat::zeros(img_mask_last_cache[pair.first].rows, img_mask_last_cache[pair.first].cols, CV_8UC3);
232 mask.setTo(cv::Scalar(0, 0, 255), img_mask_last_cache[pair.first]);
233 cv::addWeighted(mask, 0.1, img_temp, 1.0, 0.0, img_temp);
235 img_temp.copyTo(img_out(cv::Rect(max_width * index_cam, 0, img_last_cache[pair.first].cols, img_last_cache[pair.first].rows)));
std::map< size_t, cv::Mat > img_mask_last
Last set of images (use map so all trackers render in the same order)
std::map< size_t, cv::Mat > img_last
Last set of images (use map so all trackers render in the same order)
std::vector< cv::Mat > images
Raw image we have collected for each camera.
boost::posix_time::ptime rT2
std::unordered_map< size_t, std::vector< cv::KeyPoint > > pts_last
Last set of tracked points.
Struct for a collection of camera measurements.
std::unordered_map< size_t, std::vector< size_t > > ids_last
Set of IDs of each current feature in the database.
boost::posix_time::ptime rT3
std::vector< int > sensor_ids
Camera ids for each of the images collected.
HistogramMethod histogram_method
What histogram equalization method we should pre-process images with?
std::vector< cv::Mat > masks
Tracking masks for each camera we have.
void feed_new_camera(const CameraData &message) override
Process a new image.
virtual void display_active(cv::Mat &img_out, int r1, int g1, int b1, int r2, int g2, int b2, std::string overlay="")
Shows features extracted in the last image.
std::unordered_map< size_t, std::shared_ptr< CamBase > > camera_calib
Camera object which has all calibration in it.
Core algorithms for OpenVINS.
#define PRINT_ERROR(x...)
std::shared_ptr< FeatureDatabase > database
Database with all our current features.
boost::posix_time::ptime rT1
std::mutex mtx_last_vars
Mutex for editing the *_last variables.
std::vector< std::mutex > mtx_feeds
Mutexs for our last set of image storage (img_last, pts_last, and ids_last)