Я пытаюсь прочитать данные с нескольких датчиков Kinect (3 на данный момент) и имеет проблемы, когда есть более двух устройств.Проблемы с чтением данных с 3 камер Kinect
Я использую Daniel Shiffman's OpenKinect Processing wrapper, слегка модифицированный, поэтому он позволяет открывать несколько экземпляров устройства. Все работает нормально с двумя устройствами. Проблема в том, что я использую 3. Один Kinect подключается прямо к одному из доступных двух портов USB, а два других подключаются к USB 2.0 Hub (у которого есть собственный адаптер питания).
Устройства все инициализации успешно:
[email protected] initialized
[email protected] initialized
[email protected] 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;
}
}
Единственное серьезное изменение, которое я сделал в классе Kinect Даниэля добавлял дополнительный старт() метод:
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 карты глубины, но третий не обновляется.
Таким образом, кажется, что проблема связана с драйвером, а не обертку, так как то же самое поведение присутствует с использованием 2 разных оберток для libfreenect (Java/Обработка и Макс), но я невежествен, почему это бывает честно.
У кого-нибудь была аналогичная проблема (получение глубины подачи из 3-х устройств) с использованием драйвера OpenKinect/libfreenect? Любые идеи о том, как я могу преодолеть эту проблему?