aruco_tracker.cpp
Go to the documentation of this file.
1 // Copyright 2022 Kell Ideas sp. z o.o.
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a copy
4 // of this software and associated documentation files (the "Software"), to deal
5 // in the Software without restriction, including without limitation the rights
6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 // copies of the Software, and to permit persons to whom the Software is
8 // furnished to do so, subject to the following conditions:
9 //
10 // The above copyright notice and this permission notice shall be included in
11 // all copies or substantial portions of the Software.
12 //
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 // THE SOFTWARE.
20 
21 #include <mutex>
22 
23 #include <opencv2/aruco.hpp>
24 #include <opencv2/calib3d.hpp>
25 #include <yaml-cpp/yaml.h>
26 
27 #include <nodelet/nodelet.h>
29 #include <ros/ros.h>
30 
31 #include <cv_bridge/cv_bridge.h>
32 #include <dynamic_reconfigure/server.h>
38 
39 #include <aruco_opencv/ArucoDetectorConfig.h>
40 #include <aruco_opencv/utils.hpp>
41 #include <aruco_opencv_msgs/ArucoDetection.h>
42 
43 namespace aruco_opencv {
44 
46 
47  // Parameters
48  std::string cam_base_topic_;
50  std::string output_frame_;
51  std::string marker_dict_;
54  double marker_size_;
57 
58  // ROS
62  bool cam_info_retrieved_ = false;
67  dynamic_reconfigure::Server<aruco_opencv::ArucoDetectorConfig> *dyn_srv_;
68 
69  // Aruco
70  cv::Mat camera_matrix_;
73  cv::Ptr<cv::aruco::DetectorParameters> detector_parameters_;
74  cv::Ptr<cv::aruco::Dictionary> dictionary_;
75  std::vector<std::pair<std::string, cv::Ptr<cv::aruco::Board>>> boards_;
76 
77  // Thread safety
78  std::mutex cam_info_mutex_;
79 
80  // Tf2
84 
85 public:
87  : camera_matrix_(3, 3, CV_64FC1), distortion_coeffs_(4, 1, CV_64FC1, cv::Scalar(0)),
88  marker_obj_points_(4, 1, CV_32FC3) {}
89 
90 private:
91  void onInit() override {
92  auto &nh = getNodeHandle();
93  auto &pnh = getPrivateNodeHandle();
94 
95  detector_parameters_ = cv::aruco::DetectorParameters::create();
96 
98 
99  if (ARUCO_DICT_MAP.find(marker_dict_) == ARUCO_DICT_MAP.end()) {
100  ROS_ERROR_STREAM("Unsupported dictionary name: " << marker_dict_);
101  return;
102  }
103 
104  dictionary_ = cv::aruco::getPredefinedDictionary(ARUCO_DICT_MAP.at(marker_dict_));
105 
106  if (!board_descriptions_path_.empty())
107  load_boards();
108 
109  dyn_srv_ = new dynamic_reconfigure::Server<aruco_opencv::ArucoDetectorConfig>(pnh);
110  dyn_srv_->setCallback(boost::bind(&ArucoTracker::reconfigure_callback, this, _1, _2));
111 
112  if (transform_poses_)
114 
115  if (publish_tf_)
117 
118  // set coordinate system in the middle of the marker, with Z pointing out
119  marker_obj_points_.ptr<cv::Vec3f>(0)[0] = cv::Vec3f(-marker_size_ / 2.f, marker_size_ / 2.f, 0);
120  marker_obj_points_.ptr<cv::Vec3f>(0)[1] = cv::Vec3f(marker_size_ / 2.f, marker_size_ / 2.f, 0);
121  marker_obj_points_.ptr<cv::Vec3f>(0)[2] = cv::Vec3f(marker_size_ / 2.f, -marker_size_ / 2.f, 0);
122  marker_obj_points_.ptr<cv::Vec3f>(0)[3] =
123  cv::Vec3f(-marker_size_ / 2.f, -marker_size_ / 2.f, 0);
124 
127 
128  detection_pub_ = nh.advertise<aruco_opencv_msgs::ArucoDetection>("aruco_detections", 5);
129  debug_pub_ = pit_->advertise("debug", 1);
130 
131  NODELET_INFO("Waiting for first camera info...");
132 
133  std::string cam_info_topic = image_transport::getCameraInfoTopic(cam_base_topic_);
134  cam_info_sub_ = nh.subscribe(cam_info_topic, 1, &ArucoTracker::callback_camera_info, this);
135 
136  img_sub_ =
138  }
139 
141  pnh.param<std::string>("cam_base_topic", cam_base_topic_, "camera/image_raw");
142  ROS_INFO_STREAM("Camera Base Topic: " << cam_base_topic_);
143 
144  pnh.param<bool>("image_is_rectified", image_is_rectified_, false);
145  ROS_INFO_STREAM("Assume images are rectified: " << (image_is_rectified_ ? "YES" : "NO"));
146 
147  pnh.param<std::string>("output_frame", output_frame_, "");
148  if (output_frame_.empty()) {
149  ROS_INFO("Marker detections will be published in the camera frame");
150  transform_poses_ = false;
151  } else {
152  ROS_INFO("Marker detections will be transformed to \'%s\' frame", output_frame_.c_str());
153  transform_poses_ = true;
154  }
155 
156  pnh.param<std::string>("marker_dict", marker_dict_, "4X4_50");
157  ROS_INFO_STREAM("Marker Dictionary name: " << marker_dict_);
158 
159  pnh.param<bool>("publish_tf", publish_tf_, true);
160  ROS_INFO_STREAM("TF publishing is " << (publish_tf_ ? "enabled" : "disabled"));
161 
162  pnh.param<double>("marker_size", marker_size_, 0.15);
163  ROS_INFO_STREAM("Marker size: " << marker_size_);
164 
165  pnh.param<int>("image_queue_size", image_queue_size_, 1);
166  ROS_INFO_STREAM("Image Queue size: " << image_queue_size_);
167 
168  pnh.param<std::string>("board_descriptions_path", board_descriptions_path_, "");
169  }
170 
171  void load_boards() {
172  ROS_INFO_STREAM("Trying to load board descriptions from " << board_descriptions_path_);
173 
174  YAML::Node descriptions;
175  try {
176  descriptions = YAML::LoadFile(board_descriptions_path_);
177  } catch (const YAML::Exception &e) {
178  ROS_ERROR_STREAM("Failed to load board descriptions: " << e.what());
179  return;
180  }
181 
182  if (!descriptions.IsSequence()) {
183  ROS_ERROR_STREAM("Failed to load board descriptions: root node is not a sequence");
184  }
185 
186  for (const YAML::Node &desc : descriptions) {
187  std::string name;
188  try {
189  name = desc["name"].as<std::string>();
190  const bool frame_at_center = desc["frame_at_center"].as<bool>();
191  const int markers_x = desc["markers_x"].as<int>();
192  const int markers_y = desc["markers_y"].as<int>();
193  const double marker_size = desc["marker_size"].as<double>();
194  const double separation = desc["separation"].as<double>();
195 
196  auto board = cv::aruco::GridBoard::create(markers_x, markers_y, marker_size, separation,
197  dictionary_, desc["first_id"].as<int>());
198 
199  if (frame_at_center) {
200  double offset_x = (markers_x * (marker_size + separation) - separation) / 2.0;
201  double offset_y = (markers_y * (marker_size + separation) - separation) / 2.0;
202  for (auto &obj : board->objPoints) {
203  for (auto &point : obj) {
204  point.x -= offset_x;
205  point.y -= offset_y;
206  }
207  }
208  }
209 
210  boards_.push_back(std::make_pair(name, board));
211  } catch (const YAML::Exception &e) {
212  ROS_ERROR_STREAM("Failed to load board '" << name << "': " << e.what());
213  continue;
214  }
215  ROS_INFO_STREAM("Successfully loaded configuration for board '" << name << "'");
216  }
217  }
218 
219  void reconfigure_callback(aruco_opencv::ArucoDetectorConfig &config, uint32_t level) {
220  if (config.adaptiveThreshWinSizeMax < config.adaptiveThreshWinSizeMin)
221  config.adaptiveThreshWinSizeMax = config.adaptiveThreshWinSizeMin;
222 
223  if (config.maxMarkerPerimeterRate < config.minMarkerPerimeterRate)
224  config.maxMarkerPerimeterRate = config.minMarkerPerimeterRate;
225 
226  detector_parameters_->adaptiveThreshWinSizeMin = config.adaptiveThreshWinSizeMin;
227  detector_parameters_->adaptiveThreshWinSizeMax = config.adaptiveThreshWinSizeMax;
228  detector_parameters_->adaptiveThreshWinSizeStep = config.adaptiveThreshWinSizeStep;
229  detector_parameters_->adaptiveThreshConstant = config.adaptiveThreshConstant;
230  detector_parameters_->minMarkerPerimeterRate = config.minMarkerPerimeterRate;
231  detector_parameters_->maxMarkerPerimeterRate = config.maxMarkerPerimeterRate;
232  detector_parameters_->polygonalApproxAccuracyRate = config.polygonalApproxAccuracyRate;
233  detector_parameters_->minCornerDistanceRate = config.minCornerDistanceRate;
234  detector_parameters_->minDistanceToBorder = config.minDistanceToBorder;
235  detector_parameters_->minMarkerDistanceRate = config.minMarkerDistanceRate;
236  detector_parameters_->markerBorderBits = config.markerBorderBits;
237  detector_parameters_->perspectiveRemovePixelPerCell = config.perspectiveRemovePixelPerCell;
238  detector_parameters_->perspectiveRemoveIgnoredMarginPerCell =
239  config.perspectiveRemoveIgnoredMarginPerCell;
240  detector_parameters_->maxErroneousBitsInBorderRate = config.maxErroneousBitsInBorderRate;
241  detector_parameters_->minOtsuStdDev = config.minOtsuStdDev;
242  detector_parameters_->errorCorrectionRate = config.errorCorrectionRate;
243 #if CV_VERSION_MAJOR >= 4
244  detector_parameters_->cornerRefinementMethod = config.cornerRefinementMethod;
245 #else
246  detector_parameters_->doCornerRefinement = config.cornerRefinementMethod == 1;
247 #endif
248  detector_parameters_->cornerRefinementWinSize = config.cornerRefinementWinSize;
249  detector_parameters_->cornerRefinementMaxIterations = config.cornerRefinementMaxIterations;
250  detector_parameters_->cornerRefinementMinAccuracy = config.cornerRefinementMinAccuracy;
251  }
252 
253  void callback_camera_info(const sensor_msgs::CameraInfo &cam_info) {
254  std::lock_guard<std::mutex> guard(cam_info_mutex_);
255 
256  if (image_is_rectified_) {
257  for (int i = 0; i < 9; ++i)
258  camera_matrix_.at<double>(i / 3, i % 3) = cam_info.P[i + i/3];
259  } else {
260  for (int i = 0; i < 9; ++i)
261  camera_matrix_.at<double>(i / 3, i % 3) = cam_info.K[i];
262  distortion_coeffs_ = cv::Mat(cam_info.D, true);
263  }
264 
265  if (!cam_info_retrieved_) {
266  NODELET_INFO("First camera info retrieved.");
267  cam_info_retrieved_ = true;
268  }
269  }
270 
271  void callback_image(const sensor_msgs::ImageConstPtr &img_msg) {
272  ROS_DEBUG_STREAM("Image message address [SUBSCRIBE]:\t" << img_msg.get());
273 
274  if (!cam_info_retrieved_)
275  return;
276 
277  if (img_msg->header.stamp == last_msg_stamp) {
278  ROS_DEBUG("The new image has the same timestamp as the previous one (duplicate frame?). "
279  "Ignoring...");
280  return;
281  }
282  last_msg_stamp = img_msg->header.stamp;
283 
284  auto callback_start_time = ros::Time::now();
285 
286  // Convert the image
287  auto cv_ptr = cv_bridge::toCvShare(img_msg);
288 
289  std::vector<int> marker_ids;
290  std::vector<std::vector<cv::Point2f>> marker_corners;
291 
292  cv::aruco::detectMarkers(cv_ptr->image, dictionary_, marker_corners, marker_ids,
294 
295  int n_markers = marker_ids.size();
296  std::vector<cv::Vec3d> rvec_final(n_markers), tvec_final(n_markers);
297 
298  aruco_opencv_msgs::ArucoDetection detection;
299  detection.header.frame_id = img_msg->header.frame_id;
300  detection.header.stamp = img_msg->header.stamp;
301  detection.markers.resize(n_markers);
302 
303  {
304  std::lock_guard<std::mutex> guard(cam_info_mutex_);
305 #if CV_VERSION_MAJOR >= 4
306  cv::parallel_for_(cv::Range(0, n_markers), [&](const cv::Range &range) {
307 #else
308  const cv::Range range = cv::Range(0, n_markers);
309  ({
310 #endif
311  for (int i = range.start; i < range.end; i++) {
312  int id = marker_ids[i];
313 
314 #if CV_VERSION_MAJOR >= 4
315  cv::solvePnP(marker_obj_points_, marker_corners[i], camera_matrix_, distortion_coeffs_,
316  rvec_final[i], tvec_final[i], false, cv::SOLVEPNP_IPPE_SQUARE);
317 #else
318  cv::solvePnP(marker_obj_points_, marker_corners[i], camera_matrix_, distortion_coeffs_,
319  rvec_final[i], tvec_final[i], false, cv::SOLVEPNP_ITERATIVE);
320 #endif
321 
322  detection.markers[i].marker_id = id;
323  detection.markers[i].pose = convert_rvec_tvec(rvec_final[i], tvec_final[i]);
324  }
325  });
326 
327  for (const auto &board_desc : boards_) {
328  std::string name = board_desc.first;
329  auto &board = board_desc.second;
330 
331  cv::Vec3d rvec, tvec;
332  int valid = cv::aruco::estimatePoseBoard(marker_corners, marker_ids, board, camera_matrix_,
333  distortion_coeffs_, rvec, tvec);
334 
335  if (valid > 0) {
336  aruco_opencv_msgs::BoardPose bpose;
337  bpose.board_name = name;
338  bpose.pose = convert_rvec_tvec(rvec, tvec);
339  detection.boards.push_back(bpose);
340  rvec_final.push_back(rvec);
341  tvec_final.push_back(tvec);
342  n_markers++;
343  }
344  }
345  }
346 
347  if (transform_poses_ && n_markers > 0) {
348  detection.header.frame_id = output_frame_;
349  geometry_msgs::TransformStamped cam_to_output;
350  // Retrieve camera -> output_frame transform
351  try {
352  cam_to_output = tf_buffer_.lookupTransform(output_frame_, img_msg->header.frame_id,
353  img_msg->header.stamp, ros::Duration(1.0));
354  } catch (tf2::TransformException &ex) {
355  ROS_WARN("%s", ex.what());
356  return;
357  }
358  for (auto &marker_pose : detection.markers)
359  tf2::doTransform(marker_pose.pose, marker_pose.pose, cam_to_output);
360  for (auto &board_pose : detection.boards)
361  tf2::doTransform(board_pose.pose, board_pose.pose, cam_to_output);
362  }
363 
364  if (publish_tf_ && n_markers > 0) {
365  std::vector<geometry_msgs::TransformStamped> transforms;
366  for (auto &marker_pose : detection.markers) {
367  geometry_msgs::TransformStamped transform;
368  transform.header.stamp = detection.header.stamp;
369  transform.header.frame_id = detection.header.frame_id;
370  transform.child_frame_id = std::string("marker_") + std::to_string(marker_pose.marker_id);
371  tf2::Transform tf_transform;
372  tf2::fromMsg(marker_pose.pose, tf_transform);
373  transform.transform = tf2::toMsg(tf_transform);
374  transforms.push_back(transform);
375  }
376  for (auto &board_pose : detection.boards) {
377  geometry_msgs::TransformStamped transform;
378  transform.header.stamp = detection.header.stamp;
379  transform.header.frame_id = detection.header.frame_id;
380  transform.child_frame_id = std::string("board_") + board_pose.board_name;
381  tf2::Transform tf_transform;
382  tf2::fromMsg(board_pose.pose, tf_transform);
383  transform.transform = tf2::toMsg(tf_transform);
384  transforms.push_back(transform);
385  }
386  tf_broadcaster_->sendTransform(transforms);
387  }
388 
389  detection_pub_.publish(detection);
390 
391  if (debug_pub_.getNumSubscribers() > 0) {
392  auto debug_cv_ptr = cv_bridge::toCvCopy(img_msg, "bgr8");
393  cv::aruco::drawDetectedMarkers(debug_cv_ptr->image, marker_corners, marker_ids);
394  {
395  std::lock_guard<std::mutex> guard(cam_info_mutex_);
396  for (size_t i = 0; i < n_markers; i++) {
397 #if CV_VERSION_MAJOR >= 4
398  cv::drawFrameAxes(debug_cv_ptr->image, camera_matrix_, distortion_coeffs_, rvec_final[i],
399  tvec_final[i], 0.2, 3);
400 #else
401  cv::aruco::drawAxis(debug_cv_ptr->image, camera_matrix_, distortion_coeffs_,
402  rvec_final[i], tvec_final[i], 0.2);
403 #endif
404  }
405  }
406 
407  debug_pub_.publish(debug_cv_ptr->toImageMsg());
408  }
409 
410  auto callback_end_time = ros::Time::now();
411  double whole_callback_duration = (callback_end_time - callback_start_time).toSec();
412  double image_send_duration = (callback_start_time - img_msg->header.stamp).toSec();
413 
414  NODELET_DEBUG("Image callback completed. The callback started %.4f s after "
415  "the image frame was "
416  "grabbed and completed its execution in %.4f s.",
417  image_send_duration, whole_callback_duration);
418  }
419 };
420 
421 } // namespace aruco_opencv
422 
aruco_opencv::ArucoTracker::camera_matrix_
cv::Mat camera_matrix_
Definition: aruco_tracker.cpp:70
image_transport::getCameraInfoTopic
IMAGE_TRANSPORT_DECL std::string getCameraInfoTopic(const std::string &base_topic)
aruco_opencv::ArucoTracker::detection_pub_
ros::Publisher detection_pub_
Definition: aruco_tracker.cpp:59
ros::Publisher
nodelet::Nodelet::getNodeHandle
ros::NodeHandle & getNodeHandle() const
aruco_opencv::ArucoTracker::tf_broadcaster_
tf2_ros::TransformBroadcaster * tf_broadcaster_
Definition: aruco_tracker.cpp:83
image_transport::ImageTransport
aruco_opencv::ArucoTracker::it_
image_transport::ImageTransport * it_
Definition: aruco_tracker.cpp:63
aruco_opencv::ArucoTracker::boards_
std::vector< std::pair< std::string, cv::Ptr< cv::aruco::Board > > > boards_
Definition: aruco_tracker.cpp:75
ROS_ERROR_STREAM
#define ROS_ERROR_STREAM(args)
utils.hpp
aruco_opencv::ArucoTracker::marker_dict_
std::string marker_dict_
Definition: aruco_tracker.cpp:51
tf2::fromMsg
void fromMsg(const A &, B &b)
ros.h
aruco_opencv::ArucoTracker::callback_image
void callback_image(const sensor_msgs::ImageConstPtr &img_msg)
Definition: aruco_tracker.cpp:271
aruco_opencv
Definition: utils.hpp:31
image_transport::Publisher::getNumSubscribers
uint32_t getNumSubscribers() const
aruco_opencv::ARUCO_DICT_MAP
const std::unordered_map< std::string, cv::aruco::PREDEFINED_DICTIONARY_NAME > ARUCO_DICT_MAP
Definition: utils.cpp:50
aruco_opencv::convert_rvec_tvec
geometry_msgs::Pose convert_rvec_tvec(const cv::Vec3d &rvec, const cv::Vec3d &tvec)
Definition: utils.cpp:30
aruco_opencv::ArucoTracker::cam_info_retrieved_
bool cam_info_retrieved_
Definition: aruco_tracker.cpp:62
aruco_opencv::ArucoTracker::callback_camera_info
void callback_camera_info(const sensor_msgs::CameraInfo &cam_info)
Definition: aruco_tracker.cpp:253
aruco_opencv::ArucoTracker::board_descriptions_path_
std::string board_descriptions_path_
Definition: aruco_tracker.cpp:56
ROS_DEBUG_STREAM
#define ROS_DEBUG_STREAM(args)
nodelet::Nodelet::getPrivateNodeHandle
ros::NodeHandle & getPrivateNodeHandle() const
ros::Publisher::publish
void publish(const boost::shared_ptr< M > &message) const
aruco_opencv::ArucoTracker::debug_pub_
image_transport::Publisher debug_pub_
Definition: aruco_tracker.cpp:66
transform_broadcaster.h
aruco_opencv::ArucoTracker
Definition: aruco_tracker.cpp:45
f
f
aruco_opencv::ArucoTracker::distortion_coeffs_
cv::Mat distortion_coeffs_
Definition: aruco_tracker.cpp:71
image_transport::ImageTransport::advertise
Publisher advertise(const std::string &base_topic, uint32_t queue_size, bool latch=false)
aruco_opencv::ArucoTracker::cam_info_sub_
ros::Subscriber cam_info_sub_
Definition: aruco_tracker.cpp:60
image_transport::Subscriber
tf2_ros::TransformListener
class_list_macros.h
PLUGINLIB_EXPORT_CLASS
#define PLUGINLIB_EXPORT_CLASS(class_type, base_class_type)
tf2_ros::TransformBroadcaster::sendTransform
void sendTransform(const geometry_msgs::TransformStamped &transform)
cv_bridge::toCvCopy
CvImagePtr toCvCopy(const sensor_msgs::CompressedImage &source, const std::string &encoding=std::string())
ROS_DEBUG
#define ROS_DEBUG(...)
image_transport::ImageTransport::subscribe
Subscriber subscribe(const std::string &base_topic, uint32_t queue_size, const boost::function< void(const sensor_msgs::ImageConstPtr &)> &callback, const ros::VoidPtr &tracked_object=ros::VoidPtr(), const TransportHints &transport_hints=TransportHints())
aruco_opencv::ArucoTracker::image_queue_size_
int image_queue_size_
Definition: aruco_tracker.cpp:55
aruco_opencv::ArucoTracker::ArucoTracker
ArucoTracker()
Definition: aruco_tracker.cpp:86
tf2::Transform
aruco_opencv::ArucoTracker::cam_base_topic_
std::string cam_base_topic_
Definition: aruco_tracker.cpp:48
ROS_WARN
#define ROS_WARN(...)
aruco_opencv::ArucoTracker::last_msg_stamp
ros::Time last_msg_stamp
Definition: aruco_tracker.cpp:61
tf2_ros::Buffer
aruco_opencv::ArucoTracker::dyn_srv_
dynamic_reconfigure::Server< aruco_opencv::ArucoDetectorConfig > * dyn_srv_
Definition: aruco_tracker.cpp:67
aruco_opencv::ArucoTracker::onInit
void onInit() override
Definition: aruco_tracker.cpp:91
ROS_INFO_STREAM
#define ROS_INFO_STREAM(args)
image_transport::Publisher::publish
void publish(const sensor_msgs::Image &message) const
aruco_opencv::ArucoTracker::load_boards
void load_boards()
Definition: aruco_tracker.cpp:171
aruco_opencv::ArucoTracker::tf_buffer_
tf2_ros::Buffer tf_buffer_
Definition: aruco_tracker.cpp:81
image_transport.h
aruco_opencv::ArucoTracker::tf_listener_
tf2_ros::TransformListener * tf_listener_
Definition: aruco_tracker.cpp:82
NODELET_INFO
#define NODELET_INFO(...)
transform_listener.h
camera_common.h
aruco_opencv::ArucoTracker::output_frame_
std::string output_frame_
Definition: aruco_tracker.cpp:50
nodelet::Nodelet
ros::Time
tf2::doTransform
void doTransform(const T &data_in, T &data_out, const geometry_msgs::TransformStamped &transform)
nodelet.h
image_transport::Publisher
aruco_opencv::ArucoTracker::retrieve_parameters
void retrieve_parameters(ros::NodeHandle &pnh)
Definition: aruco_tracker.cpp:140
cv_bridge.h
aruco_opencv::ArucoTracker::transform_poses_
bool transform_poses_
Definition: aruco_tracker.cpp:52
tf2_ros::TransformBroadcaster
aruco_opencv::ArucoTracker::reconfigure_callback
void reconfigure_callback(aruco_opencv::ArucoDetectorConfig &config, uint32_t level)
Definition: aruco_tracker.cpp:219
ros::NodeHandle::param
T param(const std::string &param_name, const T &default_val) const
tf2_geometry_msgs.h
tf2::toMsg
B toMsg(const A &a)
aruco_opencv::ArucoTracker::marker_obj_points_
cv::Mat marker_obj_points_
Definition: aruco_tracker.cpp:72
aruco_opencv::ArucoTracker::cam_info_mutex_
std::mutex cam_info_mutex_
Definition: aruco_tracker.cpp:78
cv_bridge::toCvShare
CvImageConstPtr toCvShare(const sensor_msgs::Image &source, const boost::shared_ptr< void const > &tracked_object, const std::string &encoding=std::string())
aruco_opencv::ArucoTracker::pit_
image_transport::ImageTransport * pit_
Definition: aruco_tracker.cpp:64
tf2::TransformException
ROS_INFO
#define ROS_INFO(...)
aruco_opencv::ArucoTracker::image_is_rectified_
bool image_is_rectified_
Definition: aruco_tracker.cpp:49
ros::Duration
aruco_opencv::ArucoTracker::detector_parameters_
cv::Ptr< cv::aruco::DetectorParameters > detector_parameters_
Definition: aruco_tracker.cpp:73
aruco_opencv::ArucoTracker::img_sub_
image_transport::Subscriber img_sub_
Definition: aruco_tracker.cpp:65
aruco_opencv::ArucoTracker::marker_size_
double marker_size_
Definition: aruco_tracker.cpp:54
tf2_ros::Buffer::lookupTransform
virtual geometry_msgs::TransformStamped lookupTransform(const std::string &target_frame, const ros::Time &target_time, const std::string &source_frame, const ros::Time &source_time, const std::string &fixed_frame, const ros::Duration timeout) const
aruco_opencv::ArucoTracker::dictionary_
cv::Ptr< cv::aruco::Dictionary > dictionary_
Definition: aruco_tracker.cpp:74
aruco_opencv::ArucoTracker::publish_tf_
bool publish_tf_
Definition: aruco_tracker.cpp:53
ros::NodeHandle
ros::Subscriber
NODELET_DEBUG
#define NODELET_DEBUG(...)
ros::Time::now
static Time now()


aruco_opencv
Author(s): Błażej Sowa
autogenerated on Fri Aug 2 2024 08:38:24