先决条件:
你必须安装 Python 和 OpenCV Contrib
你必须安装 numpy 库
你必须对 Python 语言及其基本库有基本的了解。
如果你想实时识别 Aruco Markers,你可能需要一个网络摄像头。
注意:这里的所有文件都在这个 Github 上:https://github.com/Suave101/StackData/tree/main/Aruco_Marker/How%20to%20draw%20on%20an%20Aruco%20marker%20in%20OpenCV%C2%A0python%3F
Aruco Markers 是OpenCV 库可以使用简单的函数和变量生成和识别的基准标记。每个标记都有自己的识别号。
要开始生成这些标记,我们需要设置项目环境。在开始创建 Python 文件之前,你需要创建一个空文件夹来放置标记生成器。创建此文件夹后,你可以在此文件夹中创建一个 python 文件。如果你很懒,只想复制粘贴一次,这里是 Github 上的文件:https://github.com/Suave101/StackData/tree/main/Aruco_Marker/How%20to%20draw%20on%20an%20Aruco%20marker%20in%20OpenCV%C2%A0python%3F
你需要先导入所需的库:
import cv2
import numpy as np
然后你需要为你的标记设置字典变量和空白变量:
注意:除了 6x6 之外,你还可以使用许多不同大小的字典。这些将在下一节中列出。
dictionary = cv2.aruco.Dictionary_get(cv2.aruco.DICT_6X6_250)
markerImage = np.zeros((300, 300), dtype=np.uint8)
之后,你需要生成标记。下面是一个生成 250 个标记的 for 循环。
for x in range(0, 250):
markerImage = cv2.aruco.drawMarker(dictionary, x, 300, markerImage, 1)
cv2.imwrite(f"marker{x}.png", markerImage)
运行此代码(https://github.com/Suave101/StackData/blob/main/Aruco_Marker/How%20to%20draw%20on%20an%20Aruco%20marker%20in%20OpenCV%C2%A0python%3F/aruco_marker_generator.py)后,你应该会得到一个包含 Aruco Markers 的文件夹。
如果你收到这样的错误:
AttributeError: module 'cv2' has no attribute 'aruco'
这可能是因为你没有安装 OpenCV 的 contrib 版本。要干净利落地执行此操作,你必须卸载旧的 OpenCV 发行版,然后下载 contrib 版本。
pip uninstall opencv-python
pip install opencv-contrib-python
首先,在识别 Aruco 标记时,我们将在图像中识别它们。
这是 Github 上的代码:https://github.com/Suave101/StackData/tree/main/Aruco_Marker/How%20to%20draw%20on%20an%20Aruco%20marker%20in%20OpenCV%C2%A0python%3F
我们需要 Aruco 标记的图像,因此,你应该使用网络摄像头或手机拍照,以便让 OpenCV 找到 Aruco 标记。以下代码显示了如何读取图像:
import cv2
image = cv2.imread("path\\to\\image.png")
接下来,你需要定义字典大小和参数:
dictionary = cv2.aruco.Dictionary_get(cv2.aruco.DICT_6X6_250)
parameters = cv2.aruco.DetectorParameters_create()
最后,你需要查找标记并打印数据:
markerCorners, markerIds, rejectedCandidates = cv2.aruco.detectMarkers(image, dictionary, parameters=parameters)
print(markerIds)
要实时识别 Aruco 标记,我们需要有一个网络摄像头来获取帧。如果你没有网络摄像头,你仍然可以通过从 Internet 获取视频或使用录制设备录制视频来参与此练习。
为此,你必须将 Video Capture 函数中的 number 参数替换为你尝试读取的视频的路径。例如,我将在下面使用的视频文件名为“Mighty_Wings.mov”,它位于我的硬盘 Z 上:
vid = cv2.VideoCapture("Z:\\Mighty_Wings.mov")
回到现场识别标记。首先,我们将初始化所需的变量并导入必要的库。在这种情况下,我们只导入 OpenCV 库。我们之前已经看过字典和参数变量,但是,这个视频捕获对象呢?视频捕获对象从视频源或网络摄像头获取视频输入。0 代表使用的视频设备。
import cv2
vid = cv2.VideoCapture(0)
dictionary = cv2.aruco.Dictionary_get(cv2.aruco.DICT_6X6_250)
parameters = cv2.aruco.DetectorParameters_create()
现在我们需要定义识别循环。首先,循环从网络摄像头读取作为实时图像的帧数据。然后它会寻找一个 Aruco 标记。这个 while 循环将循环直到按下等待键“q”。
while True:
ret, frame = vid.read()
markerCorners, markerIds, rejectedCandidates = cv2.aruco.detectMarkers(frame, dictionary, parameters=parameters)
cv2.imshow('frame', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
最后,我们将停止从网络摄像头或视频源获取视频输入,并关闭任何延迟的窗口以实现冗余。
vid.release()
cv2.destroyAllWindows()
这是要复制和粘贴的 Github 文件:https://github.com/Suave101/StackData/blob/main/Aruco_Marker/How%20to%20draw%20on%20an%20Aruco%20marker%20in%20OpenCV%C2%A0python%3F/advanced_aruco_recognition.py
首先,我们导入库并定义变量。我们将随机库用于随机唯一颜色的 ID。我们使用数学库来计算距离公式。for 循环创建一个随机颜色列表。它比冗余所需的时间长。
import random
import cv2
import math
vid = cv2.VideoCapture(0)
dictionary = cv2.aruco.Dictionary_get(cv2.aruco.DICT_6X6_250)
parameters = cv2.aruco.DetectorParameters_create()
color_list = []
for x in range(0, 260):
color_list.append((random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)))
然后我们得到大坏循环函数。我们读取帧,然后寻找标记。之后,我们将解析结果,直到我们得到 4 组坐标。它们是矩形的每个角。它们被放入一个列表中,因此我们从左下角开始,围绕矩形逆时针方向移动。
顶点标记
然后我们使用一些代数来获得宽度和高度。OpenCV 矩形函数使用顶点零作为其 X 和 Y 位置。此外,我们将矩形标记为 Aruco Marker ID。
请注意,文本标签在矩形下方 10 像素处,以免被矩形覆盖。我们从上一步中创建的颜色列表中获取一种颜色,以获得独特的颜色。
while True:
ret, frame = vid.read()
markerCorners, markerIds, rejectedCandidates = cv2.aruco.detectMarkers(frame, dictionary, parameters=parameters)
del rejectedCandidates
if markerIds is not None:
i = 0
for marker in markerIds:
k = str(markerCorners[i]).replace("\n", "").split("[")
k2 = []
for j in k:
j = j.split("]")
j2 = []
for n in j:
n = n.split(".")
j2 = j2 + n
k2 = k2 + j2
del j2, j
del k
k3 = []
for item in k2:
try:
k3.append(int(item))
except:
pass
del k2
k2 = [k3[i:i + 2] for i in range(0, len(k3), 2)]
del k3
x = k2[0][0]
y = k2[0][1]
w = int(math.dist(k2[0], k2[1]))
h = int(math.dist(k2[3], k2[0]))
frame = cv2.rectangle(frame, (x, y), (x + w, y + h), color_list[int(marker)], 1)
frame = cv2.putText(frame, f'Marker: {int(marker)}', (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9,
color_list[int(marker)], 2)
i = i + 1
del i, markerCorners, markerIds
cv2.imshow('frame', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
最后,我们执行之前见过的冗余代码行。
vid.release()
cv2.destroyAllWindows()
有许多不同大小的标记用于不同的用途。你可能希望对质量较低的相机或距离较远的相机使用较少量的数据。相反,如果你的环境中需要更多数据点,你可能需要更大的数据集。
4x4 标记有 50 个可能的 ID。5x5 标记有 100 个可能的 ID。6x6 标记有 250 个可能的 ID。7x7 标记有 1000 个可能的 ID。6x6 是最流行的标记系统之一。这就是我们使用它的原因。
本教程没有沿色谱的颜色分布均匀。为此,你必须乘以黄金比例,使用一些调制函数,并将 HSV 值转换为 RGB 值。
☆ END ☆
如果看到这里,说明你喜欢这篇文章,请转发、点赞。微信搜索「uncle_pn」,欢迎添加小编微信「 woshicver」,每日朋友圈更新一篇高质量博文。
↓扫描二维码添加小编↓