You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#结合Kinect v2:获取与深度像素匹配的RGB值

Kinect v2 + C#:生成512×424的深度+RGBA融合图像数组

我之前在做Kinect v2相关的C#项目时,刚好实现过类似需求——要输出一个512×424分辨率的数组,每个元素同时包含对应位置的深度值和RGBA颜色信息。这里给你梳理一下完整的实现思路和代码:

核心思路

Kinect v2的深度帧原生分辨率就是512×424,但彩色帧默认是1920×1080,所以不能直接用原始彩色数组和深度数组拼接,必须通过Kinect的坐标映射功能,把彩色像素精准对应到深度帧的每个像素位置上,这样才能得到一一对应的融合数据。

实现步骤与代码示例

1. 初始化必要的对象

首先要初始化KinectSensor、MultiSourceFrameReader,还有坐标映射器(CoordinateMapper):

private KinectSensor _kinectSensor;
private MultiSourceFrameReader _multiSourceReader;
private CoordinateMapper _coordinateMapper;
private ushort[] _depthData;
private byte[] _colorData;

// 自定义结构体存储每个像素的深度+RGBA信息
public struct DepthRgbaPixel 
{ 
    public ushort Depth; 
    public byte R; 
    public byte G; 
    public byte B; 
    public byte A; 
}
private DepthRgbaPixel[] _mergedDepthRgbaData; // 最终的512×424数组

// 初始化方法
private void InitializeKinect()
{
    _kinectSensor = KinectSensor.GetDefault();
    if (_kinectSensor != null)
    {
        // 指定读取深度帧和彩色帧
        _multiSourceReader = _kinectSensor.OpenMultiSourceFrameReader(
            FrameSourceTypes.Depth | FrameSourceTypes.Color);
        _multiSourceReader.MultiSourceFrameArrived += MultiSourceFrameArrived;
        
        _coordinateMapper = _kinectSensor.CoordinateMapper;
        
        // 初始化数组:深度数组是512×424的ushort数组;彩色数组是1920×1080×4的RGBA数组
        _depthData = new ushort[_kinectSensor.DepthFrameSource.FrameDescription.LengthInPixels];
        _colorData = new byte[_kinectSensor.ColorFrameSource.FrameDescription.LengthInPixels * 4];
        // 初始化融合数组
        _mergedDepthRgbaData = new DepthRgbaPixel[512 * 424];
        
        _kinectSensor.Open();
    }
}

2. 处理帧到达事件

在MultiSourceFrameArrived事件中提取帧数据,并完成坐标映射:

private void MultiSourceFrameArrived(object sender, MultiSourceFrameArrivedEventArgs e)
{
    var reference = e.FrameReference.AcquireFrame();
    
    // 提取深度帧
    using (var depthFrame = reference.DepthFrameReference.AcquireFrame())
    // 提取彩色帧
    using (var colorFrame = reference.ColorFrameReference.AcquireFrame())
    {
        if (depthFrame != null && colorFrame != null)
        {
            // 获取深度数据
            depthFrame.CopyFrameDataToArray(_depthData);
            
            // 将彩色帧转换为RGBA格式并复制到数组(原始彩色帧是YUV422,需要转换)
            colorFrame.CopyConvertedFrameDataToArray(_colorData, ColorImageFormat.Rgba);
            
            // 获取深度帧的描述
            var depthDesc = depthFrame.FrameDescription;
            int depthWidth = depthDesc.Width; // 512
            int depthHeight = depthDesc.Height; // 424
            int colorWidth = _kinectSensor.ColorFrameSource.FrameDescription.Width; // 1920
            
            // 准备坐标映射:获取每个深度像素对应的彩色空间坐标
            ColorSpacePoint[] colorSpacePoints = new ColorSpacePoint[depthWidth * depthHeight];
            _coordinateMapper.MapDepthFrameToColorSpace(_depthData, colorSpacePoints);
            
            // 生成融合数组
            for (int y = 0; y < depthHeight; y++)
            {
                for (int x = 0; x < depthWidth; x++)
                {
                    int depthIndex = y * depthWidth + x;
                    ColorSpacePoint colorPoint = colorSpacePoints[depthIndex];
                    
                    // 检查彩色坐标是否在有效范围内
                    if (colorPoint.X >= 0 && colorPoint.X < colorWidth &&
                        colorPoint.Y >= 0 && colorPoint.Y < _kinectSensor.ColorFrameSource.FrameDescription.Height)
                    {
                        // 计算彩色数组的索引(RGBA格式,每个像素4字节)
                        int colorIndex = (int)(colorPoint.Y * colorWidth + colorPoint.X) * 4;
                        
                        // 填充融合像素数据
                        _mergedDepthRgbaData[depthIndex] = new DepthRgbaPixel
                        {
                            Depth = _depthData[depthIndex],
                            R = _colorData[colorIndex],
                            G = _colorData[colorIndex + 1],
                            B = _colorData[colorIndex + 2],
                            A = _colorData[colorIndex + 3]
                        };
                    }
                    else
                    {
                        // 如果坐标无效,设置默认颜色(黑色不透明)
                        _mergedDepthRgbaData[depthIndex] = new DepthRgbaPixel
                        {
                            Depth = _depthData[depthIndex],
                            R = 0,
                            G = 0,
                            B = 0,
                            A = 255
                        };
                    }
                }
            }
            
            // 这里就可以使用_mergedDepthRgbaData了,它是512×424的融合数据数组
        }
    }
}

关键注意事项

  • 坐标映射的必要性:直接拿原始1920×1080的彩色数组和512×424的深度数组是无法一一对应的,必须通过CoordinateMapper.MapDepthFrameToColorSpace方法把深度像素的坐标转换到彩色空间,才能拿到对应的颜色值。
  • 帧资源释放:一定要用using语句包裹获取到的DepthFrame和ColorFrame,避免资源泄漏。
  • 边界检查:转换后的彩色坐标可能会超出彩色帧的范围,必须做有效性判断,否则会出现数组越界错误。
  • 数组大小计算:深度数组的大小是512*424(每个元素是ushort),彩色RGBA数组的大小是1920*1080*4(每个像素4字节),融合数组的大小根据你的存储方式调整。

内容的提问来源于stack exchange,提问作者oRole

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:40:23