3、深度相机选型与SDK:Intel RealSense、Microsoft Kinect、Apple LiDAR
做姿态估计和动作捕捉,第一步就是选相机。这步要是走错了,后面全白搭。我这些年折腾过不少深度相机,踩过的坑能写本书。今天咱们就聊聊市面上最主流的三个方案:Intel RealSense、Microsoft Kinect、还有Apple LiDAR。
说白了,没有完美的相机。只有最适合你项目的相机。你想想看,做手势识别和做全身动捕,对设备的要求能一样吗?
3.1 三大主流方案对比
先给个总览,心里有个底。
| 特性 | Intel RealSense D435 | Microsoft Kinect Azure | Apple LiDAR (iPad Pro) |
|---|---|---|---|
| 技术原理 | 主动立体红外 | ToF (Time of Flight) | dToF (直接飞行时间) |
| 最佳工作距离 | 0.3m - 3m | 0.5m - 5m | 0.5m - 5m |
| 深度分辨率 | 1280x720 @ 30fps | 1024x1024 @ 30fps | 256x192 @ 60fps |
| RGB分辨率 | 1920x1080 @ 30fps | 3840x2160 @ 30fps | 1200万像素 |
| 户外可用性 | 一般(受强光影响) | 较好 | 优秀 |
| SDK成熟度 | librealsense (开源) | Azure Kinect SDK | ARKit (iOS原生) |
| 价格 | 约300-400美元 | 约400-500美元 | 需搭配iPad Pro |
我的建议:如果你做桌面级手势识别,RealSense D435性价比最高。如果是全身动捕,Kinect Azure更稳。移动端项目,没得选,只能用Apple LiDAR。
3.2 Intel RealSense 与 librealsense
RealSense是我用得最多的。为什么?因为它SDK开源,社区活跃,遇到问题好查资料。
我记得第一次用D435的时候,插上USB线,Windows直接认出来了。但别高兴太早——你得装SDK才能拿到深度数据。
安装 librealsense
Windows下最简单,直接去GitHub下载安装包。Linux下稍微麻烦点,要编译源码。我个人习惯用Ubuntu 20.04,命令如下:
# 1. 注册密钥
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-key F6E65AC044F831AC80A06380C8B3A55A6F3EFCDE
# 2. 添加仓库
sudo add-apt-repository "deb https://librealsense.intel.com/Debian/apt-repo $(lsb_release -cs) main" -u
# 3. 安装
sudo apt-get install librealsense2-dkms
sudo apt-get install librealsense2-utils
# 4. 验证
realsense-viewer
小技巧:装完后运行realsense-viewer,如果能看到深度图,说明驱动没问题。我曾经遇到过一次,装完死活不出图,最后发现是USB3.0线的问题——换根线就好了。
基础API调用
librealsense的API设计得很清爽。核心就几个类:pipeline、config、frameset。看代码:
#include <librealsense2/rs.hpp>
int main() {
// 创建pipeline
rs2::pipeline pipe;
rs2::config cfg;
// 配置深度流和彩色流
cfg.enable_stream(RS2_STREAM_DEPTH, 640, 480, RS2_FORMAT_Z16, 30);
cfg.enable_stream(RS2_STREAM_COLOR, 640, 480, RS2_FORMAT_BGR8, 30);
// 启动pipeline
pipe.start(cfg);
while (true) {
// 等待一帧数据
rs2::frameset frames = pipe.wait_for_frames();
// 获取深度帧和彩色帧
rs2::depth_frame depth = frames.get_depth_frame();
rs2::video_frame color = frames.get_color_frame();
// 获取深度值(单位:毫米)
uint16_t depth_value = depth.get_distance(320, 240) * 1000;
// 这里可以处理你的姿态估计逻辑
}
return 0;
}
这段代码看着简单,但够用了。你想想看,核心就是三步:创建pipeline、配置流、循环取帧。嗯,这里要注意,wait_for_frames()是阻塞的,如果你的处理逻辑很慢,帧率会下降。
3.3 Microsoft Kinect Azure
Kinect Azure是微软的第三代深度相机。说实话,它比RealSense重不少,但精度确实高。我在做全身动捕项目时,首选就是它。
安装Azure Kinect SDK
Windows下直接装MSI安装包。Linux下稍微折腾点:
# 添加微软仓库
curl -sSL https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add -
sudo apt-add-repository https://packages.microsoft.com/ubuntu/20.04/prod
sudo apt-get update
# 安装SDK
sudo apt-get install k4a-tools
sudo apt-get install libk4a1.4-dev
# 验证
k4aviewer
避坑指南:我曾经在Ubuntu 22.04上装Kinect SDK,折腾了两天。最后发现官方只支持到20.04。如果你用新系统,建议用Docker或者直接换Windows。
基础API调用
Kinect的API比RealSense复杂一些,但逻辑类似:
#include <k4a/k4a.h>
int main() {
k4a_device_t device = NULL;
k4a_device_open(0, &device);
k4a_device_configuration_t config = K4A_DEVICE_CONFIG_INIT_DISABLE_ALL;
config.camera_fps = K4A_FRAMES_PER_SECOND_30;
config.depth_mode = K4A_DEPTH_MODE_NFOV_UNBINNED;
config.color_format = K4A_IMAGE_FORMAT_COLOR_BGRA32;
config.color_resolution = K4A_COLOR_RESOLUTION_1080P;
k4a_device_start_cameras(device, &config);
k4a_capture_t capture;
while (true) {
if (k4a_device_get_capture(device, &capture, 1000) == K4A_WAIT_RESULT_SUCCEEDED) {
k4a_image_t depth_image = k4a_capture_get_depth_image(capture);
// 获取深度数据
uint16_t* depth_data = (uint16_t*)k4a_image_get_buffer(depth_image);
int width = k4a_image_get_width_pixels(depth_image);
int height = k4a_image_get_height_pixels(depth_image);
// 处理你的姿态估计
k4a_image_release(depth_image);
k4a_capture_release(capture);
}
}
k4a_device_stop_cameras(device);
k4a_device_close(device);
return 0;
}
这里有个坑——Kinect的深度图和彩色图是不同步的。你需要用k4a_calibration_t来做对齐。我刚开始做的时候没注意,结果深度和彩色对不上,姿态估计全歪了。
3.4 Apple LiDAR 与 ARKit
Apple LiDAR是近两年才火起来的。它集成在iPad Pro和iPhone Pro上,便携性无敌。但说实话,深度分辨率低得可怜——只有256x192。
为什么会这样?因为dToF的原理决定了它更擅长测距,而不是精细建模。但做人体姿态估计,这个分辨率其实够用。
ARKit基础调用
ARKit是iOS原生框架,用Swift写起来很舒服:
import ARKit
class ViewController: UIViewController, ARSessionDelegate {
let session = ARSession()
override func viewDidLoad() {
super.viewDidLoad()
session.delegate = self
let config = ARWorldTrackingConfiguration()
config.frameSemantics = .sceneDepth
session.run(config)
}
func session(_ session: ARSession, didUpdate frame: ARFrame) {
guard let depthData = frame.sceneDepth else { return }
// 获取深度图
let depthMap = depthData.depthMap
// 获取深度值(单位:米)
let width = CVPixelBufferGetWidth(depthMap)
let height = CVPixelBufferGetHeight(depthMap)
CVPixelBufferLockBaseAddress(depthMap, .readOnly)
let baseAddress = CVPixelBufferGetBaseAddress(depthMap)
// 这里可以处理你的姿态估计
CVPixelBufferUnlockBaseAddress(depthMap, .readOnly)
}
}
小技巧:ARKit的深度数据是16位浮点数,单位是米。记得转成毫米再处理,不然精度不够。我习惯乘以1000后转成uint16。
3.5 知识体系总览
下面这张图,是我自己总结的选型逻辑。你照着走,基本不会错。
3.6 我的选型建议
说了这么多,给个总结吧。
- 预算有限、做手势识别:RealSense D435。开源社区活跃,遇到问题好解决。我第一个动捕项目就是用它做的。
- 做全身动捕、精度要求高:Kinect Azure。虽然重了点,但深度数据稳定,SDK功能全。
- 移动端、户外场景:Apple LiDAR。没得选,只有它能在阳光下正常工作。
最后提醒一句:不管你选哪个,先买回来试两天。参数再好看,不如实际跑一遍。我见过太多人看了一堆评测,买回来发现不适合自己的场景。