#include <opencv2/opencv.hpp>
#include <iostream>
#include <vector>
struct Point2D {
float x;
float y;
};
cv::Mat calculateAffineTransform(const std::vector<Point2D>& imagePoints,
const std::vector<Point2D>& robotPoints,
int points_num) {
cv::Mat src(points_num, 2, CV_64F);
cv::Mat dst(points_num, 2, CV_64F);
for (int i = 0; i < points_num; ++i) {
src.at<double>(i, 0) = imagePoints[i].x;
src.at<double>(i, 1) = imagePoints[i].y;
dst.at<double>(i, 0) = robotPoints[i].x;
dst.at<double>(i, 1) = robotPoints[i].y;
}
return cv::estimateAffine2D(src, dst);
}
Point2D transformPoint(const cv::Mat& transformMatrix, const Point2D& imagePoint) {
cv::Mat src(3, 1, CV_64F);
src.at<double>(0, 0) = imagePoint.x;
src.at<double>(1, 0) = imagePoint.y;
src.at<double>(2, 0) = 1.0;
cv::Mat dst = transformMatrix * src;
Point2D robotPoint;
robotPoint.x = dst.at<double>(0, 0);
robotPoint.y = dst.at<double>(1, 0);
return robotPoint;
}
int main() {
int w = 3; int h = 5;
cv::TermCriteria criteria(cv::TermCriteria::EPS + cv::TermCriteria::MAX_ITER, 30, 0.001);
std::vector<Point2D> imagePoints;
cv::Mat image = cv::imread("calibration_board.jpg");
if (image.empty()) {
std::cerr << "Could not open or find the image" << std::endl;
return -1;
}
cv::Mat gray;
cv::cvtColor(image, gray, cv::COLOR_BGR2GRAY);
cv::SimpleBlobDetector::Params params;
params.maxArea = std::numeric_limits<float>::max();
params.minArea = 2;
params.minDistBetweenBlobs = 1;
cv::Ptr<cv::SimpleBlobDetector> blobDetector = cv::SimpleBlobDetector::create(params);
std::vector<cv::Point2f> corners;
bool found = cv::findCirclesGrid(gray, cv::Size(w, h), corners, cv::CALIB_CB_SYMMETRIC_GRID, blobDetector);
if (found) {
imagePoints.resize(corners.size());
for (size_t i = 0; i < corners.size(); ++i) {
imagePoints[i].x = corners[i].x;
imagePoints[i].y = corners[i].y;
}
cv::cornerSubPix(gray, corners, cv::Size(5, 5), cv::Size(-1, -1), criteria);
} else {
std::cerr << "Could not find the circle grid" << std::endl;
return -1;
}
std::vector<Point2D> robotPoints = {
{5, 5}, {10, 5}, {15, 5}, {5, 10}, {10, 10}, {15, 10},
{5, 15}, {10, 15}, {15, 15}, {5, 20}, {10, 20}, {15, 20},
{5, 25}, {10, 25}, {15, 25}
};
cv::Mat affineMatrix = calculateAffineTransform(imagePoints, robotPoints, w * h);
std::cout << "Affine Transformation Matrix:" << std::endl << affineMatrix << std::endl;
Point2D testImagePoint = {590.203f, 885.33f};
Point2D testRobotPoint = transformPoint(affineMatrix, testImagePoint);
std::cout << "Image Point: (" << testImagePoint.x << ", " << testImagePoint.y << ") -> Robot Point: ("
<< testRobotPoint.x << ", " << testRobotPoint.y << ")" << std::endl;
return 0;
}
#include <opencv2/opencv.hpp>
#include <opencv2/calib3d.hpp>
#include <vector>
#include <cmath>
#include <iostream>
void convertXYZWPRToMat(double X, double Y, double Z, double W, double P, double R,
cv::Mat& R_base2grip, cv::Mat& t_base2grip) {
t_base2grip = (cv::Mat_<double>(3, 1) << X, Y, Z);
W *= CV_PI / 180.0; P *= CV_PI / 180.0; R *= CV_PI / 180.0;
cv::Mat Rz = (cv::Mat_<double>(3, 3) << cos(W), -sin(W), 0, sin(W), cos(W), 0, 0, 0, 1);
cv::Mat Ry = (cv::Mat_<double>(3, 3) << cos(P), 0, sin(P), 0, 1, 0, -sin(P), 0, cos(P));
cv::Mat Rx = (cv::Mat_<double>(3, 3) << 1, 0, 0, 0, cos(R), -sin(R), 0, sin(R), cos(R));
R_base2grip = Rz * Ry * Rx;
}
int main() {
const float square_size = 0.025f;
const cv::Size board_size(9, 6);
std::vector<cv::Point3f> object_points;
for (int i = 0; i < board_size.height; ++i) {
for (int j = 0; j < board_size.width; ++j) {
object_points.emplace_back(j * square_size, i * square_size, 0);
}
}
cv::Mat camera_matrix, dist_coeffs;
camera_matrix = (cv::Mat_<double>(3, 3) << 542.35, 0, 328.32, 0, 541.61, 246.95, 0, 0, 1);
dist_coeffs = (cv::Mat_<double>(5, 1) << -0.28, 0.10, -0.0005, 0.0013, -0.0237);
std::vector<std::vector<double>> xyzwpr_data = {
{100.0, 200.0, 300.0, 45.0, 30.0, 15.0},
{150.0, 250.0, 350.0, 60.0, 45.0, 30.0},
{200.0, 300.0, 400.0, 75.0, 60.0, 45.0},
{250.0, 350.0, 450.0, 90.0, 75.0, 60.0},
{300.0, 400.0, 500.0, 105.0, 90.0, 75.0},
{350.0, 450.0, 550.0, 120.0, 105.0, 90.0},
{400.0, 500.0, 600.0, 135.0, 120.0, 105.0},
{450.0, 550.0, 650.0, 150.0, 135.0, 120.0},
{500.0, 600.0, 700.0, 165.0, 150.0, 135.0}
};
std::vector<cv::Mat> R_base2gripper, t_base2gripper;
std::vector<cv::Mat> R_target2cam, t_target2cam;
for (int i = 0; i < 9; ++i) {
cv::Mat R_base2grip = cv::Mat::eye(3, 3, CV_64F);
cv::Mat t_base2grip = (cv::Mat_<double>(3, 1) << 0.1 * i, 0, 0);
convertXYZWPRToMat(xyzwpr_data[i][0], xyzwpr_data[i][1], xyzwpr_data[i][2],
xyzwpr_data[i][3], xyzwpr_data[i][4], xyzwpr_data[i][5],
R_base2grip, t_base2grip);
R_base2gripper.push_back(R_base2grip.clone());
t_base2gripper.push_back(t_base2grip.clone());
cv::Mat rvec, tvec;
cv::solvePnP(object_points, std::vector<cv::Point2f>(), camera_matrix, dist_coeffs, rvec, tvec);
cv::Mat R_target2cam_i;
cv::Rodrigues(rvec, R_target2cam_i);
R_target2cam.push_back(R_target2cam_i);
t_target2cam.push_back(tvec);
}
cv::Mat X_rot, X_trans;
cv::calibrateHandEye(R_base2gripper, t_base2gripper, R_target2cam, t_target2cam,
X_rot, X_trans, cv::CALIB_HAND_EYE_TSAI);
cv::Mat X = cv::Mat::eye(4, 4, CV_64F);
X_rot.copyTo(X(cv::Rect(0, 0, 3, 3)));
X_trans.copyTo(X(cv::Rect(3, 0, 1, 3)));
std::cout << "Camera to Base Transform Matrix X =\n" << X << std::endl;
return 0;
}