17 #include <opencv2/opencv.hpp> 18 #include <opencv2/core/core.hpp> 19 #include <opencv2/calib3d/calib3d.hpp> 20 #include <opencv2/imgproc/imgproc.hpp> 28 return r / M_PI * 180.0;
32 double dist(cv::Mat pts,
int i1,
int i2)
34 double x1 = pts.at<
double>(0, i1);
35 double y1 = pts.at<
double>(1, i1);
36 double x2 = pts.at<
double>(0, i2);
37 double y2 = pts.at<
double>(1, i2);
42 return sqrt(dx*dx + dy*dy);
49 double a1 =
dist(pts, 0, 1);
50 double b1 =
dist(pts, 0, 3);
51 double c1 =
dist(pts, 1, 3);
53 double a2 =
dist(pts, 1, 2);
54 double b2 =
dist(pts, 2, 3);
57 double s1 = (a1 + b1 + c1) / 2.0;
58 double s2 = (a2 + b2 + c2) / 2.0;
60 a1 = sqrt(s1*(s1-a1)*(s1-b1)*(s1-c1));
61 a2 = sqrt(s2*(s2-a2)*(s2-b2)*(s2-c2));
69 printf(
"fx %lf fy %lf cx %lf cy %lf", K.at<
double>(0, 0), K.at<
double>(1, 1), K.at<
double>(0, 2), K.at<
double>(1, 2));
70 for (
int i=0; i<pts.cols; i++) {
71 pts.at<
double>(0, i) = (pts.at<
double>(0, i) - K.at<
double>(0, 2)) / K.at<
double>(0, 0);
72 pts.at<
double>(1, i) = (pts.at<
double>(1, i) - K.at<
double>(1, 2)) / K.at<
double>(1, 1);
76 cv::Mat src(1, pts.cols, CV_64FC2);
77 cv::Mat dst(1, pts.cols, CV_64FC2);
79 for (
int i=0; i<pts.cols; i++) {
80 src.at<cv::Vec2d>(0, i)[0] = pts.at<
double>(0, i);
81 src.at<cv::Vec2d>(0, i)[1] = pts.at<
double>(1, i);
83 std::vector<cv::Point2f> dest;
86 for (
int i=0; i<pts.cols; i++) {
87 pts.at<
double>(0, i) = dst.at<cv::Vec2d>(0, i)[0];
88 pts.at<
double>(1, i) = dst.at<cv::Vec2d>(0, i)[1];
95 fiducial_msgs::FiducialTransform* ft)
97 ROS_INFO(
"id %d direction %d", msg->fiducial_id, msg->direction);
110 printf(
"fid %d dir %d vertices %lf %lf %lf %lf %lf %lf %lf %lf\n",
111 msg->fiducial_id, msg->direction,
112 msg->x0, msg->y0, msg->x1, msg->y1,
113 msg->x2, msg->y2, msg->x3, msg->y3);
115 switch(msg->direction) {
118 ipts.at<
double>(0,0) = msg->x0;
119 ipts.at<
double>(1,0) = msg->y0;
120 ipts.at<
double>(0,1) = msg->x1;
121 ipts.at<
double>(1,1) = msg->y1;
122 ipts.at<
double>(0,2) = msg->x2;
123 ipts.at<
double>(1,2) = msg->y2;
124 ipts.at<
double>(0,3) = msg->x3;
125 ipts.at<
double>(1,3) = msg->y3;
130 ipts.at<
double>(0,0) = msg->x3;
131 ipts.at<
double>(1,0) = msg->y3;
132 ipts.at<
double>(0,1) = msg->x0;
133 ipts.at<
double>(1,1) = msg->y0;
134 ipts.at<
double>(0,2) = msg->x1;
135 ipts.at<
double>(1,2) = msg->y1;
136 ipts.at<
double>(0,3) = msg->x2;
137 ipts.at<
double>(1,3) = msg->y2;
142 ipts.at<
double>(0,0) = msg->x2;
143 ipts.at<
double>(1,0) = msg->y2;
144 ipts.at<
double>(0,1) = msg->x3;
145 ipts.at<
double>(1,1) = msg->y3;
146 ipts.at<
double>(0,2) = msg->x0;
147 ipts.at<
double>(1,2) = msg->y0;
148 ipts.at<
double>(0,3) = msg->x1;
149 ipts.at<
double>(1,3) = msg->y1;
154 ipts.at<
double>(0,0) = msg->x1;
155 ipts.at<
double>(1,0) = msg->y1;
156 ipts.at<
double>(0,1) = msg->x2;
157 ipts.at<
double>(1,1) = msg->y2;
158 ipts.at<
double>(0,2) = msg->x3;
159 ipts.at<
double>(1,2) = msg->y3;
160 ipts.at<
double>(0,3) = msg->x0;
161 ipts.at<
double>(1,3) = msg->y0;
169 std::vector<cv::Point2f> imagePoints;
170 std::vector<cv::Point3f> model2;
171 for (
int i=0; i<4; i++) {
172 imagePoints.push_back(cv::Point2f(
ipts.at<
double>(0, i),
ipts.at<
double>(1, i)));
173 model2.push_back(cv::Point3f(
model.at<
double>(0, i),
model.at<
double>(1, i),
model.at<
double>(2, i)));
177 cv::Mat rvec(3,1,cv::DataType<double>::type);
178 cv::Mat tvec(3,1,cv::DataType<double>::type);
180 cv::solvePnP(model2, imagePoints,
K,
dist, rvec, tvec,
false, CV_EPNP);
182 ROS_INFO(
"tvec %lf %lf %lf", tvec.at<
double>(0, 0), tvec.at<
double>(1, 0), tvec.at<
double>(2, 0));
183 ROS_INFO(
"rvec %lf %lf %lf",
r2d(rvec.at<
double>(0, 0)),
r2d(rvec.at<
double>(1, 0)),
r2d(rvec.at<
double>(2, 0)));
185 tf::Vector3 translation(tvec.at<
double>(0, 0), tvec.at<
double>(1, 0), tvec.at<
double>(2, 0));
187 rotation.
setRPY(rvec.at<
double>(0, 0), rvec.at<
double>(1, 0), rvec.at<
double>(2, 0));
190 ft->transform.translation.x = translation.
x();
191 ft->transform.translation.y = translation.
y();
192 ft->transform.translation.z = translation.
z();
194 ft->transform.rotation.w = rotation.w();
195 ft->transform.rotation.x = rotation.x();
196 ft->transform.rotation.y = rotation.y();
197 ft->transform.rotation.z = rotation.z();
198 ft->fiducial_id = msg->fiducial_id;
209 std::vector<RPP::Solution> sol;
211 std::map<int, cv::Mat>::iterator it;
213 it =
prevRots.find(msg->fiducial_id);
215 rotation = cv::Mat();
217 rotation = it->second;
219 if(!
RPP::Rpp(
model,
ipts, rotation, translation, iterations, obj_err, img_err, sol)) {
220 ROS_ERROR(
"Cannot find transform for fiducial %d", msg->fiducial_id);
224 prevRots[msg->fiducial_id] = rotation;
251 tf::Matrix3x3 m1(rotation.at<
double>(0,0), rotation.at<
double>(0,1), rotation.at<
double>(0,2),
252 rotation.at<
double>(1,0), rotation.at<
double>(1,1), rotation.at<
double>(1,2),
253 rotation.at<
double>(2,0), rotation.at<
double>(2,1), rotation.at<
double>(2,2));
254 tf::Vector3 t1(translation.at<
double>(0), translation.at<
double>(1), translation.at<
double>(2));
264 ROS_INFO(
"fid %d T: %.3lf %.3lf %.3lf R: %.2f %.2f %.2f",
266 t1.
x(), t1.
y(), t1.
z(),
276 ft->transform.translation.x = t1.
x();
277 ft->transform.translation.y = t1.
y();
278 ft->transform.translation.z = t1.
z();
280 ft->transform.rotation.w = q.w();
281 ft->transform.rotation.x = q.x();
282 ft->transform.rotation.y = q.y();
283 ft->transform.rotation.z = q.z();
285 ft->fiducial_id = msg->fiducial_id;
287 ft->image_error = img_err;
288 ft->object_error = obj_err;
301 for (
int i=0; i<3; i++) {
302 for (
int j=0; j<3; j++) {
303 K.at<
double>(i, j) = msg->K[i*3+j];
307 printf(
"camera intrinsics:\n");
310 for (
int i=0; i<5; i++) {
311 dist.at<
double>(0,i) = msg->D[i];
314 printf(
"distortion coefficients:\n");
327 K = cv::Mat::zeros(3, 3, CV_64F);
330 dist = cv::Mat::zeros(1, 5, CV_64F);
333 ipts = cv::Mat::ones(3, 4, CV_64F);
336 model = cv::Mat::zeros(3, 4, CV_64F);
355 model.at<
double>(0,0) = fiducialLen / 2.0;
356 model.at<
double>(1,0) = -fiducialLen / 2.0;
358 model.at<
double>(0,1) = -fiducialLen / 2.0;
359 model.at<
double>(1,1) = -fiducialLen / 2.0;
361 model.at<
double>(0,2) = -fiducialLen / 2.0;
362 model.at<
double>(1,2) = fiducialLen / 2.0;
364 model.at<
double>(0,3) = fiducialLen / 2.0;
365 model.at<
double>(1,3) = fiducialLen / 2.0;
std::map< int, cv::Mat > prevRots
void undistortPoints(cv::Mat pts, cv::Mat K, cv::Mat dist, bool doUndistort)
bool Rpp(const cv::Mat &model_3D, const cv::Mat &iprts, cv::Mat &Rlu, cv::Mat &tlu, int &it1, double &obj_err1, double &img_err1, std::vector< Solution > &sol)
RosRpp(double fiducialLen, bool doUndistort)
bool fiducialCallback(fiducial_msgs::Fiducial *fiducial, fiducial_msgs::FiducialTransform *transform)
TFSIMD_FORCE_INLINE const tfScalar & y() const
void Print(const cv::Mat &m)
double dist(cv::Mat pts, int i1, int i2)
TFSIMD_FORCE_INLINE const tfScalar & x() const
TFSIMD_FORCE_INLINE const tfScalar & z() const
void setRPY(const tfScalar &roll, const tfScalar &pitch, const tfScalar &yaw)
void getRPY(tfScalar &roll, tfScalar &pitch, tfScalar &yaw, unsigned int solution_number=1) const
TFSIMD_FORCE_INLINE const tfScalar & y() const
std::map< int, tf::Transform > frameTransforms
void camInfoCallback(const sensor_msgs::CameraInfo::ConstPtr &msg)
double calcFiducialArea(cv::Mat pts)