目次
概要
OpenCV で ArUco マーカー画像を作成、画像から ArUco マーカーを検出する方法について解説します。
ArUco マーカー
ArUco (Augmented Reality University of Cordoba marker) マーカーとは、拡張現実のアプリケーションで使用することを意図して設計された視覚的なマーカー (通称 AR マーカー, Augmented Reality Markers) の一種で、カメラで簡単に認識できるようになっています。
ArUco マーカー画像を作成する
OpenCV で ArUco マーカーを作成する方法を解説します。
- ArUco マーカーには、マーカーの大きさと数に応じて、辞書がいくつか存在します。
cv2.aruco.getPredefinedDictionary()
に辞書 ID を指定して、50 種類のマーカーが含まれる辞書を取得します。例えば、辞書 ID がcv2.aruco.DICT_4X4_50
の場合、マーカーのサイズは4x4
で、50 種類のマーカーがあることを意味します。 marker_dict.generateImageMarker(id, sidePixels)
を使用して、辞書内のマーカー ID がid
であるマーカーを、解像度が(sidePixels, sidePixels)
の画像として生成します。
In [1]:
import cv2
from IPython.display import Image, display
def imshow(img):
"""ndarray 配列をインラインで Notebook 上に表示する。"""
ret, encoded = cv2.imencode(".png", img)
display(Image(encoded))
In [2]:
import cv2
# Marker Dictionary を作成する。
marker_dict = cv2.aruco.getPredefinedDictionary(cv2.aruco.DICT_4X4_50)
marker_img = marker_dict.generateImageMarker(id=0, sidePixels=200)
imshow(marker_img)
画像に ArUco マーカーを描画する
大きな画像に ArUco マーカーを貼り付けた画像を作成したい場合、以下のコードを使用してください。
In [3]:
import cv2
import numpy as np
def paste(src, dst, x, y):
"""画像を貼り付ける。"""
dst = dst.copy()
src_h, src_w = src.shape[:2]
dst_h, dst_w = dst.shape[:2]
# 貼り付け範囲を計算する。
# (x, y, x + src_w, y + src_h) と (0, 0, dst_w, dst_h) の共通部分を求める。
dst_x1 = max(0, x)
dst_x2 = min(x + src_w, dst_w)
dst_y1 = max(0, y)
dst_y2 = min(y + src_h, dst_h)
if dst_x1 >= dst_x2 or dst_y1 >= dst_y2:
return dst # 貼り付け範囲がない場合
dst[dst_y1:dst_y2, dst_x1:dst_x2] = src[
dst_y1 - y : dst_y2 - y, dst_x1 - x : dst_x2 - x
]
return dst
def create_marker_img(
img_size,
position,
marker_size,
dict_id=cv2.aruco.DICT_4X4_100,
makrer_id=0,
background=(255, 255, 255),
):
"""マーカー画像を作成する。"""
img_w, img_h = img_size # 背景画像の大きさ
x, y = position # 貼り付ける位置
# 背景画像を作成する。
img = np.full((img_h, img_w, 3), background, dtype=np.uint8)
# マーカー画像を作成する。
marker_dict = cv2.aruco.getPredefinedDictionary(dict_id)
marker_img = marker_dict.generateImageMarker(id=makrer_id, sidePixels=marker_size)
marker_img = cv2.cvtColor(marker_img, cv2.COLOR_GRAY2BGR)
# 背景画像にマーカー画像を貼り付ける。
dst = paste(marker_img, img, x, y)
return dst
img = create_marker_img((640, 480), (50, 50), marker_size=100, background=(200, 200, 0))
cv2.imwrite("marker.png", img)
辞書の種類
マーカーのサイズや種類に応じて、以下の辞書が選択できます。
例えば、マーカーで区別したい物体が 200 種類ある場合、200 種類以上のマーカーが必要となるため、cv2.aruco.DICT_4X4_250
を選択します。
辞書 ID | サイズ | 種類 |
---|---|---|
cv2.aruco.DICT_4X4_50 | 4 | 50 |
cv2.aruco.DICT_4X4_100 | 4 | 100 |
cv2.aruco.DICT_4X4_250 | 4 | 250 |
cv2.aruco.DICT_4X4_1000 | 4 | 1000 |
cv2.aruco.DICT_5X5_50 | 5 | 50 |
cv2.aruco.DICT_5X5_100 | 5 | 100 |
cv2.aruco.DICT_5X5_250 | 5 | 250 |
cv2.aruco.DICT_5X5_1000 | 5 | 1000 |
cv2.aruco.DICT_6X6_50 | 6 | 50 |
cv2.aruco.DICT_6X6_100 | 6 | 100 |
cv2.aruco.DICT_6X6_250 | 6 | 250 |
cv2.aruco.DICT_6X6_1000 | 6 | 1000 |
cv2.aruco.DICT_7X7_50 | 7 | 50 |
cv2.aruco.DICT_7X7_100 | 7 | 100 |
cv2.aruco.DICT_7X7_250 | 7 | 250 |
cv2.aruco.DICT_7X7_1000 | 7 | 1000 |
cv2.aruco.DICT_APRILTAG_16H5 | 4 | 30 |
cv2.aruco.DICT_APRILTAG_16h5 | 4 | 30 |
cv2.aruco.DICT_APRILTAG_25H9 | 5 | 35 |
cv2.aruco.DICT_APRILTAG_25h9 | 5 | 35 |
cv2.aruco.DICT_APRILTAG_36H11 | 6 | 587 |
cv2.aruco.DICT_APRILTAG_36h11 | 6 | 587 |
cv2.aruco.DICT_APRILTAG_36H10 | 6 | 2320 |
cv2.aruco.DICT_APRILTAG_36h10 | 6 | 2320 |
cv2.aruco.DICT_ARUCO_ORIGINAL | 5 | 1024 |
cv2.aruco.DICT_ARUCO_MIP_36H12 | 6 | 250 |
cv2.aruco.DICT_ARUCO_MIP_36h12 | 6 | 250 |
ArUco マーカーを検出する
In [4]:
import cv2
img = cv2.imread("sample.jpg")
# 検出対象の辞書 ID を指定して、マーカー辞書を作成する。
marker_dict = cv2.aruco.getPredefinedDictionary(cv2.aruco.DICT_6X6_250)
# マーカーを検出する。
params = cv2.aruco.DetectorParameters()
detector = cv2.aruco.ArucoDetector(marker_dict, params)
corners, ids, rejectedImgPoints = detector.detectMarkers(img)
for corner, marker_id in zip(corners, ids):
print(f"マーカー ID: {marker_id}, 4点の座標: {corner}")
# 検出されたマーカーを描画する。
cv2.aruco.drawDetectedMarkers(img, corners, ids)
# rejectedImgPoints を描画する。
for points in rejectedImgPoints:
cv2.polylines(img, points.astype(np.int64), isClosed=True, color=(0, 0, 255))
imshow(img)
マーカー ID: [40], 4点の座標: [[[359. 310.] [404. 310.] [410. 350.] [362. 350.]]] マーカー ID: [98], 4点の座標: [[[427. 255.] [469. 256.] [477. 289.] [434. 288.]]] マーカー ID: [62], 4点の座標: [[[233. 273.] [190. 273.] [196. 241.] [237. 241.]]] マーカー ID: [23], 4点の座標: [[[298. 185.] [334. 186.] [335. 212.] [297. 211.]]] マーカー ID: [124], 4点の座標: [[[425. 163.] [430. 186.] [394. 186.] [390. 162.]]] マーカー ID: [203], 4点の座標: [[[195. 155.] [230. 155.] [227. 178.] [190. 178.]]]
コメント