ibgho_tracker_node.cpp
Go to the documentation of this file.
1 #include <cv_bridge/cv_bridge.h>
2 #include <homography_optimizer/ibg.h>
4 #include <opencv2/highgui/highgui.hpp>
5 #include <ros/ros.h>
6 #include <std_msgs/Char.h>
7 #include <vtec_msgs/TrackingResult.h>
8 
10 
11 VTEC::IBGHomographyOptimizer *ibg_optimizer;
12 
13 cv::Mat H;
14 float alpha, beta;
18 
22 
25 
26 bool start_command = false;
27 cv::Mat cur_img;
28 
29 int image_index = 0;
30 
42 void fillTrackingMsg(vtec_msgs::TrackingResult &msg, const double score,
43  const cv::Mat &H, const float alpha, const float beta,
44  int bbox_size_x, int bbox_size_y) {
45  cv::Point2f p1(0, 0), p2(0, bbox_size_y), p3(bbox_size_x, 0),
46  p4(bbox_size_x, bbox_size_y);
47  VTEC::warpPoints(p1, H);
48  VTEC::warpPoints(p2, H);
49  VTEC::warpPoints(p3, H);
50  VTEC::warpPoints(p4, H);
51 
52  geometry_msgs::Point p;
53  p.z = 0.0;
54  p.x = p1.x;
55  p.y = p1.y;
56  msg.corners[0] = p;
57 
58  p.x = p2.x;
59  p.y = p2.y;
60  msg.corners[1] = p;
61 
62  p.x = p3.x;
63  p.y = p3.y;
64  msg.corners[2] = p;
65 
66  p.x = p4.x;
67  p.y = p4.y;
68  msg.corners[3] = p;
69 
70  msg.alpha = alpha;
71  msg.beta = beta;
72  msg.score = score;
73 
74  msg.homography[0] = H.at<double>(0, 0);
75  msg.homography[1] = H.at<double>(0, 1);
76  msg.homography[2] = H.at<double>(0, 2);
77  msg.homography[3] = H.at<double>(1, 0);
78  msg.homography[4] = H.at<double>(1, 1);
79  msg.homography[5] = H.at<double>(1, 2);
80  msg.homography[6] = H.at<double>(2, 0);
81  msg.homography[7] = H.at<double>(2, 1);
82  msg.homography[8] = H.at<double>(2, 2);
83 }
84 
89  H = cv::Mat::eye(3, 3, CV_64F);
90  H.at<double>(0, 2) = BBOX_POS_X;
91  H.at<double>(1, 2) = BBOX_POS_Y;
92  ibg_optimizer->setHomography(H);
93  alpha = 1.0;
94  beta = 0.0;
95 
96  ibg_optimizer->setReferenceTemplate(cur_img, BBOX_POS_X, BBOX_POS_Y,
98  cv::Mat reference_template;
99  ibg_optimizer->getReferenceTemplate(reference_template);
100 
101  reference_template.convertTo(out_ref_template, CV_8U);
102 }
103 
109 void imageCallback(const sensor_msgs::ImageConstPtr &msg) {
110  try {
111  cur_img = cv_bridge::toCvShare(msg, "mono8")->image;
112  vtec_msgs::TrackingResult result_msg;
113  result_msg.header = msg->header;
114 
115  cv::Mat H_test = H.clone();
116  float alpha_test = alpha;
117  float beta_test = beta;
118 
119  double zncc = 0.0;
120 
121  bool force_reference_image_pub = false;
122 
123  if (start_command) {
124  ROS_INFO("Reference Image Selected");
125  start_command = false;
126  start_tracking();
127  force_reference_image_pub = true;
128  state = TRACKING;
129  }
130 
131  if (state != STARTING) {
132  zncc = ibg_optimizer->optimize(cur_img, H_test, alpha_test, beta_test,
133  VTEC::ZNCC_PREDICTOR);
134  }
135 
136  if (state == NOT_TRACKING && zncc > 0.5 ||
137  state == TRACKING && zncc > 0.0) {
138  state = TRACKING;
139  H = H_test;
140  alpha = alpha_test;
141  beta = beta_test;
142 
143  cv::Mat current_template;
144  ibg_optimizer->getCurrentTemplate(current_template);
145 
146  cv::Mat out_cur_template;
147  current_template.convertTo(out_cur_template, CV_8U);
148  sensor_msgs::ImagePtr stabilized_msg =
149  cv_bridge::CvImage(std_msgs::Header(), "mono8", out_cur_template)
150  .toImageMsg();
151  stabilized_pub_ptr->publish(stabilized_msg);
152 
153  VTEC::drawResult(cur_img, H, zncc, BBOX_SIZE_X, BBOX_SIZE_Y,
154  cv::Scalar(0.0, 255.0, 0.0));
155  fillTrackingMsg(result_msg, zncc, H, alpha, beta, BBOX_SIZE_X,
156  BBOX_SIZE_Y);
157  results_pub_ptr->publish(result_msg);
158 
159  if (ros::Time::now() - last_ref_pub_time > ros::Duration(5.0) ||
160  force_reference_image_pub) {
161  sensor_msgs::ImagePtr reference_msg =
162  cv_bridge::CvImage(std_msgs::Header(), "mono8", out_ref_template)
163  .toImageMsg();
164  reference_pub_ptr->publish(reference_msg);
165  last_ref_pub_time = ros::Time::now();
166  }
167  } else if (state != STARTING) {
169  }
170 
171  if (state != TRACKING) {
172  VTEC::drawResult(cur_img, H, zncc, BBOX_SIZE_X, BBOX_SIZE_Y);
173  cv::putText(cur_img, "press S to start tracking", cv::Point(30, 60),
174  CV_FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 3);
175  }
176 
177  sensor_msgs::ImagePtr annotated_msg =
178  cv_bridge::CvImage(std_msgs::Header(), "mono8", cur_img).toImageMsg();
179  annotated_msg->header.frame_id = "camera";
180  annotated_pub_ptr->publish(annotated_msg);
181  } catch (cv_bridge::Exception &e) {
182  ROS_ERROR("Could not convert from '%s' to 'mono8'.", msg->encoding.c_str());
183  }
184 }
185 
191 void cmdCallback(const std_msgs::Char cmd_msg) {
192  switch (cmd_msg.data) {
193  // S key
194  case 115:
195  ROS_INFO("(re)starting tracking");
196  start_command = true;
197  break;
198  default:
199  break;
200  }
201 }
202 
203 int main(int argc, char **argv) {
204  ros::init(argc, argv, "ibgho_tracker_node");
205  ros::NodeHandle nh;
206  ros::NodeHandle nhPrivate("~");
207 
208  // Tracker Parameters
209  int MAX_NB_ITERATION_PER_LEVEL;
210  int MAX_NB_PYR_LEVEL;
211  double PIXEL_KEEP_RATE;
212  std::string reference_image_path;
213  std::string image_topic = "usb_cam/image_raw";
214  std::string homography_type = "full";
215  bool robust_flag = false;
216 
217  nhPrivate.param<int>("bbox_pos_x", BBOX_POS_X, 200);
218  nhPrivate.param<int>("bbox_pos_y", BBOX_POS_Y, 150);
219  nhPrivate.param<int>("bbox_size_x", BBOX_SIZE_X, 200);
220  nhPrivate.param<int>("bbox_size_y", BBOX_SIZE_Y, 200);
221  nhPrivate.param<int>("max_nb_iter_per_level", MAX_NB_ITERATION_PER_LEVEL, 5);
222  nhPrivate.param<int>("max_nb_pyr_level", MAX_NB_PYR_LEVEL, 2);
223  nhPrivate.param<double>("sampling_rate", PIXEL_KEEP_RATE, 1.0);
224  nhPrivate.getParam("image_topic", image_topic);
225  nhPrivate.getParam("homography_type", homography_type);
226  nhPrivate.getParam("robust_flag", robust_flag);
227 
228  // Register publisher
230  image_transport::Publisher annotated_pub = it.advertise("annotated_image", 1);
231  annotated_pub_ptr = &annotated_pub;
232 
233  image_transport::Publisher stabilized_pub =
234  it.advertise("stabilized_image", 1);
235  stabilized_pub_ptr = &stabilized_pub;
236 
237  image_transport::Publisher reference_pub = it.advertise("reference_image", 1);
238  reference_pub_ptr = &reference_pub;
239 
240  ros::Publisher results_pub =
241  nh.advertise<vtec_msgs::TrackingResult>("tracking", 1);
242  results_pub_ptr = &results_pub;
243 
244  image_transport::Subscriber sub = it.subscribe(image_topic, 1, imageCallback);
245 
246  ros::Subscriber cmd_sub = nh.subscribe("track_cmd", 1, cmdCallback);
247 
248  // Initialize the optimizer according to the homography type
249  if (homography_type == "affine") {
250  ibg_optimizer = new VTEC::IBGAffineHomographyOptimizer();
251  } else if (homography_type == "stretch") {
252  ibg_optimizer = new VTEC::IBGStretchHomographyOptimizer();
253  } else {
254  ibg_optimizer = new VTEC::IBGFullHomographyOptimizer();
255  }
256 
257  ibg_optimizer->initialize(MAX_NB_ITERATION_PER_LEVEL, MAX_NB_PYR_LEVEL,
258  PIXEL_KEEP_RATE);
259  ibg_optimizer->setRobustFlag(robust_flag);
260 
261  if (robust_flag) {
262  ROS_INFO("USING ROBUST METHOD");
263  }
264 
265  // Start optimizer
266  H = cv::Mat::eye(3, 3, CV_64F);
267  H.at<double>(0, 2) = BBOX_POS_X;
268  H.at<double>(1, 2) = BBOX_POS_Y;
269  ibg_optimizer->setHomography(H);
270  alpha = 1.0;
271  beta = 0.0;
272 
273  last_ref_pub_time = ros::Time::now();
274 
275  ros::spin();
276 }
cv::Mat cur_img
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())
void publish(const boost::shared_ptr< M > &message) const
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
Publisher advertise(const std::string &base_topic, uint32_t queue_size, bool latch=false)
void fillTrackingMsg(vtec_msgs::TrackingResult &msg, const double score, const cv::Mat &H, const float alpha, const float beta, int bbox_size_x, int bbox_size_y)
Fills a vtec_msgs/TrackingResult message.
int BBOX_SIZE_Y
image_transport::Publisher * stabilized_pub_ptr
int BBOX_POS_Y
ROSCPP_DECL void spin(Spinner &spinner)
float beta
int main(int argc, char **argv)
int BBOX_POS_X
VTEC::IBGHomographyOptimizer * ibg_optimizer
cv::Mat H
void publish(const sensor_msgs::Image &message) const
#define ROS_INFO(...)
cv::Mat out_ref_template
bool param(const std::string &param_name, T &param_val, const T &default_val) const
image_transport::Publisher * annotated_pub_ptr
tracking_states
int image_index
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
float alpha
void imageCallback(const sensor_msgs::ImageConstPtr &msg)
Callback to handle incoming images.
ros::Publisher * results_pub_ptr
int BBOX_SIZE_X
bool start_command
void start_tracking()
Starts a tracking.
bool getParam(const std::string &key, std::string &s) const
void cmdCallback(const std_msgs::Char cmd_msg)
Callback for the keyboard command.
static Time now()
image_transport::Publisher * reference_pub_ptr
#define ROS_ERROR(...)
int state
ros::Time last_ref_pub_time


vtec_tracker
Author(s):
autogenerated on Sat Dec 7 2019 03:17:05