Try it by referring to Detection of ArUco Markers.
Environment: Mac OS X El Capitan OpenCV 3.2
ArUco features are included in OpenCV's contrib. So if you have OpenCV installed with homebrew, install it with the --with-contrib option.
% brew install opencv3 --with-contrib
In OpenCV a while ago, ArUco's Python support did not seem to be perfect. But now it feels like it can be used crisply.
import cv2
aruco = cv2.aruco
dir(aruco)
It was output like this.
['Board_create',
'CharucoBoard_create',
'DICT_4X4_100',
'DICT_4X4_1000',
'DICT_4X4_250',
'DICT_4X4_50',
'DICT_5X5_100',
'DICT_5X5_1000',
'DICT_5X5_250',
'DICT_5X5_50',
'DICT_6X6_100',
'DICT_6X6_1000',
'DICT_6X6_250',
'DICT_6X6_50',
'DICT_7X7_100',
'DICT_7X7_1000',
'DICT_7X7_250',
'DICT_7X7_50',
'DICT_ARUCO_ORIGINAL',
'DetectorParameters_create',
'Dictionary_create',
'Dictionary_create_from',
'Dictionary_get',
'GridBoard_create',
'__doc__',
'__name__',
'__package__',
'calibrateCameraAruco',
'calibrateCameraArucoExtended',
'calibrateCameraCharuco',
'calibrateCameraCharucoExtended',
'custom_dictionary',
'custom_dictionary_from',
'detectCharucoDiamond',
'detectMarkers',
'drawAxis',
'drawDetectedCornersCharuco',
'drawDetectedDiamonds',
'drawDetectedMarkers',
'drawMarker',
'drawPlanarBoard',
'estimatePoseBoard',
'estimatePoseCharucoBoard',
'estimatePoseSingleMarkers',
'getPredefinedDictionary',
'interpolateCornersCharuco',
'refineDetectedMarkers’]
Create a dictionary object using a predefined dictionary. In this case, the size of the markers is 4x4 and the number of markers is 50.
dictionary = aruco.getPredefinedDictionary(aruco.DICT_4X4_50)
Then draw the marker. The second parameter is the value held by the marker and the third parameter is the size of the marker image.
marker = aruco.drawMarker(dictionary, 4, 100)
I made something like this!
Prepare an image with a marker and call it as follows. I captured the screen of the jupyter I'm trying and tried to reduce the image to 1/20 and detect it.
img = cv2.imread('screenshot.png')
img = cv2.resize(img, None, fx=0.05, fy=0.05)
corners, ids, rejectedImgPoints = aruco.detectMarkers(img, dictionary)
Even if the size of the marker is a dozen pixels, it can be detected correctly. It's excellent!
for number, corner in zip(ids, corners):
print number, corner
[4] [[[ 11. 34.]
[ 26. 34.]
[ 26. 48.]
[ 11. 48.]]]
[4] [[[ 11. 6.]
[ 26. 6.]
[ 26. 20.]
[ 11. 20.]]]
It seems that there are various other functions, so I will play with it.