Skip to content

Latest commit

 

History

History
211 lines (157 loc) · 8.89 KB

File metadata and controls

211 lines (157 loc) · 8.89 KB
  1. 请问外参矩阵里 这个 -1 要怎么理解呢? 意思是 世界坐标系旋转之后, 再往下(相机坐标系的Y轴)平移 1 嘛?

这个外参矩阵是用于相机坐标系和世界坐标系的转化的,代码的情况是相机离地1米的高度架在车上,两个坐标系3轴方向相同,所以只有平移矩阵作用没有旋转矩阵。如果你自定义的世界坐标系比较特殊,就可以通过外参矩阵来实现转化。

这个是相机的外参矩阵,表示什么意思?

根据我的搜索结果¹²,相机的外参矩阵是一个4x4的矩阵,它描述了相机坐标系相对于世界坐标系的位置和方向。具体来说,外参矩阵可以分解为一个3x3的旋转矩阵和一个3x1的平移向量,如下所示:

$$ \begin{bmatrix} R & t \\ 0 & 1 \end{bmatrix} $$

其中,$R$是旋转矩阵,$t$是平移向量,0是一个1x3的零向量,1是一个标量。旋转矩阵表示了相机坐标系的三个轴(x,y,z)相对于世界坐标系的三个轴(X,Y,Z)的旋转角度。平移向量表示了相机坐标系的原点(相机光心)相对于世界坐标系的原点的位移。

给定一个世界坐标系下的三维点$P_w=[X_w, Y_w, Z_w, 1]^T$,我们可以通过外参矩阵将其变换到相机坐标系下的三维点$P_c=[X_c, Y_c, Z_c, 1]^T$,如下所示:

$$ P_c = \begin{bmatrix} R & t \\ 0 & 1 \end{bmatrix} P_w $$

或者,我们可以通过外参矩阵的逆矩阵将相机坐标系下的三维点变换到世界坐标系下的三维点,如下所示:

$$ P_w = \begin{bmatrix} R & t \\ 0 & 1 \end{bmatrix}^{-1} P_c $$

你给出的外参矩阵是:

$$ \begin{bmatrix} 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 1 \\ 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} $$

它表示了相机坐标系相对于世界坐标系的变换如下:

  • 相机坐标系的x轴与世界坐标系的z轴平行,方向相反;
  • 相机坐标系的y轴与世界坐标系的x轴平行,方向相同;
  • 相机坐标系的z轴与世界坐标系的y轴平行,方向相同;
  • 相机坐标系的原点沿着世界坐标系的y轴正方向平移了1个单位。

¹: 相机内参矩阵、外参矩阵、畸变矩阵-CSDN博客 ²: 相机校准—外参矩阵_woshicver的博客-CSDN博客

Source: Conversation with Bing, 12/5/2023 (1) 相机内参矩阵、外参矩阵、畸变矩阵-CSDN博客. https://blog.csdn.net/qq_43742590/article/details/104109103. (2) 相机校准—外参矩阵_woshicver的博客-CSDN博客. https://blog.csdn.net/woshicver/article/details/124223766. (3) 相机内参矩阵、外参矩阵、畸变矩阵-CSDN博客. https://blog.csdn.net/qq_43742590/article/details/104109103. (4) 相机校准—外参矩阵_woshicver的博客-CSDN博客. https://blog.csdn.net/woshicver/article/details/124223766. (5) GitHub - tracykim/PnPCameraLiDAR: 手动选取3D-2D点,计算激光雷达-相机的外参矩阵. https://github.com/tracykim/PnPCameraLiDAR.

https://towardsdatascience.com/what-are-intrinsic-and-extrinsic-camera-parameters-in-computer-vision-7071b72fb8ec

  1. https://zhuanlan.zhihu.com/p/593213100?utm_psn=1715425675371200512 def object_point_world_position(u, v, h, w, out_mat, in_mat): x_d = (v + w) / 2 # 目标框 左上右下 y_d = h

    fx = in_mat[0, 0] # k内参矩阵 fy = in_mat[1, 1] cam_H = 1.32

    angle_a = math.pi/10.5# 俯仰角pi/180*x

    angle_c = angle_b + angle_a

    print('angle_b', angle_b)

    #联系我:qq1309399183

    return d1, distance,x_d,y_d,H,W

计算距离的方法是利用相机模型和目标的实际尺寸来估算目标到相机的距离。具体的代码如下:

# 导入yolov5模型
model = torch.hub.load('ultralytics/yolov5', 'yolov5s', pretrained=True)

# 读取图像或视频
cap = cv2.VideoCapture('video.mp4')

# 设置相机的内外参数和畸变参数
# 这些参数可以通过相机标定得到,具体方法可以参考[这篇文章](^1^)
# 这里假设已经得到了以下参数,仅作示例,实际应用中需要根据实际情况修改
fx = 1810.0 # 焦距
cx = 960.0 # 图像中心的u坐标
cy = 540.0 # 图像中心的v坐标
k1 = -0.01 # 径向畸变系数
k2 = 0.0001 # 径向畸变系数
p1 = 0.0 # 切向畸变系数
p2 = 0.0 # 切向畸变系数
R = np.eye(3) # 旋转矩阵
T = np.array([0, 0, 0]) # 平移向量
W = 64.96 # 目标的实际宽度或高度,单位为英寸

# 定义一个函数,根据目标在图像中的位置和大小,计算目标到相机的距离
def distance(u, v, w, h):
    # u, v 是目标中心的像素坐标
    # w, h 是目标的像素宽度和高度
    # 返回值是目标到相机的距离,单位为厘米

    # 首先,校正畸变,得到目标中心在图像坐标系下的坐标
    x = (u - cx) * fx / w # 利用相似三角形的原理
    y = (v - cy) * fx / w # 利用相似三角形的原理
    r = np.sqrt(x**2 + y**2) # 计算畸变半径
    x = x * (1 + k1 * r**2 + k2 * r**4) + 2 * p1 * x * y + p2 * (r**2 + 2 * x**2) # 校正径向畸变和切向畸变
    y = y * (1 + k1 * r**2 + k2 * r**4) + p1 * (r**2 + 2 * y**2) + 2 * p2 * x * y # 校正径向畸变和切向畸变

    # 然后,利用相机模型,得到目标中心在相机坐标系下的坐标
    Xc = x / fx # 利用相似三角形的原理
    Yc = y / fx # 利用相似三角形的原理
    Zc = W * fx / w # 利用相似三角形的原理

    # 最后,利用相机外参数,得到目标中心在世界坐标系下的坐标
    Xw = R[0, 0] * Xc + R[0, 1] * Yc + R[0, 2] * Zc + T[0] # 利用旋转平移的关系
    Yw = R[1, 0] * Xc + R[1, 1] * Yc + R[1, 2] * Zc + T[1] # 利用旋转平移的关系
    Zw = R[2, 0] * Xc + R[2, 1] * Yc + R[2, 2] * Zc + T[2] # 利用旋转平移的关系

    # 计算目标到相机的距离,假设相机的高度为0
    D = np.sqrt(Xw**2 + Yw**2 + Zw**2) # 利用勾股定理
    D = D * 2.54 # 将英寸转换为厘米

    return D

# 对每一帧图像进行处理
while True:
    # 读取一帧图像
    ret, frame = cap.read()
    if not ret:
        break

    # 利用yolov5进行目标检测,得到检测结果
    results = model(frame)

    # 遍历每一个检测结果
    for result in results.xyxy[0]:
        # 获取目标的类别,位置和大小
        label = result[5]
        u = (result[0] + result[2]) / 2 # 目标中心的u坐标
        v = (result[1] + result[3]) / 2 # 目标中心的v坐标
        w = result[2] - result[0] # 目标的宽度
        h = result[3] - result[1] # 目标的高度

        # 计算目标到相机的距离
        D = distance(u, v, w, h)

        # 在图像上绘制目标的矩形框和距离信息
        cv2.rectangle(frame, (int(result[0]), int(result[1])), (int(result[2]), int(result[3])), (0, 255, 0), 2)
        cv2.putText(frame, f'{label}: {D:.2f} cm', (int(result[0]), int(result[1]) - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2)

    # 显示处理后的图像
    cv2.imshow('frame', frame)
    cv2.waitKey(1)

# 释放资源
cap.release()
cv2.destroyAllWindows()

这是一个基于yolov5的目标检测和单目测距的示例代码,仅供参考。具体的参数和细节需要根据实际情况进行调整。更多的相关资料和代码可以参考以下链接:

Source: Conversation with Bing, 2023/12/5 (1) YOLOv5+单目测距(python)_yolov5测距-CSDN博客. https://blog.csdn.net/qq_45077760/article/details/130261489. (2) 基于yolov5的目标检测和单目测距_yolov5测距-CSDN博客. https://blog.csdn.net/XiaoLanZi7k7k/article/details/126822650. (3) WangRongsheng/yolov5-obj-distance-measure - GitHub. https://github.com/WangRongsheng/yolov5-obj-distance-measure. (4) liuchangji/simple-distance-measure-by-camera - GitHub. https://github.com/liuchangji/simple-distance-measure-by-camera. (5) 单目测距(yolo目标检测+标定+测距代码) - 知乎专栏. https://zhuanlan.zhihu.com/p/593213100. (6) undefined. https://download.csdn.net/download/qq_45077760/87708260. (7) undefined. https://github.com/up-up-up-up/yolov5_Monocular_ranging. (8) undefined. https://blog.csdn.net/qq_45077760/category_12312107.html. (9) undefined. https://www.bilibili.com/video/BV1oh411a71G.

  1. link https://pyimagesearch.com/2015/01/19/find-distance-camera-objectmarker-using-python-opencv/

  2. https://docs.opencv.org/4.x/dc/dbb/tutorial_py_calibration.html

  3. https://learnopencv.com/camera-calibration-using-opencv/

  4. import:https://learnopencv.com/geometry-of-image-formation/ formula https://learnopencv.com/understanding-lens-distortion/

  5. 双目测距项目:https://github.com/iamfaith/yolov5_ceju https://blog.csdn.net/qq_45077760/article/details/124731530?spm=1001.2014.3001.5502 双目测距csdn

  6. calibration: https://github.com/paulmelis/opencv-camera-calibration/tree/main https://github.com/jagracar/OpenCV-python-tests