Note

This notebook can be downloaded here: aruco_basics_video.ipynb

ARUCO markers: basics

1: Marker creation

import numpy as np
import cv2, PIL
from cv2 import aruco
import matplotlib.pyplot as plt
import matplotlib as mpl
import pandas as pd
%matplotlib nbagg
aruco_dict = aruco.Dictionary_get(aruco.DICT_6X6_250)

fig = plt.figure()
nx = 4
ny = 3
for i in range(1, nx*ny+1):
    ax = fig.add_subplot(ny,nx, i)
    img = aruco.drawMarker(aruco_dict,i, 700)
    plt.imshow(img, cmap = mpl.cm.gray, interpolation = "nearest")
    ax.axis("off")

plt.savefig("_data/markers.jpeg")
plt.show()
<IPython.core.display.Javascript object>

3: Post processing

%%time
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
aruco_dict = aruco.Dictionary_get(aruco.DICT_6X6_250)
parameters =  aruco.DetectorParameters_create()
corners, ids, rejectedImgPoints = aruco.detectMarkers(gray, aruco_dict, parameters=parameters)
frame_markers = aruco.drawDetectedMarkers(frame.copy(), corners, ids)
Wall time: 178 ms
rejectedImgPoints[1]
array([[[ 1213.,  1229.],
        [ 1217.,  1221.],
        [ 1259.,  1224.],
        [ 1256.,  1229.]]], dtype=float32)
corners
[array([[[ 1339.,   951.],
         [ 1413.,   934.],
         [ 1434.,   981.],
         [ 1358.,   999.]]], dtype=float32), array([[[ 2247.,  1604.],
         [ 2306.,  1653.],
         [ 2263.,  1691.],
         [ 2203.,  1643.]]], dtype=float32), array([[[ 2071.,  1279.],
         [ 2101.,  1233.],
         [ 2162.,  1267.],
         [ 2132.,  1314.]]], dtype=float32), array([[[ 1209.,  1217.],
         [ 1297.,  1218.],
         [ 1290.,  1287.],
         [ 1201.,  1286.]]], dtype=float32), array([[[ 1507.,  1244.],
         [ 1510.,  1309.],
         [ 1421.,  1313.],
         [ 1419.,  1245.]]], dtype=float32), array([[[  940.,  1212.],
         [  933.,  1282.],
         [  840.,  1285.],
         [  849.,  1216.]]], dtype=float32), array([[[ 2736.,  1132.],
         [ 2764.,  1183.],
         [ 2723.,  1241.],
         [ 2701.,  1191.]]], dtype=float32), array([[[ 1140.,  1120.],
         [ 1129.,  1059.],
         [ 1214.,  1048.],
         [ 1226.,  1108.]]], dtype=float32), array([[[  990.,  1050.],
         [  906.,  1071.],
         [  885.,  1013.],
         [  968.,   993.]]], dtype=float32), array([[[ 1586.,   950.],
         [ 1513.,   929.],
         [ 1543.,   879.],
         [ 1616.,   899.]]], dtype=float32)]

Pretty fast processing !

4: Results

plt.figure()
plt.imshow(frame_markers, origin = "upper")
if ids is not None:
    for i in range(len(ids)):
        c = corners[i][0]
        plt.plot([c[:, 0].mean()], [c[:, 1].mean()], "+", label = "id={0}".format(ids[i]))
"""for points in rejectedImgPoints:
    y = points[:, 0]
    x = points[:, 1]
    plt.plot(x, y, ".m-", linewidth = 1.)"""
plt.legend()
plt.show()
<IPython.core.display.Javascript object>
def quad_area(data):
    l = data.shape[0]//2
    corners = data[["c1", "c2", "c3", "c4"]].values.reshape(l, 2,4)
    c1 = corners[:, :, 0]
    c2 = corners[:, :, 1]
    c3 = corners[:, :, 2]
    c4 = corners[:, :, 3]
    e1 = c2-c1
    e2 = c3-c2
    e3 = c4-c3
    e4 = c1-c4
    a = -.5 * (np.cross(-e1, e2, axis = 1) + np.cross(-e3, e4, axis = 1))
    return a

corners2 = np.array([c[0] for c in corners])

data = pd.DataFrame({"x": corners2[:,:,0].flatten(), "y": corners2[:,:,1].flatten()},
                   index = pd.MultiIndex.from_product(
                           [ids.flatten(), ["c{0}".format(i )for i in np.arange(4)+1]],
                       names = ["marker", ""] ))

data = data.unstack().swaplevel(0, 1, axis = 1).stack()
data["m1"] = data[["c1", "c2"]].mean(axis = 1)
data["m2"] = data[["c2", "c3"]].mean(axis = 1)
data["m3"] = data[["c3", "c4"]].mean(axis = 1)
data["m4"] = data[["c4", "c1"]].mean(axis = 1)
data["o"] = data[["m1", "m2", "m3", "m4"]].mean(axis = 1)
data
c1 c2 c3 c4 m1 m2 m3 m4 o
marker
1 x 1209.0 1297.0 1290.0 1201.0 1253.0 1293.5 1245.5 1205.0 1249.25
y 1217.0 1218.0 1287.0 1286.0 1217.5 1252.5 1286.5 1251.5 1252.00
3 x 2736.0 2764.0 2723.0 2701.0 2750.0 2743.5 2712.0 2718.5 2731.00
y 1132.0 1183.0 1241.0 1191.0 1157.5 1212.0 1216.0 1161.5 1186.75
4 x 1140.0 1129.0 1214.0 1226.0 1134.5 1171.5 1220.0 1183.0 1177.25
y 1120.0 1059.0 1048.0 1108.0 1089.5 1053.5 1078.0 1114.0 1083.75
5 x 2071.0 2101.0 2162.0 2132.0 2086.0 2131.5 2147.0 2101.5 2116.50
y 1279.0 1233.0 1267.0 1314.0 1256.0 1250.0 1290.5 1296.5 1273.25
6 x 1507.0 1510.0 1421.0 1419.0 1508.5 1465.5 1420.0 1463.0 1464.25
y 1244.0 1309.0 1313.0 1245.0 1276.5 1311.0 1279.0 1244.5 1277.75
7 x 2247.0 2306.0 2263.0 2203.0 2276.5 2284.5 2233.0 2225.0 2254.75
y 1604.0 1653.0 1691.0 1643.0 1628.5 1672.0 1667.0 1623.5 1647.75
9 x 940.0 933.0 840.0 849.0 936.5 886.5 844.5 894.5 890.50
y 1212.0 1282.0 1285.0 1216.0 1247.0 1283.5 1250.5 1214.0 1248.75
10 x 990.0 906.0 885.0 968.0 948.0 895.5 926.5 979.0 937.25
y 1050.0 1071.0 1013.0 993.0 1060.5 1042.0 1003.0 1021.5 1031.75
11 x 1339.0 1413.0 1434.0 1358.0 1376.0 1423.5 1396.0 1348.5 1386.00
y 951.0 934.0 981.0 999.0 942.5 957.5 990.0 975.0 966.25
12 x 1586.0 1513.0 1543.0 1616.0 1549.5 1528.0 1579.5 1601.0 1564.50
y 950.0 929.0 879.0 899.0 939.5 904.0 889.0 924.5 914.25
# Plante un peu...
"""cap = cv2.VideoCapture('_data/AeroTrain.mp4')
while(cap.isOpened()):
    ret, frame = cap.read()

    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    cv2.imshow('frame',gray)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()"""
"cap = cv2.VideoCapture('_data/AeroTrain.mp4')nwhile(cap.isOpened()):n    ret, frame = cap.read()nn    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)nn    cv2.imshow('frame',gray)n    if cv2.waitKey(1) & 0xFF == ord('q'):n        breaknncap.release()ncv2.destroyAllWindows()"
cap = cv2.VideoCapture('_data/AeroTrain.mp4')
nframe = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))

print("nframe =", nframe)
cap.set(1, 300) # arguments: 1: laisser, 2: numéro du frame
ret, frame = cap.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
plt.figure()
plt.imshow(gray)
plt.show()
cap.release()
nframe = 712
<IPython.core.display.Javascript object>
%%time
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
aruco_dict = aruco.Dictionary_get(aruco.DICT_6X6_250)
parameters =  aruco.DetectorParameters_create()
corners, ids, rejectedImgPoints = aruco.detectMarkers(gray, aruco_dict, parameters=parameters)
frame_markers = aruco.drawDetectedMarkers(frame.copy(), corners, ids)
Wall time: 31.3 ms
plt.figure()
plt.imshow(frame_markers, origin = "upper")
if ids is not None:
    for i in range(len(ids)):
        c = corners[i][0]
        plt.plot([c[:, 0].mean()], [c[:, 1].mean()], "+", label = "id={0}".format(ids[i]))
"""for points in rejectedImgPoints:
    y = points[:, 0]
    x = points[:, 1]
    plt.plot(x, y, ".m-", linewidth = 1.)"""
plt.legend()
plt.show()
<IPython.core.display.Javascript object>
help(aruco.DetectorParameters_create)
Help on built-in function DetectorParameters_create:

DetectorParameters_create(...)
    DetectorParameters_create() -> retval
    .