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 #if CV_MAJOR_VERSION > 4 || ( CV_MAJOR_VERSION == 4 && CV_MINOR_VERSION >= 7)
98 aruco_detector.detectMarkers(img0, corners[cam_id], ids_aruco[cam_id], rejects[cam_id]);
100 cv::aruco::detectMarkers(img0, aruco_dict, corners[cam_id], ids_aruco[cam_id], aruco_params, rejects[cam_id]);
102 rT2 = boost::posix_time::microsec_clock::local_time();
111 for (
size_t i = 0; i < corners[cam_id].size(); i++) {
112 for (
size_t j = 0; j < corners[cam_id].at(i).size(); j++) {
113 corners[cam_id].at(i).at(j).x *= 2;
114 corners[cam_id].at(i).at(j).y *= 2;
117 for (
size_t i = 0; i < rejects[cam_id].size(); i++) {
118 for (
size_t j = 0; j < rejects[cam_id].at(i).size(); j++) {
119 rejects[cam_id].at(i).at(j).x *= 2;
120 rejects[cam_id].at(i).at(j).y *= 2;
129 std::vector<size_t> ids_new;
130 std::vector<cv::KeyPoint> pts_new;
133 for (
size_t i = 0; i < ids_aruco[cam_id].size(); i++) {
138 assert(corners[cam_id].at(i).size() == 4);
139 for (
int n = 0; n < 4; n++) {
142 if (maskin.at<uint8_t>((
int)corners[cam_id].at(i).at(n).y, (
int)corners[cam_id].at(i).at(n).x) > 127)
145 cv::Point2f npt_l =
camera_calib.at(cam_id)->undistort_cv(corners[cam_id].at(i).at(n));
147 size_t tmp_id = (size_t)ids_aruco[cam_id].at(i) + n *
max_tag_id;
148 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);
151 kpt.pt = corners[cam_id].at(i).at(n);
152 ids_new.push_back(tmp_id);
153 pts_new.push_back(kpt);
165 rT3 = boost::posix_time::microsec_clock::local_time();
168 PRINT_ALL(
"[TIME-ARUCO]: %.4f seconds for detection\n", (
rT2 -
rT1).total_microseconds() * 1e-6);
169 PRINT_ALL(
"[TIME-ARUCO]: %.4f seconds for feature DB update (%d features)\n", (
rT3 -
rT2).total_microseconds() * 1e-6,
170 (
int)ids_new.size());
171 PRINT_ALL(
"[TIME-ARUCO]: %.4f seconds for total\n", (
rT3 -
rT1).total_microseconds() * 1e-6);
177 std::map<size_t, cv::Mat> img_last_cache, img_mask_last_cache;
183 auto ids_aruco_cache = ids_aruco;
184 auto corners_cache = corners;
185 auto rejects_cache = rejects;
190 for (
auto const &pair : img_last_cache) {
191 if (max_width < pair.second.cols)
192 max_width = pair.second.cols;
193 if (max_height < pair.second.rows)
194 max_height = pair.second.rows;
198 if (img_last_cache.empty() || max_width == -1 || max_height == -1)
202 bool is_small = (std::min(max_width, max_height) < 400);
206 bool image_new = ((int)img_last_cache.size() * max_width != img_out.cols || max_height != img_out.rows);
210 img_out = cv::Mat(max_height, (
int)img_last_cache.size() * max_width, CV_8UC3, cv::Scalar(0, 0, 0));
214 for (
auto const &pair : img_last_cache) {
218 cv::cvtColor(img_last_cache[pair.first], img_temp, cv::COLOR_GRAY2RGB);
220 img_temp = img_out(cv::Rect(max_width * index_cam, 0, max_width, max_height));
222 if (!ids_aruco_cache[pair.first].empty())
223 cv::aruco::drawDetectedMarkers(img_temp, corners_cache[pair.first], ids_aruco_cache[pair.first]);
224 if (!rejects_cache[pair.first].empty())
225 cv::aruco::drawDetectedMarkers(img_temp, rejects_cache[pair.first], cv::noArray(), cv::Scalar(100, 0, 255));
227 auto txtpt = (is_small) ? cv::Point(10, 30) : cv::Point(30, 60);
229 cv::putText(img_temp,
"CAM:" + std::to_string((
int)pair.first), txtpt, cv::FONT_HERSHEY_COMPLEX_SMALL, (is_small) ? 1.5 : 3.0,
230 cv::Scalar(0, 255, 0), 3);
232 cv::putText(img_temp, overlay, txtpt, cv::FONT_HERSHEY_COMPLEX_SMALL, (is_small) ? 1.5 : 3.0, cv::Scalar(0, 0, 255), 3);
235 cv::Mat mask = cv::Mat::zeros(img_mask_last_cache[pair.first].rows, img_mask_last_cache[pair.first].cols, CV_8UC3);
236 mask.setTo(cv::Scalar(0, 0, 255), img_mask_last_cache[pair.first]);
237 cv::addWeighted(mask, 0.1, img_temp, 1.0, 0.0, img_temp);
239 img_temp.copyTo(img_out(cv::Rect(max_width * index_cam, 0, img_last_cache[pair.first].cols, img_last_cache[pair.first].rows)));