如何获取相机到 OpenCV ArUco 标记的距离

问题描述 投票:0回答:2

如何使用 OpenCV 中的 ArUco 框架来获取相机到 ArUco 标记的距离?

python opencv aruco
2个回答
5
投票

需要执行几个步骤才能确定相机到 ArUco 标记的距离。

校准相机

这一步是最重要的。如果您跳过这一步骤,进一步描述的步骤中的所有结果都将不准确。

您将使用的相机需要校准。重要的是,在此步骤中使用相机的方式与使用相机进行标记检测的方式相同。所以相同的分辨率、焦距(相同的镜头)。

有很多好的指南,所以我将跳过此任务以专注于主要问题。 可能的指南: https://docs.opencv.org/master/da/d13/tutorial_aruco_calibration.html https://mecaruco2.readthedocs.io/en/latest/notebooks_rst/Aruco/Projet+calibration-Paul.html

接收相机到 ArUco 标记的距离

此步骤需要参数来校正上一步中的失真。在接下来的示例中,我将调用cameraMatrix

mtx
和distCoeffs
dist

  1. 确保调整 ArUco 检测所需的所有参数。

我不会解释简单的标记检测需要什么,因为那里有很多好的指南。

dictionary = cv.aruco.Dictionary_get(cv.aruco.DICT_4X4_50)
parameters = cv.aruco.DetectorParameters_create()
  1. 在您的相框上搜索制造商

frame
将是包含标记的框架

(corners, ids, rejected) = cv.aruco.detectMarkers(frame, dictionary, parameters=parameters)
  1. 估计标记的姿势

您将需要要查找的标记的大小。所以它的实际尺寸打印在纸上。测量它,因为我们将需要它。您使用什么测量单位并不重要。但请注意,我们收到的距离结果将是相同的单位。我在这个例子中使用了 CM

markerSizeInCM = 15.9
rvec , tvec, _ = aruco.estimatePoseSingleMarkers(corners, markerSizeInCM, mtx, dist)
  1. 读出距离

我们现在有了标记相对于相机的旋转向量 (

rvec
) 和平移向量 (
tvec
)。查看来源:OpenCV

平移向量与我们在步骤 3 中提供的实际标记大小相同。其格式为

[x,y,z]
,即标记在 3D 空间中的位置。

我们现在只需要从

z
读出
tvec
,这将是我们在步骤 3 中提供的同一测量单位中从相机到标记中心的距离。


0
投票

我认为之前的答案部分不正确。平移向量是相机坐标系中的坐标。所以从相机到aruco标记的距离不仅仅是

tvec
的z坐标,它是
tvec

的欧几里得范数
import cv2
import numpy as np

img = cv2.imread('img.png')  # replace with your path to image
# Replace with your camera matrix
camera_matrix = np.array([
    [580.77518, 0.0, 724.75002], 
    [0.0, 580.77518, 570.98956], 
    [0.0, 0.0, 1.0]
])
# Replace with your distortion coefficients
dist_coeffs = np.array([
    0.927077, 0.141438, 0.000196, -8.7e-05, 
    0.001695, 1.257216, 0.354688, 0.015954
])
# Replace with your aruco dictionary
dictionary = cv2.aruco.Dictionary_get(cv2.aruco.DICT_4X4_50)
parameters = cv2.aruco.DetectorParameters_create()
marker_size = 0.8  # marker size in some units

corners, ids, _ = cv2.aruco.detectMarkers(
    img, dictionary, parameters=parameters
)
rvec, tvec, _ = cv2.aruco.estimatePoseSingleMarkers(
    corners, marker_size, camera_matrix, dist_coeffs 
)
# The distance will be in the same units as marker size
distance = np.linalg.norm(tvec[0][0])

正如@Simon提到的,你需要首先校准相机以获得相机矩阵和畸变系数

© www.soinside.com 2019 - 2024. All rights reserved.