# Accuracy of cv2.aruco.estimatePoseSingleMarkers

Hello everyone,

I have been trying to estimate the accuracy of cv2.aruco.estimatePoseSingleMarker in Python. To do so, I have generated a pixel picture with a perfectly centered AprilTag. I also created a synthetic camera matrix assuming no astigmatism and a perfectly centered focal point (cx,cy). Distortion Coefficients were set to zero. Using this synthetic data, if have been running the pose estimation.

Using this synthetic data, we should have an optical axis that is perfectly aligned with the marker/image center.

I did expect a tvec with X/Y-coordinates close to zero. However, I keep getting X/Y-coordinates with values around 10 units of length (in my case: mm).

I also tried it with ArUco Markers: Same result.

Please find my code and output attached below.

Is my assumption, that X/Y should be close to zero, correct? If so, what might be the reason for this offset? Is it related to the PnP Algorithm or is there a bug in my code?

import cv2 as cv
import numpy as np #imports

dictionary = cv.aruco.getPredefinedDictionary(cv.aruco.DICT_APRILTAG_16H5)
para = cv.aruco.DetectorParameters_create()
para.cornerRefinementMethod = cv.aruco.CORNER_REFINE_APRILTAG
para.aprilTagDeglitch = 0
para.aprilTagMinWhiteBlackDiff = 30
para.aprilTagMaxLineFitMse = 20
para.maxErroneousBitsInBorderRate = 0.35
para.errorCorrectionRate = 1.0
para.minMarkerPerimeterRate = 0.05
para.maxMarkerPerimeterRate = 4
para.polygonalApproxAccuracyRate = 0.05
para.minCornerDistanceRate = 0.05
para.aprilTagMinClusterPixels = 5 #set dictionary and parameter object

camMat = np.array([[14492.753623188406, 0, 1024],[0, 14492.753623188406, 1224],[0, 0, 1]])#camera matrix for f = 50mm with chipsize = 0.00345 mm and 2048x2448px
distCoeffs = np.ndarray([0]) #distortion coefficients

marker_length = 30.00 #mm

corners,ids = cv.aruco.detectMarkers(img,dictionary,parameters = para)[:2]
corners = np.array(corners)

pose = cv.aruco.estimatePoseSingleMarkers(corners,marker_length,camMat,distCoeffs)

tvec = pose[1][0][0].tolist()
print(tvec) #get tvec


My output is:

Tvec for Apriltag Detection = [10.714285714225264, -10.714285714225268, 776.397515563502]
Tvec for ArUco Detection = [10.689704341562148, -10.743286819239351, 776.5576507340221]


Used Picture: C:\fakepath\testimg.png

My system is running: Opencv: 4.1.1, Python 3.7.3, Windows 10

edit retag close merge delete

Sort by » oldest newest most voted

Your assumption concerning the X and Y coordinates of the TVEC is right: If you supply a picture corresponding to a perfectly perpendicular, undistorted view and have the marker centered in the frame, X and Y should yield something close to zero.

It seems that cx and cy in your camera matrix are swapped: As camera sensors formats are usually defined as landscape (h x v), cx should be the bigger value. If I change this in your code, I do get

  [-2.276270217259004e-38, 4.629643948357638e-24, 776.3975155294337]


which is pretty much, what you expected.

more

Official site

GitHub

Wiki

Documentation