Search code examples
pythonopencvaruco

Unable to detect aruco using python


I am working with Aruco in python, and am able to generate a single aruco marker using aruco.drawMarker function but when I am trying to detect the same, I am unable to do so. The markerCorners list is empty and I am getting two rejected candidates. See below code and pictures for clarity.

Code for generating marker

import numpy as np
import cv2 as cv
import cv2.aruco as aruco
dictionary = cv.aruco.Dictionary_get(cv.aruco.DICT_6X6_250)

markerImage = np.zeros((200, 200), dtype=np.uint8)

markerImage = cv.aruco.drawMarker(dictionary, 34, 200, markerImage, 1)

cv.imwrite("marker34.png", markerImage

The generated aruco marker

Marker detection code

import cv2 as cv
import cv2.aruco as aruco
import numpy as np
dictionary = aruco.Dictionary_get(aruco.DICT_6X6_250)
print(dictionary)
parameters = cv.aruco.DetectorParameters_create()
print(parameters.adaptiveThreshWinSizeMax)
frame = cv.imread("marker34.png")

markerCorners, markerIds, rejectedCandidates = cv.aruco.detectMarkers(
    frame, dictionary, parameters=parameters)

print(rejectedCandidates)
print(markerCorners)
# draw circle in opencv
for rect in rejectedCandidates:
    for points in rect:
        for point in points:
            print(point)
            cv.circle(frame, (int(point[0]), int(
                point[1])), 5, (0, 0, 255), -1)

cv.ims("frame", frame)
cv.waitKey(0)

Output of the above code

<aruco_Dictionary 0x7fd7b35caa50>
23
[array([[[ 99., 150.],
        [124., 149.],
        [125., 174.],
        [100., 175.]]], dtype=float32), array([[[ 74.,  25.],
        [ 99.,  24.],
        [100.,  49.],
        [ 75.,  50.]]], dtype=float32)]
[]
[ 99. 150.]
[124. 149.]
[125. 174.]
[100. 175.]
[74. 25.]
[99. 24.]
[100.  49.]
[75. 50.]

When I plotted the rejected points I am getting this imageRejected candidates

Can anyone please help me to figure out my mistake? Thanks in advance!


Solution

  • As already stated, you need to add white padding around the marker so it can be detected.

    For completeness, this can easily be done with np.pad and choosing an appropriate width:

    import numpy as np
    import cv2
    
    image_filename = "marker34.png"
    frame = cv2.imread(image_filename, cv2.IMREAD_GRAYSCALE)
    frame = np.pad(frame, pad_width=100, constant_values=255)