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 知识体系总览

下面这张图,是我自己总结的选型逻辑。你照着走,基本不会错。

深度相机选型决策树 你的应用场景? 桌面级/手势识别 全身动捕/空间定位 移动端/户外应用 Intel RealSense D435 0.3-3m / 开源SDK Microsoft Kinect Azure 0.5-5m / 高精度 Apple LiDAR + ARKit 便携 / 户外可用 注意事项 • RealSense在强光下表现差,室内用最佳 • Kinect Azure需要USB 3.0供电,笔记本可能带不动 • Apple LiDAR深度分辨率低,不适合精细建模 • 所有深度相机在黑色/反光物体上都会失效

3.6 我的选型建议

说了这么多,给个总结吧。

  • 预算有限、做手势识别:RealSense D435。开源社区活跃,遇到问题好解决。我第一个动捕项目就是用它做的。
  • 做全身动捕、精度要求高:Kinect Azure。虽然重了点,但深度数据稳定,SDK功能全。
  • 移动端、户外场景:Apple LiDAR。没得选,只有它能在阳光下正常工作。

最后提醒一句:不管你选哪个,先买回来试两天。参数再好看,不如实际跑一遍。我见过太多人看了一堆评测,买回来发现不适合自己的场景。

专注资料整理