I'm developing a simple marker based augmented reality application with **OpenCV Viz and ARUCO**. I just want to visualize a 3D object (in PLY format) on a marker.
I can run marker detection and pose estimation (returning rotation and translation vectors) with ARUCO without a problem. And I can visualize any 3D object (PLY format) and camera frames in Viz window. However, I stuck in using rotation and translation vector outputs from ARUCO to localize 3D model on the marker.
I'm creating an affine transformation with rotation and translation vectors and applying it to 3D model. Is it correct? **How should I make use of translation and rotation vectors?**
Below is my code snippet.
// Camera calibration outputs
cv::Mat cameraMatrix, distCoeffs;
loadIntrinsicCameraParameters(cameraMatrix, distCoeffs);
// Marker dictionary
Ptr dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
viz::Viz3d myWindow("Coordinate Frame");
cv::Mat image;
// Webcam frame pose, without this frame is upside-down
Affine3f imagePose(Vec3f(3.14159,0,0), Vec3f(0,0,0));
// Viz viewer pose to see whole webcam frame
Vec3f cam_pos( 0.0f,0.0f,900.0f), cam_focal_point(0.0f,0.0f,0.0f), cam_y_dir(0.0f,0.0f,0.0f);
Affine3f viewerPose = viz::makeCameraPose(cam_pos, cam_focal_point, cam_y_dir);
// Video capture from source
VideoCapture cap(camID);
int frame_width = cap.get(CV_CAP_PROP_FRAME_WIDTH);
int frame_height = cap.get(CV_CAP_PROP_FRAME_HEIGHT);
cap >> image;
// Load mash data
viz::WMesh batman(viz::Mesh::load("../data/bat.ply"));
viz::WImage3D img(image, Size2d(frame_width, frame_height));
// Show camera frame, mesh and a coordinate widget (for debugging)
myWindow.showWidget("Image", img);
myWindow.showWidget("Batman", batman);
myWindow.showWidget("Coordinate Widget", viz::WCoordinateSystem(5.0));
myWindow.setFullScreen(true);
myWindow.setViewerPose(viewerPose);
// Rotation vector of 3D model
Mat rot_vec = Mat::zeros(1,3,CV_32F);
cv::Vec3d rvec, tvec;
// ARUCO outputs
float roll, pitch, yaw;
float x, y, z;
while (!myWindow.wasStopped()) {
if (cap.read(image)) {
cv::Mat image, imageCopy;
cap.retrieve(image);
image.copyTo(imageCopy);
// Marker detection
std::vector ids;
std::vector> corners;
cv::aruco::detectMarkers(image, dictionary, corners, ids);
if (ids.size() > 0){
// Draw a green line around markers
cv::aruco::drawDetectedMarkers(imageCopy, corners, ids);
vector rvecs, tvecs;
// Get rotation and translation vectors of each markers
cv::aruco::estimatePoseSingleMarkers(corners, 0.05, cameraMatrix, distCoeffs, rvecs, tvecs);
for(int i=0; i(0,0) = roll;
rot_vec.at(0,1) = pitch;
rot_vec.at(0,2) = yaw;
Mat rot_mat;
Rodrigues(rot_vec, rot_mat);
Affine3f pose(rot_mat, Vec3f(x, y, z));
// Set the pose of 3D model
batman.setPose(pose);
myWindow.spinOnce(1, true);
}
↧