我正在尝试从多个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个设备获取深度图时,我得到一个填充零的数组。我认为这是设备,但如果交换设备,它总是第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)包装器会出现相同的行为,但是为什么这是诚实的呢? / p>
有没有人使用OpenKinect / libfreenect驱动程序有类似的问题(从3个设备获取深度提要)?关于如何解决这个问题的任何想法?
答案 0 :(得分:2)
Kinect对USB的要求非常高 - 通常,主板上每个USB主机控制器只能获得一个Kinect(大多数PC和笔记本电脑都有两个)。我见过的唯一解决方案是购买PCI-E USB控制器并将第三个插入其中。
此外,如果您通过在所有Kinect上禁用RGB流来减少带宽需求,那么您可能会很幸运(我很乐意假设您没有使用它,因为没有提及)