【问题标题】:Problems reading data from 3 Kinect cameras从 3 个 Kinect 摄像头读取数据时出现问题
【发布时间】:2012-02-11 17:44:59
【问题描述】:

我正在尝试从多个 Kinect 传感器(目前为 3 个)读取数据,但当设备超过 2 个时出现问题。

我正在使用Daniel Shiffman's OpenKinect Processing wrapper,稍作修改,以便可以打开多个设备实例。 2 台设备一切正常。问题是当我使用 3 时。一个 Kinect 直接连接到可用的两个 USB 端口之一,另外两个插入 USB 2.0 集线器(有自己的电源适配器)。

设备全部初始化成功:

org.openkinect.Device@1deeb40 initialized
org.openkinect.Device@2c35e initialized
org.openkinect.Device@1cffeb4 initialized

问题是当我尝试从第 3 个设备获取深度图时,我得到一个用零填充的数组。我认为是设备,但如果交换设备,则始终是第三个(最后连接的设备)呈现此行为。

到目前为止,这是我的代码:

package librarytests;

import org.openkinect.Context;
import org.openkinect.processing.Kinect;

import processing.core.PApplet;
import processing.core.PVector;

public class PointCloudxN extends PApplet {

    // Kinect Library object
    int numKinects;// = 3;
    Kinect[] kinects;
    int[] colours = {color(192,0,0),color(0,192,0),color(0,0,192),color(192,192,0),color(0,192,192),color(192,0,192)};

    // Size of kinect image
    int w = 640;
    int h = 480;

    // We'll use a lookup table so that we don't have to repeat the math over and over
    float[] depthLookUp = new float[2048];

    // Scale up by 200
    float factor = 200;

    public void setup() {
        size(800,600,P3D);
        numKinects = Context.getContext().devices();
        kinects = new Kinect[numKinects];
        for (int i = 0; i < numKinects; i++) {
            kinects[i] = new Kinect(this);
            kinects[i].start(i);
            kinects[i].enableDepth(true);
            kinects[i].processDepthImage(false);
        }
        // Lookup table for all possible depth values (0 - 2047)
        for (int i = 0; i < depthLookUp.length; i++) {
            depthLookUp[i] = rawDepthToMeters(i);
        }
    }

    public void draw() {
        background(0);

        translate(width/2,height/2,-50);
        rotateY(map(mouseX,0,width,-PI,PI));
        rotateX(map(mouseY,0,height,-PI,PI));
        int skip = 4;//res
        //*
        for (int i = 0; i < numKinects; i++) {
            Kinect kinect = kinects[i];
            int[] depth = kinect.getRawDepth(); 
            //if(frameCount % 60 == 0 && i == 2) println(depth);
            if (depth != null) {

                // Translate and rotate

                for(int x=0; x<w; x+=skip) {
                    for(int y=0; y<h; y+=skip) {
                        int offset = x+y*w;

                        // Convert kinect data to world xyz coordinate
                        int rawDepth = depth[offset];
                        PVector v = depthToWorld(x,y,rawDepth);

                        stroke(colours[i]);
                        // Draw a point
                        point(v.x*factor,v.y*factor,factor-v.z*factor);

                    }
                }
            }
        }


        //*/
    }

    public void stop() {
        for (int i = 0; i < numKinects; i++) kinects[i].quit();
        super.stop();
    }

    public static void main(String _args[]) {
        PApplet.main(new String[] { librarytests.PointCloudxN.class.getName() });
    }

    // These functions come from: http://graphics.stanford.edu/~mdfisher/Kinect.html
    float rawDepthToMeters(int depthValue) {
        if (depthValue < 2047)  {
            return (float)(1.0 / ((double)(depthValue) * -0.0030711016 + 3.3309495161));
        }
        return 0.0f;
    }

    PVector depthToWorld(int x, int y, int depthValue) {

        final double fx_d = 1.0 / 5.9421434211923247e+02;
        final double fy_d = 1.0 / 5.9104053696870778e+02;
        final double cx_d = 3.3930780975300314e+02;
        final double cy_d = 2.4273913761751615e+02;

        PVector result = new PVector();
        double depth =  depthLookUp[depthValue];//rawDepthToMeters(depthValue);
        result.x = (float)((x - cx_d) * depth * fx_d);
        result.y = (float)((y - cy_d) * depth * fy_d);
        result.z = (float)(depth);
        return result;
    }








}

我对 Daniel 的 Kinect 类所做的唯一重大更改是添加了一个额外的 start() 方法:

public void start(int id) {

        context = Context.getContext();
        if(context.devices() < 1)
        {
            System.out.println("No Kinect devices found.");
        }
        device = context.getDevice(id);
        //device.acceleration(this);

        device.acceleration(new Acceleration()
        {
            void Acceleration(){
                System.out.println("new Acceleration implementation");
            }
            public void direction(float x, float y, float z)
            {
                System.out.printf("Acceleration: %f %f %f\n", x ,y ,z);
            }
        });

        kimg = new RGBImage(p5parent);
        dimg = new DepthImage(p5parent);
        running = true;

        super.start();
    }

我也尝试过使用 MaxMSP/Jitter 和 jit.freenect external,我得到了相同的行为:我可以获得 2 个深度图,但第 3 个没有更新。

所以这似乎是一个与驱动程序相关的问题,而不是包装器,因为使用 2 个不同的包装器到 libfreenect(Java/Processing 和 Max)存在相同的行为,但我不知道为什么这恰好是诚实的。

有没有人在使用 OpenKinect/libfreenect 驱动程序时遇到过类似的问题(从 3 个设备获取深度馈送)?关于如何解决这个问题的任何想法?

【问题讨论】:

    标签: java processing kinect


    【解决方案1】:

    Kinect 对 USB 要求极高 - 通常,您的主板上的每个 USB 主机控制器只能安装一个 Kinect(大多数 PC 和笔记本电脑都有两个)。我见过的唯一解决方案是购买一个 PCI-E USB 控制器并将第三个插入其中。

    此外,如果您通过禁用所有 Kinect 上的 RGB 流来降低带宽要求,您可能会很幸运(我很高兴地假设您没有使用它,因为它没有被提及)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-11-22
      • 1970-01-01
      • 1970-01-01
      • 2021-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多