pose_estimation_combomarker_node.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016, Lukas Pfeifhofer <lukas.pfeifhofer@devlabs.pro>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation
13  * and/or other materials provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its contributors
16  * may be used to endorse or promote products derived from this software without
17  * specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
33 
34 #include "marker_fiducials.h"
35 #include "opencv2/opencv.hpp"
36 #include <opencv2/highgui/highgui.hpp>
37 #include "pose_estimation_base.h"
39 
40 
41 int main(int argc, char **argv) {
42  ros::init(argc, argv, "arPoseEstimation");
44  PoseEstimationComboMarkerNode poseEstimationNode(n);
45  ros::spin();
46  return EXIT_SUCCESS;
47 }
48 
50  idFiducialDetectionSubscriber_(n_, "idFiducials", 100),
51  ellipseFiducialDetectionSubscriber_(n_, "ellipseFiducials", 100),
52  sync_(idFiducialDetectionSubscriber_, ellipseFiducialDetectionSubscriber_, 10){
53  // Advert marker publisher
54  pub_markers_ = n_.advertise<marker_msgs::MarkerDetection>("markers", 10);
55 
57 }
58 
60 
61 
62 void PoseEstimationComboMarkerNode::synchronizedFiducialsCallback(const marker_msgs::FiducialDetection::ConstPtr &msgIdFiducialDetection,
63  const marker_msgs::FiducialDetection::ConstPtr &msgEllipseFiducialDetection){
64  //ROS_INFO("fired synchronizedFiducialsCallback: %d, %d", msgIdFiducialDetection->header.seq, msgEllipseFiducialDetection->header.seq);
65 
66  // Convert camera matrix msg to cv::Mat
67  float camera_matrix_data[9];
68  for (int i = 0; i < 9; i++)
69  camera_matrix_data[i] = msgIdFiducialDetection->camera_k[i];
70  cv::Mat camera_k = cv::Mat(3, 3, CV_32F, camera_matrix_data);
71 
72  float distortion_coefficients_data[5];
73  for (int i = 0; i < 5; i++)
74  distortion_coefficients_data[i] = msgIdFiducialDetection->camera_d[i];
75  cv::Mat camera_d = cv::Mat(1, 5, CV_32F, distortion_coefficients_data);
76 
77  std::vector<MarkerFiducials> idFiducials;
78  for (auto &fiducial:msgIdFiducialDetection->fiducial) {
79  MarkerFiducials mFiducial(fiducial.ids, fiducial.ids_confidence);
80 
81  for (auto &object_point:fiducial.object_points)
82  mFiducial.object_points.push_back(cv::Point3f(object_point.x, object_point.y, object_point.z));
83 
84  for (auto &image_point:fiducial.image_points)
85  mFiducial.image_points.push_back(cv::Point2f(image_point.x, image_point.y));
86 
87  idFiducials.push_back(mFiducial);
88  }
89 
90  std::vector<MarkerFiducials> ellipseFiducials;
91  for (auto &fiducial:msgEllipseFiducialDetection->fiducial) {
92  MarkerFiducials mFiducial(fiducial.ids, fiducial.ids_confidence);
93 
94  for (auto &object_point:fiducial.object_points)
95  mFiducial.object_points.push_back(cv::Point3f(object_point.x, object_point.y, object_point.z));
96 
97  for (auto &image_point:fiducial.image_points)
98  mFiducial.image_points.push_back(cv::Point2f(image_point.x, image_point.y));
99 
100  ellipseFiducials.push_back(mFiducial);
101  }
102 
103 
104  // Do pose estimation
105  std::vector<MarkerPose> markerPoses;
106  ComboMarkerEstimator estimator;
107  estimator.estimatePose(idFiducials, camera_k, camera_d, ellipseFiducials, markerPoses);
108 
109  // Publish ros messages
110  publishMarkers(msgIdFiducialDetection->header, markerPoses);
111 
112  if(true){
113 
114  cv::Mat debugImage = cv::Mat(480, 640, CV_32FC3, cv::Scalar(255, 255, 255));
115 
116  for (auto &markerPose:markerPoses) {
117  cv::Mat objectPoints(4, 3, CV_32FC1);
118  float axis_size = 0.08f;
119  objectPoints.at< float >(0, 0) = 0;
120  objectPoints.at< float >(0, 1) = 0;
121  objectPoints.at< float >(0, 2) = 0;
122  objectPoints.at< float >(1, 0) = axis_size;
123  objectPoints.at< float >(1, 1) = 0;
124  objectPoints.at< float >(1, 2) = 0;
125  objectPoints.at< float >(2, 0) = 0;
126  objectPoints.at< float >(2, 1) = axis_size;
127  objectPoints.at< float >(2, 2) = 0;
128  objectPoints.at< float >(3, 0) = 0;
129  objectPoints.at< float >(3, 1) = 0;
130  objectPoints.at< float >(3, 2) = axis_size;
131 
132  std::vector<cv::Point2f> imagePoints;
133  cv::projectPoints(objectPoints, markerPose.getRVec(), markerPose.getTVec(), camera_k, camera_d, imagePoints);
134 
135  // draw lines of different colours
136  cv::line(debugImage, imagePoints[0], imagePoints[1], cv::Scalar(0, 0, 255, 255), 1, CV_AA);
137  cv::line(debugImage, imagePoints[0], imagePoints[2], cv::Scalar(0, 255, 0, 255), 1, CV_AA);
138  cv::line(debugImage, imagePoints[0], imagePoints[3], cv::Scalar(255, 0, 0, 255), 1, CV_AA);
139  }
140 
141 
142 
143 
144  //std::vector< cv::Point2f > imagePoints;
145  //cv::projectPoints(objectPoints, Rvec, Tvec, CP.CameraMatrix, CP.Distorsion, imagePoints);
146 
147  /*
148  cv::Mat debugImage;
149  cvtColor(imgPtr->image, debugImage, cv::COLOR_GRAY2BGR);
150 
151  for (unsigned int i = 0; i < markers.size(); i++) {
152  // draw 2d info
153  markers[i].draw(debugImage, cv::Scalar(0, 0, 255), 1);
154 
155  // draw a 3d cube
156  aruco::CvDrawingUtils::draw3dCube(debugImage, markers[i], camParams);
157  aruco::CvDrawingUtils::draw3dAxis(debugImage, markers[i], camParams);
158  }
159  */
160 
161  std::vector<MarkerPose> idMarkerPoses;
162  {
163  std::vector<MarkerFiducials> markers;
164  for (auto &fiducial:msgIdFiducialDetection->fiducial) {
165  MarkerFiducials marker(fiducial.ids, fiducial.ids_confidence);
166 
167  for (auto &object_point:fiducial.object_points)
168  marker.object_points.push_back(cv::Point3f(object_point.x, object_point.y, object_point.z));
169 
170  for (auto &image_point:fiducial.image_points)
171  marker.image_points.push_back(cv::Point2f(image_point.x, image_point.y));
172 
173  markers.push_back(marker);
174  }
175 
176  // Do pose estimation
177  PoseEstimationBase idPoseEstimation;
178  idPoseEstimation.estimatePose(markers, camera_k, camera_d, idMarkerPoses);
179  }
180  for (auto &markerPose:idMarkerPoses) {
181  ROS_INFO("marker[%d]", markerPose.ids[0]);
182 
183 
184  std::vector<cv::Point3f> objectPoints;
185  objectPoints.push_back(cv::Point3f(0.0f, 0.0f, 0.0f));
186  objectPoints.push_back(cv::Point3f(0.055f, 0.0f, 0.0f));
187  objectPoints.push_back(cv::Point3f(0.00f, 0.055f, 0.0f));
188  objectPoints.push_back(cv::Point3f(-0.055f, 0.0f, 0.0f));
189  objectPoints.push_back(cv::Point3f(0.00f, -0.055f, 0.0f));
190 
191  std::vector<cv::Point2f> imagePoints;
192  cv::projectPoints(objectPoints, markerPose.getRVec(), markerPose.getTVec(), camera_k, camera_d, imagePoints);
193  // draw lines of different colours
194  cv::line(debugImage, imagePoints[0], imagePoints[1], cv::Scalar(0, 0, 255, 255), 1, CV_AA);
195  cv::line(debugImage, imagePoints[0], imagePoints[2], cv::Scalar(0, 0, 255, 255), 1, CV_AA);
196  cv::line(debugImage, imagePoints[0], imagePoints[3], cv::Scalar(0, 0, 255, 255), 1, CV_AA);
197  cv::line(debugImage, imagePoints[0], imagePoints[4], cv::Scalar(0, 0, 255, 255), 1, CV_AA);
198  //putText(debugImage, "x", imagePoints[1], cv::FONT_HERSHEY_SIMPLEX, 0.6, cv::Scalar(0, 0, 255, 255), 2);
199  //putText(debugImage, "y", imagePoints[2], cv::FONT_HERSHEY_SIMPLEX, 0.6, cv::Scalar(0, 255, 0, 255), 2);
200  //putText(debugImage, "z", imagePoints[3], cv::FONT_HERSHEY_SIMPLEX, 0.6, cv::Scalar(255, 0, 0, 255), 2);
201 
202  int circleRadius = 5; // Pixel
203  cv::circle(debugImage, imagePoints[1], circleRadius, cv::Scalar(0, 0, 255, 255), 1, CV_AA);
204  cv::circle(debugImage, imagePoints[2], circleRadius, cv::Scalar(0, 0, 255, 255), 1, CV_AA);
205  cv::circle(debugImage, imagePoints[3], circleRadius, cv::Scalar(0, 0, 255, 255), 1, CV_AA);
206  cv::circle(debugImage, imagePoints[4], circleRadius, cv::Scalar(0, 0, 255, 255), 1, CV_AA);
207 
208 
209 
210  /*
211  cv::Mat objectPoints(1, 3, CV_32FC1);
212  objectPoints.at<float>(0, 0) = 0;
213  objectPoints.at<float>(0, 1) = 0;
214  objectPoints.at<float>(0, 2) = 0;
215 
216 
217  std::vector<cv::Point2f> imagePoints;
218  cv::projectPoints(objectPoints, markerPose.getRVec(), markerPose.getTVec(), camera_k, camera_d, imagePoints);
219 
220 
221  putText(debugImage, "x", imagePoints[0], cv::FONT_HERSHEY_SIMPLEX, 0.6, cv::Scalar(0, 0, 255, 255), 2);
222  */
223 
224 
225  /*
226  cv::projectPoints(objectPoints, Rvec, Tvec, CP.CameraMatrix, CP.Distorsion, imagePoints);
227  // draw lines of different colours
228  cv::line(Image, imagePoints[0], imagePoints[1], Scalar(0, 0, 255, 255), 1, CV_AA);
229  cv::line(Image, imagePoints[0], imagePoints[2], Scalar(0, 255, 0, 255), 1, CV_AA);
230  cv::line(Image, imagePoints[0], imagePoints[3], Scalar(255, 0, 0, 255), 1, CV_AA);
231  putText(Image, "x", imagePoints[1], FONT_HERSHEY_SIMPLEX, 0.6, Scalar(0, 0, 255, 255), 2);
232  markerPose.rt_matrix.
233  */
234 
235  }
236 
237  for (auto &fiducial:msgEllipseFiducialDetection->fiducial) {
238  cv::circle(debugImage, cv::Point2f(fiducial.image_points[0].x, fiducial.image_points[0].y), 5, cv::Scalar(0, 0, 0, 255), 1, CV_AA);
239  }
240 
241  cv::imshow("combomarker_node_debug", debugImage);
242  cv::waitKey(1);
243  }
244 }
245 
246 static tf::StampedTransform markerPoseToStampedTransform(MarkerPose &markerPose, const std_msgs::Header &header) {
247  cv::Mat m = markerPose.rt_matrix;
248 
249  tf::Vector3 tv(
250  m.at<float>(0, 3),
251  m.at<float>(1, 3),
252  m.at<float>(2, 3)
253  );
254 
255  tf::Matrix3x3 rm(
256  m.at<float>(0, 0), m.at<float>(0, 1), m.at<float>(0, 2),
257  m.at<float>(1, 0), m.at<float>(1, 1), m.at<float>(1, 2),
258  m.at<float>(2, 0), m.at<float>(2, 1), m.at<float>(2, 2)
259  );
260 
261  char markerLabel[64];
262  if (markerPose.ids.size() > 0) {
263  sprintf(markerLabel, "t%i", markerPose.ids[0]);
264  } else {
265  sprintf(markerLabel, "t?");
266  }
267  return tf::StampedTransform(tf::Transform(rm, tv), ros::Time::now(), header.frame_id, markerLabel);
268 }
269 
270 void PoseEstimationComboMarkerNode::publishMarkers(const std_msgs::Header &header, std::vector<MarkerPose> &markerPoses) {
271  marker_msgs::MarkerDetection msg;
272 
273  msg.header = header;
274  msg.distance_min = 0; //TODO
275  msg.distance_max = 8; //TODO
276  msg.distance_max_id = 5; //TODO
277  msg.view_direction.x = 0; //TODO
278  msg.view_direction.y = 0; //TODO
279  msg.view_direction.z = 0; //TODO
280  msg.view_direction.w = 1; //TODO
281  msg.fov_horizontal = 6; //TODO
282  msg.fov_vertical = 0; //TODO
283 
284  msg.markers = marker_msgs::MarkerDetection::_markers_type();
285 
286  for (auto &markerPose:markerPoses) {
287  tf::StampedTransform stf = markerPoseToStampedTransform(markerPose, header);
288 
289  // Send transform
290  //if (base_.getParameters().getPublishTf())
292 
293  // Push marker into MarkerDetection message
294  marker_msgs::Marker marker;
295 
296  marker.ids = markerPose.ids;
297  marker.ids_confidence = markerPose.ids_confidence;
298  tf::poseTFToMsg(stf, marker.pose);
299 
300  msg.markers.push_back(marker);
301  }
302 
303  // Publish MarkerDetection message
304  //if (base_.getParameters().getPublishMarkers())
305  pub_markers_.publish(msg);
306 }
void publish(const boost::shared_ptr< M > &message) const
void publishMarkers(const std_msgs::Header &header, std::vector< MarkerPose > &markerPoses)
f
void estimatePose(std::vector< MarkerFiducials > &idFiducials, cv::Mat &camera_k, cv::Mat &camera_d, std::vector< MarkerFiducials > &ellipseFiducials, std::vector< MarkerPose > &markerPoses)
cv::Mat rt_matrix
Definition: marker_pose.h:44
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
message_filters::TimeSynchronizer< marker_msgs::FiducialDetection, marker_msgs::FiducialDetection > sync_
std::vector< int > ids
Definition: marker_pose.h:41
void synchronizedFiducialsCallback(const marker_msgs::FiducialDetection::ConstPtr &msgIdFiducialDetection, const marker_msgs::FiducialDetection::ConstPtr &msgEllipseFiducialDetection)
ROSCPP_DECL void spin(Spinner &spinner)
Connection registerCallback(C &callback)
#define ROS_INFO(...)
static tf::StampedTransform markerPoseToStampedTransform(MarkerPose &markerPose, const std_msgs::Header &header)
void sendTransform(const StampedTransform &transform)
int main(int argc, char **argv)
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
void estimatePose(std::vector< MarkerFiducials > &markers, cv::Mat &camera_k, cv::Mat &camera_d, std::vector< MarkerPose > &markerPoses)
std::vector< cv::Point3f > object_points
static void poseTFToMsg(const Pose &bt, geometry_msgs::Pose &msg)
static Time now()
std::vector< cv::Point2f > image_points


tuw_marker_pose_estimation
Author(s): Lukas Pfeifhofer
autogenerated on Mon Jun 10 2019 15:42:13