Hi,
Thanks for everything!
I use the following version of OpenCV : OpenCV 4.5.5
I tried to draw the axes manually and the result is the same in Gazebo simulation and even in real world with a webcam.
Here is the code:
float mtx[3][3] = {
{229.41206666, 0.00000000e+00, 292.21276158/2 } ,
{0.00000000e+00, 229.41206666, 163.36008624} ,
{0.00000000e+00, 0.00000000e+00, 1.00000000e+00}
};
float dist[14][1] = {
{0.15749949} ,
{0.71279781} ,
{ -0.00673416} ,
{-0.04085565} ,
{3.81203065} ,
{0.12853096} ,
{0.76355458} ,
{ 3.70903916} ,
{0.} ,
{0.} ,
{0.} ,
{0.}
};
cv::Mat camMatrix = cv::Mat(3, 3, CV_32F, mtx);
cv::Mat distCoeffs = cv::Mat(14, 1, CV_32F, dist);
cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
while(video_stream.grab())
{
cv::Mat image, imageCopy;
video_stream.retrieve(image);
image.copyTo(imageCopy);
std::vector<std::vector<cv::Point2f>> mycorners,rejected;
std::vector<cv::Vec3d>rvecs, tvecs;
std::vector<int> myids;
cv::aruco::detectMarkers(image, dictionary, mycorners, myids, detectorParams, rejected);
if (myids.size() > 0)
{
cv::aruco::estimatePoseSingleMarkers(mycorners, MARKER_LENGTH, camMatrix, distCoeffs, rvecs, tvecs);
cv::aruco::drawDetectedMarkers(imageCopy, mycorners, myids);
vector< cv::Point3f > axisPoints;
axisPoints.push_back(cv::Point3f(0, 0, 0));
axisPoints.push_back(cv::Point3f(MARKER_LENGTH, 0, 0));
axisPoints.push_back(cv::Point3f(0, MARKER_LENGTH, 0));
axisPoints.push_back(cv::Point3f(0, 0, MARKER_LENGTH));
vector< cv::Point2f > imagePoints;
cv::projectPoints(axisPoints, rvecs, tvecs, camMatrix, distCoeffs, imagePoints);
cv::line(imageCopy, imagePoints[0], imagePoints[1], cv::Scalar(0, 0, 255), 3);
cv::line(imageCopy, imagePoints[0], imagePoints[2], cv::Scalar(0, 255, 0), 3);
cv::line(imageCopy, imagePoints[0], imagePoints[3], cv::Scalar(255, 0, 0), 3);
}
imshow("receiver", imageCopy);
char key = (char) cv::waitKey(10);
if (key == 27)
break;
}