Open DavidLeeDoosan opened 4 years ago
You need to calibrate your camera, calculate the pose of the marker, project the axis points to the image using these and draw lines between the projected points. I'm copy pasting an example below.
Note that the axis may end up looking wrong due to this
https://stackoverflow.com/questions/32447357/solvepnp-pose-estimation-for-planar-object-ambiguous-case
I went through all the existing solutions and none of them produce satisfactory results. So if your axis looks wrong, your best bet would be to use useExtrinsicGuess
and randomize the rvec
/tvec
starting point until you end up with a good looking result (or just use a different image).
cv::Mat image = cv::imread("0.png", CV_LOAD_IMAGE_GRAYSCALE);
edm.detectMarkers(image, false);
//edm.dumpLog(outPath, "teaser");
Mat colorImage;
cv::cvtColor(image, colorImage, CV_GRAY2BGR);
Marker marker = edm.getMarkers()[0];
vector<cv::Point3f> objectPoints;
objectPoints.push_back(cv::Point3f(0, 0, 0));
objectPoints.push_back(cv::Point3f(1, 0, 0));
objectPoints.push_back(cv::Point3f(1, 1, 0));
objectPoints.push_back(cv::Point3f(0, 1, 0));
Mat cameraMatrix = (cv::Mat)(cv::Matx33d(1408.654794182396, 0, 981.1555853221231, 0, 1404.977436090862, 561.9808485811495, 0, 0, 1));
vector<double> distCoeff = { 0.126706318892812, -0.206388301229407, 0, 0 };
Mat rvec, tvec;
cv::solvePnP(objectPoints, marker.corners, cameraMatrix, distCoeff, rvec, tvec);
objectPoints.clear();
float axisLength = 0.5;
objectPoints.push_back(cv::Point3f(0, 0, 0));
objectPoints.push_back(cv::Point3f(axisLength, 0, 0));
objectPoints.push_back(cv::Point3f(0, axisLength, 0));
objectPoints.push_back(cv::Point3f(0, 0, -axisLength));
vector<cv::Point2f> imagePoints;
cv::projectPoints(objectPoints, rvec, tvec, cameraMatrix, distCoeff, imagePoints);
cv::line(colorImage, cv::Point(imagePoints[0].x, imagePoints[0].y), cv::Point(imagePoints[1].x, imagePoints[1].y), cv::Scalar(255, 255, 255), 5, CV_AA);
cv::line(colorImage, cv::Point(imagePoints[0].x, imagePoints[0].y), cv::Point(imagePoints[2].x, imagePoints[2].y), cv::Scalar(255, 255, 255), 5, CV_AA);
cv::line(colorImage, cv::Point(imagePoints[0].x, imagePoints[0].y), cv::Point(imagePoints[3].x, imagePoints[3].y), cv::Scalar(255, 255, 25), 5, CV_AA);
cv::line(colorImage, cv::Point(imagePoints[0].x, imagePoints[0].y), cv::Point(imagePoints[1].x, imagePoints[1].y), cv::Scalar(0, 0, 255), 2, CV_AA);
cv::line(colorImage, cv::Point(imagePoints[0].x, imagePoints[0].y), cv::Point(imagePoints[2].x, imagePoints[2].y), cv::Scalar(0, 255, 0), 2, CV_AA);
cv::line(colorImage, cv::Point(imagePoints[0].x, imagePoints[0].y), cv::Point(imagePoints[3].x, imagePoints[3].y), cv::Scalar(255, 0, 0), 2, CV_AA);
vector<int> compressionParams = { CV_IMWRITE_PNG_COMPRESSION, 0 };
cv::imwrite("teaser.png", colorImage, compressionParams);
How to Draw a Axes on the image from Stag?
After running your program, I had some result such as 1 edges.png ~ 8 ellipses.png, but there is no Homography Refinement image. You mentioned (j) Homography Refinement in Figure 7 on the paper. How can I make Homography Refinement Image such as Drawing a Axes.