Aruco标签定位、测距、三维位置估算 opencv应用

这篇具有很好参考价值的文章主要介绍了Aruco标签定位、测距、三维位置估算 opencv应用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

aruco定位,aruco,opencv4.0,opencv,opencv,python,定位,计算机视觉,aruco

 aruco定位,aruco,opencv4.0,opencv,opencv,python,定位,计算机视觉,aruco

 准备:

+ aruco标签6*6

+ 相机标定文件(参考我的上篇文章)

+ 摄像头

+ 摄像头要一开始对准aruco标签才开始运行文章来源地址https://www.toymoban.com/news/detail-629281.html

import numpy as np
import time
import cv2
import cv2.aruco as aruco
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import yaml
import warnings
warnings.filterwarnings("ignore")
cv2.namedWindow('imgage', cv2.WINDOW_FREERATIO)



###加载标定参数yaml
###加载文件路径###
file_path = ("./4k标定参数.yaml")
# file_path = ("/home/pi/PycharmProjects/pythonProject/opencv_test/变焦相机标定参数.yaml")
###加载文件路径###

with open(file_path, "r") as file:
    parameter = yaml.load(file.read(), Loader=yaml.Loader)
    mtx = parameter['camera_matrix']
    dist = parameter['dist_coeff']
    camera_u = parameter['camera_u']
    camera_v = parameter['camera_v']
    mtx = np.array(mtx)
    dist = np.array(dist)



#打开摄像头
ID = 0
while (1):

    cap = cv2.VideoCapture(ID)
    ret, frame = cap.read()
    if ret == False:
        ID += 1
    elif ID >= 10:
        break
    else:
        #print(ID)
        break

font = cv2.FONT_HERSHEY_SIMPLEX  # font for displaying text (below)
flag = cap.isOpened()
cap.set(3, 3840)
cap.set(4, 2160)
cap.set(6, cv2.VideoWriter.fourcc(*'MJPG'))

plt.ion()
#画三维图

fig = plt.figure()
ax = fig.gca(projection="3d")


    #print(mtx, dist, camera_u, camera_v)
while 1:

    ret, img = cap.read()
    frame = img
    h1, w1 = frame.shape[:2]
    newcameramtx, roi = cv2.getOptimalNewCameraMatrix(mtx, dist, (h1, w1), 0, (h1, w1))
    dst1 = cv2.undistort(frame, mtx, dist, None, newcameramtx)
    x, y, w1, h1 = roi
    dst1 = dst1[y:y + h1, x:x + w1]
    frame1 = dst1

    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    aruco_dict = aruco.Dictionary_get(aruco.DICT_6X6_1000)
    parameters = aruco.DetectorParameters_create()
    dst1 = cv2.undistort(frame, mtx, dist, None, newcameramtx)
    #保存图像
    # cv2.imwrite("./frame.jpg", dst1)

    '''
    detectMarkers(...)
        detectMarkers(image, dictionary[, corners[, ids[, parameters[, rejectedI
        mgPoints]]]]) -> corners, ids, rejectedImgPoints
    '''

    # 使用aruco.detectMarkers()函数可以检测到marker,返回ID和标志板的4个角点坐标
    corners, ids, rejectedImgPoints = aruco.detectMarkers(gray, aruco_dict, parameters=parameters)

    #print(corners)
    #print(ids)
    #f是板卡的长度
    f=0.03

    #    如果找不打id
    if ids is not None:
        #计算r和t
        rvec, tvec, _ = aruco.estimatePoseSingleMarkers(corners, f, mtx, dist)
        # 估计每个标记的姿态并返回值rvet和tvec ---不同
        # from camera coeficcients
        (rvec - tvec).any()  # get rid of that nasty numpy value array error
        #print(tvec)
        #        aruco.drawAxis(frame, mtx, dist, rvec, tvec, 0.1) #绘制轴
        #        aruco.drawDetectedMarkers(frame, corners) #在标记周围画一个正方形

        for i in range(rvec.shape[0]):
            cv2.drawFrameAxes(frame, mtx, dist, rvec[i, :, :], tvec[i, :, :], 0.05)
            aruco.drawDetectedMarkers(frame, corners)

        ###### DRAW ID #####
        cv2.putText(frame, "Id: " + str(ids), (0, 64), font, 1, (0, 255, 0), 2, cv2.LINE_AA)
        # plt.imshow(frame, aspect='auto')
        cv2.imshow("imgage",frame)

        #计算两两标记间的距离并输出

        for i in range(tvec.shape[0]):
            j = i - 1
            while j >= 0:
                print('point:' + str(ids[i]) + str(ids[j]), ',dist:' + str(np.linalg.norm(tvec[i][0] - tvec[j][0])))
                j = j - 1
        #计算各个坐标到相机的距离
        for i in range(tvec.shape[0]):
            print('point:' + str(ids[i]) + ',dist:' + str(np.linalg.norm(tvec[i][0] - [0, 0, 0])))

        h1, w1 = frame.shape[:2]

        #每个标记自己的世界坐标系坐标
        #原点和四个角
        joint_world = [[0, 0, 0],
                       [f / 2, f / 2, 0],
                       [-f / 2, f / 2, 0],
                       [-f / 2, -f / 2, 0],
                       [f / 2, -f / 2, 0]]
        joint_cam_ori = []
        joint_cam_1 = []
        joint_cam_2 = []
        joint_cam_3 = []
        joint_cam_4 = []

        #循环将各个标记的世界坐标系转为相机坐标系
        #    如果找不打id
        if ids is not None:
            for i in range(rvec.shape[0]):
                R = np.zeros((3, 3), dtype=np.float64)
                cv2.Rodrigues(rvec[i, :, :], R)
                T = tvec[i][0]
                # print("R:",R)
                # print("T:",T)
                """
                世界坐标系 -> 相机坐标系: R * (pt - T):
                joint_cam = np.dot(R, (joint_world - T).T).T
                :return:
                """
                joint_world = np.asarray(joint_world)
                joint_num = len(joint_world)
                # 世界坐标系 -> 相机坐标系
                # [R|t] world coords -> camera coords
                # joint_cam = np.zeros((joint_num, 3))  # joint camera
                # for i in range(joint_num):  # joint i
                #     joint_cam[i] = np.dot(R, joint_world[i] - T)  # R * (pt - T)
                # .T is 转置, T is translation mat
                joint_cam = np.dot(R, (joint_world).T).T + T
                joint_cam_ori.append(joint_cam[0])
                joint_cam_1.append(joint_cam[1])
                joint_cam_2.append(joint_cam[2])
                joint_cam_3.append(joint_cam[3])
                joint_cam_4.append(joint_cam[4])




        xs = [0]
        ys = [0]
        zs = [0]

        for i in range(len(joint_cam_ori)):
            xs.append(joint_cam_ori[i][0])
            ys.append(joint_cam_ori[i][1] )
            zs.append(joint_cam_ori[i][2])

        for i in range(len(joint_cam_1)):
            xs.append(joint_cam_1[i][0])
            ys.append(joint_cam_1[i][1])
            zs.append(joint_cam_1[i][2])
        # '''
        for i in range(len(joint_cam_2)):
            xs.append(joint_cam_2[i][0])
            ys.append(joint_cam_2[i][1] )
            zs.append(joint_cam_2[i][2])

        for i in range(len(joint_cam_3)):
            xs.append(joint_cam_3[i][0])
            ys.append(joint_cam_3[i][1] )
            zs.append(joint_cam_3[i][2])

        for i in range(len(joint_cam_4)):
            xs.append(joint_cam_4[i][0])
            ys.append(joint_cam_4[i][1] )
            zs.append(joint_cam_4[i][2])
        # '''

        #画各个标记平面

        ax.scatter(xs, ys, zs, zdir="z", c="#00DDAA", marker="o", s=50)

        ax.set(xlabel="X", ylabel="Y", zlabel="Z")

        for i in range(len(ids)):
            j = 1 + i
            k = len(ids)
            x, y, z = np.array([[xs[j + k], ys[j + k], zs[j + k]], [xs[j + 2 * k], ys[j + 2 * k], zs[j + 2 * k]],
                                [xs[j + 3 * k], ys[j + 3 * k], zs[j + 3 * k]],
                                [xs[j + 4 * k], ys[j + 4 * k], zs[j + 4 * k]], [xs[j + k], ys[j + k], zs[j + k]],
                                [xs[j + 2 * k], ys[j + 2 * k], zs[j + 2 * k]],
                                [xs[j + 3 * k], ys[j + 3 * k], zs[j + 3 * k]],
                                [xs[j + 4 * k], ys[j + 4 * k], zs[j + 4 * k]]]).T
            ax.plot_trisurf(x, y, z)
        #画相机原点三轴
        ax.plot([0, f], [0, 0], [0, 0], label=' ', color='blue')
        ax.plot([0, 0], [0, f], [0, 0], label=' ', color='green')
        ax.plot([0, 0], [0, 0], [0, f], label=' ', color='red')

        plt.gca().set_box_aspect((3, 2, 12))  # 当x、y、z轴范围之比为3:5:2时。
        plt.pause(0.1)
        plt.cla()
        # plt.ioff()  # 关闭画图窗口Z



    else:
        ##### DRAW "NO IDS" #####
        cv2.putText(frame, "No Ids", (0, 64), font, 1, (0, 255, 0), 2, cv2.LINE_AA)


plt.clf()  # 清除之前画的图

到了这里,关于Aruco标签定位、测距、三维位置估算 opencv应用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 双目三维测距(python)

    代码打包下载: 链接1:https://download.csdn.net/download/qq_45077760/87680186 链接2:https://github.com/up-up-up-up/Binocular-ranging(GitHub) 本文是实现某一个像素点的测距,想用yolov5实现测距的,请移步👉这篇文章 打开相机,测试双目相机两个画面是否正常显示,也可进行棋盘格拍照 同理把

    2024年02月05日
    浏览(24)
  • 基于测距的定位(RSSI定位算法原理)

    (1)测距阶段:锚节点和未知节点发送RSSI信号,利用信号衰减模型和RSSI值估计未知节点和锚节点之间的距离 (2)定位阶段:利用第一步得到的距离信息,通过三边定位、多边定位、极大似然估计、最小二乘等方法获取未知节点的位置。 (3)优化阶段:利用WSN网络拓扑信息

    2024年02月02日
    浏览(23)
  • Opencv之Aruco码的检测和姿态估计

    Aruco码是由宽黑色边框和确定其标识符(id)的内部二进制矩阵组成的正方形标记。它的黑色边框有助于其在图像中的快速检测,内部二进制编码用于识别标记和提供错误检测和纠正。单个aruco 标记就可以提供足够的对应关系,例如有四个明显的角点及内部的二进制编码,所以

    2024年02月02日
    浏览(29)
  • OpenCV应用实例 —— 二维码识别与定位

    定位二维码不仅仅是为了识别二维码;还可以通过二维码对图像进行水平纠正以及相邻区域定位。定位二维码,不仅需要图像处理相关知识,还需要分析二维码的特性,本文先从二维码的特性讲起。 二维码在设计之初就考虑到了识别问题,所以二维码有一些特征是非常明显的

    2024年02月12日
    浏览(43)
  • 机器学习与图像识别(二)—— OpenCV中aruco算法的坑

    OpenCV是一个优秀的开源视觉处理软件框架,也是计算机视觉学习道路上必须掌握的一套工具,奈何其版本兼容性上实在是一言难尽。本文主要介绍不同版本下使用aruco算法遇到的坑与排雷方法。如果你也刚好遇到类似的问题并且靠着本文的处理方式解决掉你的麻烦,不妨搜一

    2024年03月22日
    浏览(29)
  • yolov8直接调用zed相机实现三维测距(python)

    相关链接 此项目直接调用zed相机实现三维测距,无需标定,相关内容如下: 1.yolov5直接调用zed相机实现三维测距(python) 2. yolov4直接调用zed相机实现三维测距 3. Windows+YOLOV8环境配置 4.具体实现效果已在哔哩哔哩发布,点击此链接跳转 本篇博文工程源码下载(麻烦github给个星

    2024年04月11日
    浏览(31)
  • aruco二维码检测原理详解与基于opencv的代码实现(自己详细整理)

    aruco二维码检测原理讲解及基于opencv的代码和ros功能包实现 20240403 aruco二维码介绍 aruco又称为aruco标记、aruco标签、aruco二维码等,其中 CharucoBoard GridBoard AprilTag 原理相通,只是生成字典不同,而AprilTag用于机器人领域或可编程摄像头比较多,而aruco CharucoBoard GridBoard则用于AR应用

    2024年04月13日
    浏览(30)
  • 使用 ESP32 UWB DW3000进行测距和定位

    UWB 是一种类似于蓝牙或 Wi-Fi 的短距离无线通信协议。它还使用无线电波进行通信并以非常高的频率运行。顾名思义,它还使用几 GHz 的宽频谱。可以将其想象成一种雷达,可以连续扫描整个房间并像激光束一样精确锁定物体以发现其位置并传输数据。 超宽带的主要目的是位

    2024年02月05日
    浏览(26)
  • 基于RSSI测距的多边定位法(附代码与讲解视频)

    1、学习RSSI测距的原理 2、学习多边定位法对RSSI定位的实现 3、用仿真实现RSSI定位 RSSI测距方法是无线传感器网络中比较常用的一种测距方法。当无线信号在大气中传播时,由于各种因素的干扰,信号强度会随着距离的增大而衰减,这表明 在信号强度变化与传播距离之间存在

    2024年02月05日
    浏览(22)
  • 使用opencv做双目测距(相机标定+立体匹配+测距)

    最近在做双目测距,觉得有必要记录点东西,所以我的第一篇博客就这么诞生啦~ 双目测距属于立体视觉这一块,我觉得应该有很多人踩过这个坑了,但网上的资料依旧是云里雾里的,要么是理论讲一大堆,最后发现还不知道怎么做,要么就是直接代码一贴,让你懵逼。 所以

    2024年01月20日
    浏览(24)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包