AprilRobotics / apriltag

AprilTag is a visual fiducial system popular for robotics research.
https://april.eecs.umich.edu/software/apriltag
Other
1.62k stars 541 forks source link

Python Wrapper for estimate_tag_pose #101

Open ShrutheeshIR opened 4 years ago

ShrutheeshIR commented 4 years ago

Thanks for the wonderful repo!

Is there a similar python wrapper for estimate_tag_pose as well? How would I go about writing one?

If not, can I write a similar function in Python directly? The doc does say we can use OpenCV's SOLVEPNP_IPPE_SQUARE However, I wish to know if that is different from the estimate_tag_pose implementation. If so, how different is it? How much drop in accuracy can I expect?

Thanks

iuliuv commented 4 years ago

this repository may already have what you need: https://github.com/duckietown/lib-dt-apriltags

mkrogius commented 4 years ago

I don't believe that we have a wrapper for estimate_tag_pose yet. If you want to write it, take a look at apriltag_pywrap.c for the current wrapper. If you write a wrapper for it, please send me a pull request and I'll incorporate it into this repo.

OpenCV's SOLVEPNP_IPPE_SQUARE is most likely more accurate, but I have not actually tested it. I'm not sure which method would be faster either.

ShrutheeshIR commented 4 years ago

Hey @mkrogius Could you provide a small code snippet of how to use SOLVEPNP_IPPE_SQUARE, since the april tag detection function returns the 4 corner locations of the square in the image. OpenCV's PNP function however requires 3D points.

Thanks

ShrutheeshIR commented 4 years ago

@iuliuv thanks for sharing that. It works nicely!

mkrogius commented 4 years ago

@ShrutheeshIR You're going to have to figure out exactly how to use it on your own. I can say at least that the points that apriltag returns would correspond to their imagePoints argument which is a list of 2d points, like our detector gives you. The objectPoints, which are in 3d, would correspond to the nominal positions of the corners of the tag, so something like {{tag_size/2, tag_size/2, 0},{tag_size/2,-tag_size/2,0}, {-tag_size/2, -tag_size/2, 0}, {-tag_size/2, tag_size/2, 0}} should work. Basically you want a list of the 3d points that the detected 2d points should correspond to.

cosama commented 3 years ago

It's a little outdated, but here how to estimate the pose with cv2 in python from apriltag, maybe it helps someone else with a similar problem.

import cv2
import apriltag
import numpy as np

camera_info_D = np.array([0., 0., 0., 0., 0.])

camera_info_K = np.array([fx, 0.000000, cx, 0.000000, fy, cy, 0.000000, 0.000000, 1.000000]).reshape(3, 3)

image_bw = cv2.imread("myimage.jpg", cv2.IMREAD_GRAYSCALE)
detector = apriltag("tag36h11")

detections = detector.detect(image_bw)
ids = np.array([i['id'] for i in detections], dtype=np.int32)[:, None]
corners = [i['lb-rb-rt-lt'][None, ::-1].astype(np.float32) for i in detections]

rvecs, tvecs, markerPoints = cv2.aruco.estimatePoseSingleMarkers(
            corners, tag_width_in_meter, camera_info_K, camera_info_D
        )

If you need any pointers please read the documentation of the respective functions, particular cv2.aruco.estimatePoseSingleMarkers.

What I am quite interested would be to understand if this method is better/worse than the one implemented in apriltags?