Hey there,
I’ve been trying to detect custom markers similar to 5x5 ArUco markers such as the one below:
Using the following code adapted from this repo, it is able to detect normal ArUco markers with no issues, but is very inconsistent when trying to detect custom markers.
# Program to create custom ArUco dictionary using OpenCV and detect markers using webcam
# original code from: http://www.philipzucker.com/aruco-in-opencv/
# Modified by Iyad Aldaqre
# 12.07.2019
import numpy as np
import cv2
import cv2.aruco as aruco
# we will not use a built-in dictionary, but we could
# aruco_dict = aruco.getPredefinedDictionary(aruco.DICT_4X4_50)
# define an empty custom dictionary with
aruco_dict = aruco.Dictionary(0, 5, 1)
# add empty bytesList array to fill with 3 markers later
aruco_dict.bytesList = np.empty(shape = (4, 4, 4), dtype = np.uint8)
# add new marker(s)
mybits = np.array([[0,0,1,0,0],[0,1,0,1,0],[1,1,1,1,1],[1,0,0,0,1],[1,0,0,0,1]], dtype = np.uint8) # A
aruco_dict.bytesList[0] = aruco.Dictionary.getByteListFromBits(mybits)
mybits = np.array([[1,1,1,1,0],[1,0,0,0,1],[1,1,1,1,0],[1,0,0,0,1],[1,1,1,1,0]], dtype = np.uint8) # B
aruco_dict.bytesList[1] = aruco.Dictionary.getByteListFromBits(mybits)
mybits = np.array([[0,1,1,1,0],[1,0,0,0,1],[1,0,0,0,0],[1,0,0,0,1],[0,1,1,1,0]], dtype = np.uint8) # C
aruco_dict.bytesList[2] = aruco.Dictionary.getByteListFromBits(mybits)
mybits = np.array([[1,0,1,0,0],[0,1,0,1,1],[0,1,1,0,0],[1,0,1,0,1],[1,1,1,0,0]], dtype = np.uint8) # ArUco 5x5_50 id:0
aruco_dict.bytesList[3] = aruco.Dictionary.getByteListFromBits(mybits)
# save marker images
for i in range(len(aruco_dict.bytesList)):
cv2.imwrite("custom_aruco_" + str(i) + ".png", aruco.generateImageMarker(aruco_dict, i, 128))
aruco_param = aruco.DetectorParameters()
aruco_detector = aruco.ArucoDetector(aruco_dict, aruco_param)
# open video capture from (first) webcam
cap = cv2.VideoCapture(0)
while(True):
# Capture frame-by-frame
ret, frame = cap.read()
if ret == True:
# Conver to grayscale
grayscale = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
bw = cv2.threshold(grayscale, 128, 255, cv2.THRESH_BINARY)[1]
#lists of ids and the corners beloning to each id
corners, ids, rejectedImgPoints = aruco_detector.detectMarkers(grayscale)
# draw markers on farme
frame = aruco.drawDetectedMarkers(frame, corners, ids)
# resize frame to show even on smaller screens
frame = cv2.resize(frame, None, fx = 0.6, fy = 0.6)
# Display the resulting frame
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()
Any idea why this might be? Are there parameters I need to tune to make this work for custom markers or does the ArUco detector simply not work for these?
Thank you!