如何使用matlab或C#在Kinect V2中将颜色流(1920x1080)转换为深度流(512x424)

时间:2017-07-01 16:52:02

标签: c# matlab visual-studio kinect resolution

支持Kinect V2颜色流的格式为:1920x1080。但kinect V2深度流格式为:512x424。现在,当我为两个传感器启动实时蒸汽时,由于分辨率不同,它们具有不同的尺寸。我不能调整它们的大小,因为我需要坐标。所以当我使用Imresize()调整大小时,坐标不匹配。我已经阅读过matlab文档。他们说硬件只分别支持这两种格式。现在我怎样才能在代码中执行此操作,以便两个流具有相同的分辨率。我尝试了两天但失败了。而且,我想通过任何过程来做到这一点,以便我拍摄第一张深度图像并根据此深度分辨率拍摄RGB或彩色图像。

我的项目是从深度图像中取出线条并将它们映射到kinect v2的RGB图像上。但解决方案并不相同。所以[x,y]坐标发生了变化。所以当我在RGB上映射它时,它与深度图像的坐标不匹配。我怎么解决呢?我以为我会改变分辨率,但在kinect V2 resoution不能改变。现在我怎么能在编码中做到。

Here is link who did like this.i want to do it in matlab or c#

3 个答案:

答案 0 :(得分:1)

在c#中,您可以使用CoordinateMapper将点从一个空间映射到另一个空间。 因此,要从深度空间映射到颜色空间,您可以连接到颜色和深度源的MultiSourceFrameArrived事件,并创建一个这样的处理程序

  private void MultiFrameReader_MultiSourceFrameArrived(object sender, MultiSourceFrameArrivedEventArgs e)
  {
        MultiSourceFrame multiSourceFrame = e.FrameReference.AcquireFrame();
        if (multiSourceFrame == null)
        {
            return;
        }


        using (ColorFrame colorFrame = multiSourceFrame.ColorFrameReference.AcquireFrame())
        {
            if (colorFrame == null) return;

            using (DepthFrame depthFrame = multiSourceFrame.DepthFrameReference.AcquireFrame())
            {
                if (colorFrame == null) return;

                using (KinectBuffer buffer = depthFrame.LockImageBuffer())
                {
                    ColorSpacePoint[] colorspacePoints = new ColorSpacePoint[depthFrame.FrameDescription.Width * depthFrame.FrameDescription.Height];
                    kinectSensor.CoordinateMapper.MapDepthFrameToColorSpaceUsingIntPtr(buffer.UnderlyingBuffer, buffer.Size, colorspacePoints);
                    //A depth point that we want the corresponding color point
                    DepthSpacePoint depthPoint = new DepthSpacePoint() { X=250, Y=250};

                    //The corrseponding color point
                    ColorSpacePoint targetPoint = colorspacePoints[(int)(depthPoint.Y * depthFrame.FrameDescription.Height + depthPoint.X)];

                }
            }
        }  
    }

colorspacePoints 数组为depthFrame中的每个像素包含colorFrame中的对应点 您还应检查targetPoint是否具有X或Y无穷大,这意味着目标空间中没有对应的像素

答案 1 :(得分:1)

对于工作示例,您可以查看VRInteraction。我将深度图像映射到RGB图像以构建3D点云。

您想要达到的目标称为注册

  1. 校准深度相机以找到深度相机投影矩阵(使用opencv)
  2. 校准RGB相机以找到RGB相机投影矩阵(使用opencv)

    - 您可以将深度图像注册为RGB图像:

  3. 映射给定深度图像的相应RGB像素。最终将得到1920x1080 RGB深度图像的分辨率。并非所有RGB像素都具有深度值,因为像素的深度较小。为此你需要

    • 使用深度相机投影矩阵
    • 计算每个深度像素的真实世界坐标()
    • 计算先前计算的现实世界纵坐标的RGB像素的坐标
    • 使用先前计算的RGB像素坐标

      在RGB图像中找到匹配的像素

      - 您可以将RGB图像注册到深度图像:

    映射给定RGB图像的相应深度像素。最终将得到512x424 RGB深度图像的分辨率。为此你需要

    • 使用深度相机投影矩阵
    • 计算每个RGB像素的真实世界纵坐标()
    • 计算先前计算的现实世界纵坐标的深度像素的坐标
    • 使用先前计算的RGB像素坐标
    • 在深度图像中找到匹配的像素

    如果您想实时实现这一目标,则需要考虑使用GPU加速。特别是如果您的深度图像包含超过30000个深度点。

    我在这件事上写了我的主人论文。如果您有更多问题,我非常乐意为您提供帮助。

答案 2 :(得分:0)

如果要覆盖两个数组(例如创建RGBD图像),则需要在Matlab中重新采样(import tkinter as tk class TestGUI(tk.Tk): def __init__(self): super().__init__() self.canvas = tk.Canvas(self) self.frame_for_content = tk.Frame(self.canvas) self.canvas_frame = self.canvas.create_window((0,0), window=self.frame_for_content, anchor=tk.NW) self.scrollbar = tk.Scrollbar(self, orient=tk.VERTICAL, command=self.canvas.yview) self.canvas.pack(side=tk.LEFT) self.scrollbar.pack(side=tk.RIGHT, fill=tk.Y) for i in range(100): tk.Label(self.frame_for_content, text="Hello World - " + str(i)).pack() self.update() bbox = self.canvas.bbox(tk.ALL) self.canvas.config(yscrollcommand=self.scrollbar.set, width=bbox[2], height=bbox[3], scrollregion=bbox) TestGUI().mainloop() )。请注意,视野的深度和颜色不同,即彩色图像的最右侧和最左侧不是深度图像的一部分,深度图像的顶部和底部不是彩色图像的一部分。

因此,你应该

  1. 从宽到深的图像裁剪彩色图像
  2. 裁剪深度图片 高度到彩色图像
  3. 使用重新采样颜色或深度图像 imresize