• 在 OpenCV python 中绘制 Aruco 标记


    先决条件:

    • 你必须安装 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 标记?

    Aruco Markers 是OpenCV 库可以使用简单的函数和变量生成和识别的基准标记。每个标记都有自己的识别号。

    如何生成 Aruco 标记?

    要开始生成这些标记,我们需要设置项目环境。在开始创建 Python 文件之前,你需要创建一个空文件夹来放置标记生成器。创建此文件夹后,你可以在此文件夹中创建一个 python 文件。如果你很懒,只想复制粘贴一次,这里是 Github 上的文件:https://github.com/Suave101/StackData/tree/main/Aruco_Marker/How%20to%20draw%20on%20an%20Aruco%20marker%20in%20OpenCV%C2%A0python%3F

    你需要先导入所需的库:

    1. import cv2
    2. import numpy as np

    然后你需要为你的标记设置字典变量和空白变量:

    注意:除了 6x6 之外,你还可以使用许多不同大小的字典。这些将在下一节中列出。

    1. dictionary = cv2.aruco.Dictionary_get(cv2.aruco.DICT_6X6_250)
    2. markerImage = np.zeros((300300), dtype=np.uint8)

    之后,你需要生成标记。下面是一个生成 250 个标记的 for 循环。

    1. for x in range(0250):
    2.     markerImage = cv2.aruco.drawMarker(dictionary, x, 300, markerImage, 1)
    3.     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 版本。

    1. pip uninstall opencv-python
    2. pip install opencv-contrib-python

    如何识别 Aruco 标记?

    首先,在识别 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 标记。以下代码显示了如何读取图像:

    1. import cv2
    2. image = cv2.imread("path\\to\\image.png")

    接下来,你需要定义字典大小和参数:

    1. dictionary = cv2.aruco.Dictionary_get(cv2.aruco.DICT_6X6_250)
    2. parameters = cv2.aruco.DetectorParameters_create()

    最后,你需要查找标记并打印数据:

    1. markerCorners, markerIds, rejectedCandidates = cv2.aruco.detectMarkers(image, dictionary, parameters=parameters)
    2. print(markerIds)

    如何实时识别 Aruco 标记?

    要实时识别 Aruco 标记,我们需要有一个网络摄像头来获取帧。如果你没有网络摄像头,你仍然可以通过从 Internet 获取视频或使用录制设备录制视频来参与此练习。

    为此,你必须将 Video Capture 函数中的 number 参数替换为你尝试读取的视频的路径。例如,我将在下面使用的视频文件名为“Mighty_Wings.mov”,它位于我的硬盘 Z 上:

    vid = cv2.VideoCapture("Z:\\Mighty_Wings.mov")

    回到现场识别标记。首先,我们将初始化所需的变量并导入必要的库。在这种情况下,我们只导入 OpenCV 库。我们之前已经看过字典和参数变量,但是,这个视频捕获对象呢?视频捕获对象从视频源或网络摄像头获取视频输入。0 代表使用的视频设备。

    1. import cv2
    2. vid = cv2.VideoCapture(0)
    3. dictionary = cv2.aruco.Dictionary_get(cv2.aruco.DICT_6X6_250)
    4. parameters = cv2.aruco.DetectorParameters_create()

    现在我们需要定义识别循环。首先,循环从网络摄像头读取作为实时图像的帧数据。然后它会寻找一个 Aruco 标记。这个 while 循环将循环直到按下等待键“q”。

    1. while True:
    2.     ret, frame = vid.read()
    3.     markerCorners, markerIds, rejectedCandidates = cv2.aruco.detectMarkers(frame, dictionary, parameters=parameters)
    4.     cv2.imshow('frame', frame)
    5.     if cv2.waitKey(1) & 0xFF == ord('q'):
    6.         break

    最后,我们将停止从网络摄像头或视频源获取视频输入,并关闭任何延迟的窗口以实现冗余。

    1. vid.release()
    2. cv2.destroyAllWindows()

    如何在 Aruco Markers 周围制作边界框?

    这是要复制和粘贴的 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 循环创建一个随机颜色列表。它比冗余所需的时间长。

    1. import random
    2. import cv2
    3. import math
    4. vid = cv2.VideoCapture(0)
    5. dictionary = cv2.aruco.Dictionary_get(cv2.aruco.DICT_6X6_250)
    6. parameters = cv2.aruco.DetectorParameters_create()
    7. color_list = []
    8. for x in range(0260):
    9.     color_list.append((random.randint(0255), random.randint(0255), random.randint(0255)))

    然后我们得到大坏循环函数。我们读取帧,然后寻找标记。之后,我们将解析结果,直到我们得到 4 组坐标。它们是矩形的每个角。它们被放入一个列表中,因此我们从左下角开始,围绕矩形逆时针方向移动。

    b9e25bcccf9cde137fe364b8b572c95f.png

    顶点标记

    然后我们使用一些代数来获得宽度和高度。OpenCV 矩形函数使用顶点零作为其 X 和 Y 位置。此外,我们将矩形标记为 Aruco Marker ID。

    请注意,文本标签在矩形下方 10 像素处,以免被矩形覆盖。我们从上一步中创建的颜色列表中获取一种颜色,以获得独特的颜色。

    1. while True:
    2.     ret, frame = vid.read()
    3.     markerCorners, markerIds, rejectedCandidates = cv2.aruco.detectMarkers(frame, dictionary, parameters=parameters)
    4.     del rejectedCandidates
    5.     if markerIds is not None:
    6.         i = 0
    7.         for marker in markerIds:
    8.             k = str(markerCorners[i]).replace("\n""").split("[")
    9.             k2 = []
    10.             for j in k:
    11.                 j = j.split("]")
    12.                 j2 = []
    13.                 for n in j:
    14.                     n = n.split(".")
    15.                     j2 = j2 + n
    16.                 k2 = k2 + j2
    17.                 del j2, j
    18.             del k
    19.             k3 = []
    20.             for item in k2:
    21.                 try:
    22.                     k3.append(int(item))
    23.                 except:
    24.                     pass
    25.             del k2
    26.             k2 = [k3[i:i + 2for i in range(0len(k3), 2)]
    27.             del k3
    28.             x = k2[0][0]
    29.             y = k2[0][1]
    30.             w = int(math.dist(k2[0], k2[1]))
    31.             h = int(math.dist(k2[3], k2[0]))
    32.             frame = cv2.rectangle(frame, (x, y), (x + w, y + h), color_list[int(marker)], 1)
    33.             frame = cv2.putText(frame, f'Marker: {int(marker)}', (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9,
    34.                                 color_list[int(marker)], 2)
    35.             i = i + 1
    36.         del i, markerCorners, markerIds
    37.     cv2.imshow('frame', frame)
    38.     if cv2.waitKey(1) & 0xFF == ord('q'):
    39.         break

    最后,我们执行之前见过的冗余代码行。

    1. vid.release()
    2. cv2.destroyAllWindows()

    有哪些不同尺寸的 Aruco 标记?

    有许多不同大小的标记用于不同的用途。你可能希望对质量较低的相机或距离较远的相机使用较少量的数据。相反,如果你的环境中需要更多数据点,你可能需要更大的数据集。

    4x4 标记有 50 个可能的 ID。5x5 标记有 100 个可能的 ID。6x6 标记有 250 个可能的 ID。7x7 标记有 1000 个可能的 ID。6x6 是最流行的标记系统之一。这就是我们使用它的原因。

    关于“独特颜色(Unique Colors)”的注意事项

    本教程没有沿色谱的颜色分布均匀。为此,你必须乘以黄金比例,使用一些调制函数,并将 HSV 值转换为 RGB 值。

    ☆ END ☆

    如果看到这里,说明你喜欢这篇文章,请转发、点赞。微信搜索「uncle_pn」,欢迎添加小编微信「 woshicver」,每日朋友圈更新一篇高质量博文。

    扫描二维码添加小编↓

    0c05338eb035bdecd30df9f845e59186.jpeg

  • 相关阅读:
    JavaScript 通过对键的引用获取对象的值
    如何排查CPU飙升的问题所在
    C#通过Entity Framework实体对数据表增删改查
    WPF类似于WINFORM的Onpaint
    解决Adobe Premiere Pro CC 2018打开无反应,并出现.crash的文件问题
    JVM调优必备理论知识-GC Collector-三色标记
    基础复习——共享参数SharedPreferences——记住密码项目——存储卡的文件操作(读写文件&读写图片)...
    VUE 组合式API
    爱尔兰博士后招聘|利默里克大学-广告学
    GitHub 已霸榜!阿里技术官肝了 3 个月才完成的 20 万字 Java 面试手册
  • 原文地址:https://blog.csdn.net/woshicver/article/details/126595553