Если я правильно понял, вы хотите сохранить 3D-позиции (ArrayList of PVectors) для каждого кадра, верно?
Если это так, вы сможете просто хранить PVectors и ссылаться на них позже.
Вот простой эскиз, чтобы проиллюстрировать это:
import processing.opengl.*;
import SimpleOpenNI.*;
SimpleOpenNI kinect;
ArrayList<ArrayList<PVector>> frames = new ArrayList<ArrayList<PVector>>();
ArrayList<PVector> frame;
boolean isRecording = true;
boolean isRecFrame;
void setup() {
size(1024, 768, OPENGL);
kinect = new SimpleOpenNI(this);
kinect.enableDepth();
stroke(255);
}
void draw() {
background(0);
translate(width/2, height/2, 500);
rotateX(PI);
translate(0,0,-1000);
kinect.update();
if(isRecording){
isRecFrame = (frameCount % 20 == 0);//record every 20 frames
int[] depthMap = kinect.depthMap();
int steps = 5; // to speed up the drawing, draw every N point
int index;
PVector realWorldPoint;
if(isRecFrame) frame = new ArrayList<PVector>();
for(int y=0;y < kinect.depthHeight();y+=steps)
{
for(int x=0;x < kinect.depthWidth();x+=steps)
{
index = x + y * kinect.depthWidth();
if(depthMap[index] > 0)
{
realWorldPoint = kinect.depthMapRealWorld()[index];
point(realWorldPoint.x,realWorldPoint.y,realWorldPoint.z);
if(isRecFrame) frame.add(realWorldPoint.get());
}
}
}
if(isRecFrame) frames.add(frame);
}else{//playback
ArrayList<PVector> currentFrame = frames.get(frameCount%frames.size());//playback is faster than recording now for testing purposes - add a decent frame counter here at some point
for(PVector p : currentFrame) point(p.x,p.y,p.z);
}
}
void keyPressed(){
if(key == ' ') isRecording = !isRecording;
}
Используйте клавишу SPACE
для переключения между записью и воспроизведением.
Главное, что нужно отметить, это то, что я храню копию реальной позиции для каждого пикселя глубины (frame.add(realWorldPoint.get());
). Еще одна вещь, которую нужно иметь в виду, это то, что в настоящее время вы храните эти координаты в памяти, которая в какой-то момент заполнится. Если вы храните только ограниченное количество кадров, это должно быть хорошо, если нет, вы можете сохранить в точках на диске. Таким образом, вы можете повторно использовать записи с другими набросками. Основным способом было бы хранить их в файле CSV:
void saveCSV(ArrayList<PVector> pts){
String csv = "x,y,z\n";
for(PVector p : pts) csv += p.x + "," + p.y + "," + p.z + "\n";
saveStrings("frame_"+frameCount+".csv",csv.split("\n"));
}
Другой вариант - использовать более подходящий формат для облаков точек, например PLY .
Сохранение ASCII PLY довольно просто:
void savePLY(ArrayList<PVector> pts){
String ply = "ply\n";
ply += "format ascii 1.0\n";
ply += "element vertex " + pts.size() + "\n";
ply += "property float x\n";
ply += "property float y\n";
ply += "property float z\n";
ply += "end_header\n";
for(PVector p : pts)ply += p.x + " " + p.y + " " + p.z + "\n";
saveStrings("frame_"+frameCount+".ply",ply.split("\n"));
}
Позже вы можете открывать / исследовать / обрабатывать эти файлы с помощью таких инструментов, как MeshLab .