00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <turtlebot_kinect_arm_calibration/detect_calibration_pattern.h>
00031
00032 void PatternDetector::setCameraMatrices(cv::Mat K_, cv::Mat D_)
00033 {
00034 K = K_;
00035 D = D_;
00036 }
00037
00038 void PatternDetector::setPattern(cv::Size grid_size_, float square_size_,
00039 Pattern pattern_type_, cv::Point3f offset_)
00040 {
00041 ideal_points = calcChessboardCorners(grid_size_, square_size_, pattern_type_, offset_);
00042 pattern_type = pattern_type_;
00043 grid_size = grid_size_;
00044 square_size = square_size_;
00045 }
00046
00047 object_pts_t PatternDetector::calcChessboardCorners(cv::Size boardSize,
00048 float squareSize,
00049 Pattern patternType,
00050 cv::Point3f offset)
00051 {
00052 object_pts_t corners;
00053 switch (patternType)
00054 {
00055 case CHESSBOARD:
00056 case CIRCLES_GRID:
00057 for (int i = 0; i < boardSize.height; i++)
00058 for (int j = 0; j < boardSize.width; j++)
00059 corners.push_back(
00060 cv::Point3f(float(j * squareSize),
00061 float(i * squareSize), 0) + offset);
00062 break;
00063 case ASYMMETRIC_CIRCLES_GRID:
00064 for (int i = 0; i < boardSize.height; i++)
00065 for (int j = 0; j < boardSize.width; j++)
00066 corners.push_back(
00067 cv::Point3f(float(i * squareSize),
00068 float((2 * j + i % 2) * squareSize), 0) + offset);
00069 break;
00070 default:
00071 std::logic_error("Unknown pattern type.");
00072 }
00073 return corners;
00074 }
00075
00076
00077
00078 int PatternDetector::detectPattern(cv::Mat& image_in, Eigen::Vector3f& translation, Eigen::Quaternionf& orientation, cv::Mat& image_out)
00079 {
00080 translation.setZero();
00081 orientation.setIdentity();
00082
00083 bool found = false;
00084
00085 observation_pts_t observation_points;
00086
00087 switch (pattern_type)
00088 {
00089 case ASYMMETRIC_CIRCLES_GRID:
00090 found = cv::findCirclesGrid(image_in, grid_size, observation_points,
00091 cv::CALIB_CB_ASYMMETRIC_GRID | cv::CALIB_CB_CLUSTERING);
00092 break;
00093 case CHESSBOARD:
00094 found = cv::findChessboardCorners(image_in, grid_size, observation_points, cv::CALIB_CB_ADAPTIVE_THRESH);
00095 break;
00096 case CIRCLES_GRID:
00097 found = cv::findCirclesGrid(image_in, grid_size, observation_points, cv::CALIB_CB_SYMMETRIC_GRID);
00098 break;
00099 }
00100
00101 if(found)
00102 {
00103
00104 if (pattern_type == CHESSBOARD)
00105 {
00106 cv::cornerSubPix(image_in, observation_points, cv::Size(5,5), cv::Size(-1,-1),
00107 cv::TermCriteria(cv::TermCriteria::MAX_ITER + cv::TermCriteria::EPS, 100, 0.01));
00108 }
00109
00110 cv::solvePnP(cv::Mat(ideal_points), cv::Mat(observation_points), K, D,
00111 rvec, tvec, false);
00112 cv::Rodrigues(rvec, R);
00113
00114 cv::drawChessboardCorners(image_out, grid_size, cv::Mat(observation_points), found);
00115
00116 convertCVtoEigen(tvec, R, translation, orientation);
00117 }
00118
00119 return found;
00120 }
00121
00122 void convertCVtoEigen(cv::Mat& tvec, cv::Mat& R, Eigen::Vector3f& translation, Eigen::Quaternionf& orientation)
00123 {
00124
00125
00126 translation = Eigen::Vector3f(tvec.at<double>(0,0), tvec.at<double>(0,1), tvec.at<double>(0, 2));
00127
00128 Eigen::Matrix3f Rmat;
00129 Rmat << R.at<double>(0,0), R.at<double>(0,1), R.at<double>(0,2),
00130 R.at<double>(1,0), R.at<double>(1,1), R.at<double>(1,2),
00131 R.at<double>(2,0), R.at<double>(2,1), R.at<double>(2,2);
00132
00133 orientation = Eigen::Quaternionf(Rmat);
00134
00135 }
00136