はじめに
OpenCVを使用してArUcoマーカの認識をしようとしたらバージョンの更新によって関数名の更新があったのでまとめます。
Web上に公開されているサンプルプログラムでも同じバージョンでないと基本的に動かないので辞書的な使い方で参考になれば幸いです。
ここでは、ArUcoマーカの生成、認識、描画等最低限の関数のみ記載することとします。
より詳細な情報は公式ページを参照してください。
バージョン
サンプルプログラムは、**4.7.0**
で動作確認したものです。
サンプルプログラム
マーカ画像の作成
マーカ画像の周りに余白を設けるために少し工夫しています。
(白い画像のimgを用意してそれに重ね合わせている。参考)
#!/usr/bin/env python3
# coding: utf-8
import cv2
import numpy as np
from cv2 import aruco
# Size and offset value
size = 150
offset = 10
x_offset = y_offset = int(offset) // 2
# get dictionary and generate image
dictionary = aruco.getPredefinedDictionary(aruco.DICT_4X4_50)
ar_img = aruco.generateImageMarker(dictionary, 0, size)
# make white image
img = np.zeros((size + offset, size + offset), dtype=np.uint8)
img += 255
# overlap image
img[y_offset:y_offset + ar_img.shape[0], x_offset:x_offset + ar_img.shape[1]] = ar_img
cv2.imwrite("marker_0.png", img)
マーカの読み込み&描画
#!/usr/bin/env python3
# coding: utf-8
import cv2
from cv2 import aruco
# get dicionary and get parameters
dictionary = aruco.getPredefinedDictionary(aruco.DICT_4X4_50)
parameters = aruco.DetectorParameters()
# read from image
input_file = "marker_0.png"
output_file = "detected_marker_0.png"
input_img = cv2.imread(input_file)
# detect and draw marker's information
corners, ids, rejectedCandidates = aruco.detectMarkers(input_img, dictionary, parameters=parameters)
print(ids)
ar_image = aruco.drawDetectedMarkers(input_img, corners, ids)
cv2.imwrite(output_file, ar_image)
更新箇所
辞書の読み込み
Dictionary_get()の廃止
辞書を取得する関数のうちの一つがなくなりました。
getPredefinedDictionary()
は4.6.0と4.7.0で変わっていないのでそれを使うのがベターだと思います。
# ver 4.6.0
Dictionary_get(dictionary_name)
getPredefinedDictionary(dictionary_name)
# ver 4.7.0
getPredefinedDictionary(dictionary_name)
ver4.7.0でDictionary_get()
を使用すると下記のエラーが発生しました。
AttributeError: module 'cv2.aruco' has no attribute 'Dictionary_get'. Did you mean: 'Dictionary'?
Dictionary_get (ver4.6.0)
getPredefinedDictionary (ver4.6.0)
getPredefinedDictionary (ver4.7.0)
マーカの生成
drawMarker => generateImageMarker
マーカを生成する関数名が変わっていました。
# Ver 4.6.0
cv.aruco.drawMarker(dictionary, id, sidePixels)
# Ver 4.7.0
cv.aruco.generateImageMarker(dictionary, id, sidePixels)
ver4.7.0でdrawMarker()
を使用すると下記のエラーが発生しました。
AttributeError: module 'cv2.aruco' has no attribute 'drawMarker'
drawMarker (ver4.6.0)
generateImageMarker (ver4.7.0)
C++の場合は、include対象も変更されているので注意してください。
マーカの認識
パラメータの取得
マーカを認識する際に使用するパラメータ変数を取得する関数の関数名が変更になっていました。
# ver 4.6.0
parameters = cv.aruco.DetectorParameters_create()
# ver4.7.0
parameters = cv.aruco.DetectorParameters()
ver4.7.0でDetectorParameters_create()
を使用すると下記のエラーが発生しました。
AttributeError: module 'cv2.aruco' has no attribute 'DetectorParameters_create'. Did you mean: 'DetectorParameters'?
DetectorParameters::create (ver 4.6.0)
PythonだとDetectorParameters_create()
DetectorParameters (ver 4.7.0)
コンストラクタだけでよくなったようです。
(少なくともメンバ変数からcreate
は消えました)
マーカの認識&描画
マーカの認識には、ver4.6.0、ver4.7.0どちらでもdetectMarkers
、認識結果の描画にはdrawDetectedMarkers
を使用できます。
ただ、ver4.7.0では cv.aruco.ArucoDetector.detectMarkers
が追加されています。
detectMarkers (ver4.6.0)
detectMarkers (ver4.7.0)
ArucoDetector.detectMarkers (ver4.7.0)
drawDetectedMarkers (ver4.6.0)
drawDetectedMarkers (ver4.7.0)
C++の場合は、include対象も変更されているので注意してください。
おわりに
バージョン情報の記載は大事ということに気付きました!!
必要があればほかの関数についても追記します。