DepthAI v2 has been superseded by DepthAI v3. You are viewing legacy documentation.
此页面由 AI 自动翻译。查看英文原版
DepthAI 教程
DepthAI API 参考

本页目录

  • 演示
  • 设置
  • 源代码
  • 流水线

立体深度自定义网格

本示例展示了如何将自定义网格加载到设备中并用于深度计算。 在此示例中,网格文件是从相机校准数据生成的,但您也可以使用 您自己的网格文件。默认情况下,StereoDepth 将使用与 def getMesh() 内部相同的逻辑来计算 当水平视场角大于 90° 时生成网格文件。您也可以强制计算网格,方法是:
Python
1stereo = pipeline.create(dai.node.StereoDepth)
2# 启用网格计算以校正畸变:
3stereo.enableDistortionCorrection(True)
StereoDepth 节点还允许您直接从文件路径加载网格文件:
Python
1stereo = pipeline.create(dai.node.StereoDepth)
2stereo.loadMeshFiles('path/to/left_mesh', 'path/to/right_mesh')

演示

https://github.com/luxonis/depthai-python/assets/18037362/f2031bd4-0748-4a06-abb1-b52e9a17134e
在上图中,您可以看到校正后的帧的视场角不如原始帧宽, 这是因为应用了畸变校正(在此情况下通过自定义网格文件),因此 可以正确执行视差匹配。

设置

请运行 安装脚本 以下载所有必需的依赖项。请注意,此脚本必须在 git 上下文中运行,因此您必须先下载 depthai-python 存储库,然后运行脚本
Command Line
1git clone https://github.com/luxonis/depthai-python.git
2cd depthai-python/examples
3python3 install_requirements.py
有关更多信息,请遵循 安装指南

源代码

Python

Python
GitHub
1#!/usr/bin/env python3
2
3import cv2
4import numpy as np
5import depthai as dai
6import argparse
7
8parser = argparse.ArgumentParser()
9parser.add_argument("-res", "--resolution", type=str, default="720",
10    help="Sets the resolution on mono cameras. Options: 800 | 720 | 400")
11parser.add_argument("-md", "--mesh_dir", type=str, default=None,
12    help="Output directory for mesh files. If not specified mesh files won't be saved")
13parser.add_argument("-lm", "--load_mesh", default=False, action="store_true",
14    help="Read camera intrinsics, generate mesh files and load them into the stereo node.")
15args = parser.parse_args()
16
17meshDirectory = args.mesh_dir  # Output dir for mesh files
18generateMesh = args.load_mesh  # Load mesh files
19RES_MAP = {
20    '800': {'w': 1280, 'h': 800, 'res': dai.MonoCameraProperties.SensorResolution.THE_800_P },
21    '720': {'w': 1280, 'h': 720, 'res': dai.MonoCameraProperties.SensorResolution.THE_720_P },
22    '400': {'w': 640, 'h': 400, 'res': dai.MonoCameraProperties.SensorResolution.THE_400_P }
23}
24if args.resolution not in RES_MAP:
25    exit("Unsupported resolution!")
26
27resolution = RES_MAP[args.resolution]
28
29def getMesh(calibData):
30    M1 = np.array(calibData.getCameraIntrinsics(dai.CameraBoardSocket.CAM_B, resolution['w'], resolution['h']))
31    d1 = np.array(calibData.getDistortionCoefficients(dai.CameraBoardSocket.CAM_B))
32    R1 = np.array(calibData.getStereoLeftRectificationRotation())
33    M2 = np.array(calibData.getCameraIntrinsics(dai.CameraBoardSocket.CAM_C, resolution['w'], resolution['h']))
34    d2 = np.array(calibData.getDistortionCoefficients(dai.CameraBoardSocket.CAM_C))
35    R2 = np.array(calibData.getStereoRightRectificationRotation())
36    mapXL, mapYL = cv2.initUndistortRectifyMap(M1, d1, R1, M2, (resolution['w'], resolution['h']), cv2.CV_32FC1)
37    mapXR, mapYR = cv2.initUndistortRectifyMap(M2, d2, R2, M2, (resolution['w'], resolution['h']), cv2.CV_32FC1)
38
39    meshCellSize = 16
40    meshLeft = []
41    meshRight = []
42
43    for y in range(mapXL.shape[0] + 1):
44        if y % meshCellSize == 0:
45            rowLeft = []
46            rowRight = []
47            for x in range(mapXL.shape[1] + 1):
48                if x % meshCellSize == 0:
49                    if y == mapXL.shape[0] and x == mapXL.shape[1]:
50                        rowLeft.append(mapYL[y - 1, x - 1])
51                        rowLeft.append(mapXL[y - 1, x - 1])
52                        rowRight.append(mapYR[y - 1, x - 1])
53                        rowRight.append(mapXR[y - 1, x - 1])
54                    elif y == mapXL.shape[0]:
55                        rowLeft.append(mapYL[y - 1, x])
56                        rowLeft.append(mapXL[y - 1, x])
57                        rowRight.append(mapYR[y - 1, x])
58                        rowRight.append(mapXR[y - 1, x])
59                    elif x == mapXL.shape[1]:
60                        rowLeft.append(mapYL[y, x - 1])
61                        rowLeft.append(mapXL[y, x - 1])
62                        rowRight.append(mapYR[y, x - 1])
63                        rowRight.append(mapXR[y, x - 1])
64                    else:
65                        rowLeft.append(mapYL[y, x])
66                        rowLeft.append(mapXL[y, x])
67                        rowRight.append(mapYR[y, x])
68                        rowRight.append(mapXR[y, x])
69            if (mapXL.shape[1] % meshCellSize) % 2 != 0:
70                rowLeft.append(0)
71                rowLeft.append(0)
72                rowRight.append(0)
73                rowRight.append(0)
74
75            meshLeft.append(rowLeft)
76            meshRight.append(rowRight)
77
78    meshLeft = np.array(meshLeft)
79    meshRight = np.array(meshRight)
80
81    return meshLeft, meshRight
82
83def saveMeshFiles(meshLeft, meshRight, outputPath):
84    print("Saving mesh to:", outputPath)
85    meshLeft.tofile(outputPath + "/left_mesh.calib")
86    meshRight.tofile(outputPath + "/right_mesh.calib")
87
88
89def create_pipeline(device: dai.Device) -> dai.Pipeline:
90    calibData = device.readCalibration()
91    print("Creating Stereo Depth pipeline")
92    pipeline = dai.Pipeline()
93
94    camLeft = pipeline.create(dai.node.MonoCamera)
95    camLeft.setBoardSocket(dai.CameraBoardSocket.LEFT)
96
97    camRight = pipeline.create(dai.node.MonoCamera)
98    camRight.setBoardSocket(dai.CameraBoardSocket.RIGHT)
99
100    xoutRight = pipeline.create(dai.node.XLinkOut)
101    xoutRight.setStreamName("right")
102    camRight.out.link(xoutRight.input)
103
104    for monoCam in (camLeft, camRight):  # Common config
105        monoCam.setResolution(resolution['res'])
106        # monoCam.setFps(20.0)
107
108    stereo = pipeline.create(dai.node.StereoDepth)
109    camLeft.out.link(stereo.left)
110    camRight.out.link(stereo.right)
111    stereo.setDefaultProfilePreset(dai.node.StereoDepth.PresetMode.HIGH_DENSITY)
112    stereo.setRectifyEdgeFillColor(0)  # Black, to better see the cutout
113    stereo.setLeftRightCheck(True)
114    stereo.setExtendedDisparity(True)
115
116    
117
118
119    xoutDisparity = pipeline.create(dai.node.XLinkOut)
120    xoutDisparity.setStreamName("disparity")
121    stereo.disparity.link(xoutDisparity.input)
122
123    xoutRectifRight = pipeline.create(dai.node.XLinkOut)
124    xoutRectifRight.setStreamName("rectifiedRight")
125    stereo.rectifiedRight.link(xoutRectifRight.input)
126
127    # Create custom meshes from calibration data. Here you could also
128    # load your own mesh files, or generate them in any other way.
129    leftMesh, rightMesh = getMesh(calibData)
130    if generateMesh:
131        meshLeft = list(leftMesh.tobytes())
132        meshRight = list(rightMesh.tobytes())
133        # Load mesh data to the StereoDepth node
134        stereo.loadMeshData(meshLeft, meshRight)
135
136    if meshDirectory is not None:
137        saveMeshFiles(leftMesh, rightMesh, meshDirectory)
138    return pipeline
139
140with dai.Device() as device:
141    device.startPipeline(create_pipeline(device))
142
143    # Create a receive queue for each stream
144    qList = [device.getOutputQueue(stream, 8, blocking=False) for stream in ['right', 'rectifiedRight', 'disparity']]
145
146    while True:
147        for q in qList:
148            name = q.getName()
149            frame = q.get().getCvFrame()
150            cv2.imshow(name, frame)
151        if cv2.waitKey(1) == ord("q"):
152            break

流水线

需要帮助?

请前往 Discussion Forum 获取技术支持或提出您可能有的任何其他问题。