1

我正在尝试更新 Luis Calçada 在 2010 年制作的脚本。他修改了 Daniel Shiffman 的点云示例文件,以将点云数据收集为文本文件。这是教程http://moullinex.tumblr.com/post/3180520798/catalina-music-video

问题是所有命令似乎都过时了,例如 Kinect.enabledepth(true); 更改为 kinect2.initDepth(true) 后返回错误“不适用于参数(布尔值)”,或者如果我删除它,那么下一行返回一个错误,指出“函数 processDepthImage(boolean) 不存在”,我在示例文件中找不到等效命令

是否有某种参考库,我可以在其中看到所有可能的命令(甚至更好的是那些命令等效的前置命令),所以我可以通过脚本更新命令来使用新的 openkinect 库,如果没有,那么这甚至是一个可能的任务让我完成一个处理新手?

http://pastebin.com/7GNZAdz7

4

1 回答 1

1

这里有几件事会有所帮助:

  1. 阅读可用的文档和教程
  2. 如果这还不够并且 javadocs/reference 不可用,请查看源代码中的公共方法并阅读它们上面的注释
  3. 在 Processing 3 中,您可以使用自动完成功能来查看整个代码(包括库)中的可用方法和属性。您甚至可以启用 Ctrl+Space 自动完成(如果您在首选项中设置)

处理 3 个偏好

这可能会揭示为什么该函数initDepth(true)“不适用于参数(布尔值)”。使用处理 3 完成功能,您可以看到实际上有一个initDepth()函数,但它不接受任何参数(因此 remove true)。

Kinect2 处理包装器自动完成

使用相同的方法,您可以很容易地发现 Kinect2 类中缺少 Kinect (v1) 中的某些功能(例如processDepthImage()getDepthFPS()),您应该删除这些功能,并且其他功能具有等效功能但名称/签名不同(例如quit()在 Kinect 中) (v1) 但stopDevice()dispose()Kinect2 中)

这是应该编译的代码的粗略重构版本,但可能无法 100% 工作,因为我没有 Kinect 2 可供使用:

import org.openkinect.freenect.*;
import org.openkinect.freenect2.*;
import org.openkinect.processing.*;
import org.openkinect.tests.*;

// Daniel Shiffman
// Kinect Point Cloud example
// http://www.shiffman.net
// https://github.com/shiffman/libfreenect/tree/master/wrappers/java/processing

import java.util.*;
import java.io.*;

// Kinect Library object
// Kinect Library object
Kinect2 kinect2;

float a = 0;

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

// writing state indicator
boolean write = false;

// treshold filter initial value
int fltValue = 950;


// "recording" object. each vector element holds a coordinate map vector
Vector <Object> recording = new Vector<Object>(); 


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

void setup() {
  size(800, 600, P3D);
  kinect2 = new Kinect2(this);
  kinect2.init();
  kinect2.initDevice();
  kinect2.initDepth();
  // We don't need the grayscale image in this example
  // so this makes it more efficient
  //kinect2.processDepthImage(false);


  // Lookup table for all possible depth values (0 - 2047)
  for (int i = 0; i < depthLookUp.length; i++) {
    depthLookUp[i] = rawDepthToMeters(i);
  }
}

void draw() {

  background(0);
  fill(255);
  textMode(SCREEN);
  text("Processing FR: " + (int)frameRate, 10, 16);

  // Get the raw depth as array of integers
  int[] depth = kinect2.getRawDepth();

  // We're just going to calculate and draw every 4th pixel (equivalent of 160x120)
  int skip = 4;

  // Translate and rotate
  translate(width/2, height/2, -50);
  rotateY(a);

  //noStroke();
  //lights();


  int index = 0;


  PVector[] frame = new PVector[19200];


  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];

      boolean flt = true;
      PVector v = depthToWorld(x, y, rawDepth);
      if (flt && rawDepth > fltValue)
      {
        v = depthToWorld(x, y, 2047);
      }

      frame[index] = v;

      index++;   

      stroke(map(rawDepth, 0, 2048, 0, 256));
      pushMatrix();
      // Scale up by 200
      float factor = 400;
      translate(v.x*factor, v.y*factor, factor-v.z*factor);
      //sphere(1);
      point(0, 0);

      //line (0,0,1,1);
      popMatrix();
    }
  }

  if (write == true) {
    recording.add(frame);
  }


  // Rotate
  //a += 0.015f;
}

// 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;
}

void stop() {
  kinect2.stopDevice();
  kinect2.dispose();
  super.stop();
}


int currentFile = 0;

void saveFile() {
}

void keyPressed() { // Press a key to save the data

  if (key == '1')
  {
    fltValue += 50;
    println("fltValue: " + fltValue);
  } else if (key == '2')
  {
    fltValue -= 50;
    println("fltValue: " + fltValue);
  } else if (key=='4') {
    if (write == true) {
      write = false;

      println( "recorded " + recording.size() + " frames.");

      // saveFile();

      // save    

      Enumeration e = recording.elements();

      println("Stopped Recording " + currentFile);
      int i = 0;
      while (e.hasMoreElements()) {

        // Create one directory
        boolean success = (new File("out"+currentFile)).mkdir(); 


        PrintWriter output = createWriter("out"+currentFile+"/frame" + i++ +".txt");
        PVector [] frame = (PVector []) e.nextElement();

        for (int j = 0; j < frame.length; j++) {
          output.println(j + ", " + frame[j].x + ", " + frame[j].y + ", " + frame[j].z );
        }
        output.flush(); // Write the remaining data
        output.close();
      }
      currentFile++;
    }
  } else if (key == '3') {
    println("Started Recording "+currentFile);
    recording.clear();

    write = true;
  }
}

更新很多原始代码仅对 Kinect v1 有效,尤其是围绕深度数据和将深度值转换为真实世界值的部分。

但是,库附带的DepthPointCloud2示例可以很容易地改变用途:它只需要将点存储在内存中,直到它们被写入磁盘。唯一的其他补充是过滤深度。原始代码仅包含一个远阈值,但在实践中同时具有远近裁剪选项可能证明是有用的。这是修改后的示例,使用SPACE来切换录制,N/n增加/减少近端剪切的F/f键和增加/减少远端剪切的键:

// Daniel Shiffman //<>//
// Thomas Sanchez Lengeling
// Kinect Point Cloud example

// https://github.com/shiffman/OpenKinect-for-Processing
// http://shiffman.net/p5/kinect/

import org.openkinect.processing.*;
import java.nio.FloatBuffer;

// Kinect Library object
Kinect2 kinect2;

// Angle for rotation
float a = 3.1;

//depth filtering
float depthNear = 700;
float depthFar = 950;

//recording point clouds to disk
boolean isRecording;
ArrayList<ArrayList<PVector>> frames = new ArrayList<ArrayList<PVector>>();

void setup() {

  // Rendering in P3D
  size(800, 600, P3D);

  kinect2 = new Kinect2(this);
  kinect2.initDepth();
  kinect2.initDevice();
}


void draw() {
  background(0);

  // Translate and rotate
  pushMatrix();
  translate(width/2, height/2, 50);
  rotateY(a);

  // We're just going to calculate and draw every 2nd pixel
  int skip = 2;

  // Get the raw depth as array of integers
  int[] depth = kinect2.getRawDepth();

  //create a new point cloud frame - a list of points
  ArrayList<PVector> frame = new ArrayList<PVector>(); 

  stroke(255);
  beginShape(POINTS);
  for (int x = 0; x < kinect2.depthWidth; x+=skip) {
    for (int y = 0; y < kinect2.depthHeight; y+=skip) {
      int offset = x + y * kinect2.depthWidth;
      float depthValue = depth[offset];

      //filter based on depth
      if(depthValue >= depthNear && depthValue <= depthFar){

      //calculte the x, y, z camera position based on the depth information
      PVector point = depthToPointCloudPos(x, y, depthValue);

      //add the point to the current frame if it's recording
      if(isRecording) frame.add(point);

      // Draw a point
      vertex(point.x, point.y, point.z);

      }
    }
  }
  endShape();

  popMatrix();

  //add the frame to the recording (list of frames) if recording
  if(isRecording) frames.add(frame);

  fill(255, 0, 0);
  text((int)frameRate+"fps\nrecording: " + isRecording + "\ndepthFar: " + depthFar + " depthNear: " + depthNear
       +"\nkeys:\nSPACE - toggle recording\nN/n - increase/decrease near clipping\nF/f - increase/decrease far clipping", 50, 50);

  // Rotate
  //a += 0.0015f;
}

void keyReleased(){
  //toggle recording using space
  if(key == ' ') {
    isRecording = !isRecording;
    //if it was recording, but now it's not, there should be some frames there to save
    if(!isRecording) saveFramesToDisk();
    else             frames.clear();//otherwise, there might have been a recording already, so clear any previous frames
  }
  //modify near/far filters
  int depthFilterAmount = 10;//depth filter increment
  if(key == 'n') depthNear -= depthFilterAmount;
  if(key == 'N') depthNear += depthFilterAmount;
  if(key == 'f') depthFar -= depthFilterAmount;
  if(key == 'F') depthFar += depthFilterAmount;
}

void saveFramesToDisk(){
  //create a timestamp string
  String folderName = "rec_"+day()+"-"+month()+"-"+year()+" "+hour()+":"+minute()+":"+second()+":"+millis();
  //make a folder with that name
  new File(folderName).mkdir();
  //count the number of frames
  int numFrames = frames.size();
  //for each frame
  for(int i = 0 ; i < numFrames; i++){
    //access the list of points
    ArrayList<PVector> frame = frames.get(i);
    //make a new text file for each frame - checkout nf() - really handy for naming files sequentially
    PrintWriter output = createWriter(folderName+"/frame" + nf(i,4) +".txt");
    //for each point in a frame
    for (int j = 0; j < frame.size(); j++) {
      //retrieve the point
      PVector p = frame.get(j);
      //write to file: index, x, y,z + new line character
      output.println(j + ", " + p.x + ", " + p.y + ", " + p.z );
    }

    output.flush(); // Write the remaining data
    output.close();

  }

  println("Wrote " + numFrames + " frames in " + folderName);

}

//calculte the xyz camera position based on the depth data
PVector depthToPointCloudPos(int x, int y, float depthValue) {
  PVector point = new PVector();
  point.z = (depthValue);// / (1.0f); // Convert from mm to meters
  point.x = (x - CameraParams.cx) * point.z / CameraParams.fx;
  point.y = (y - CameraParams.cy) * point.z / CameraParams.fy;
  return point;
}
//camera information based on the Kinect v2 hardware
static class CameraParams {
  static float cx = 254.878f;
  static float cy = 205.395f;
  static float fx = 365.456f;
  static float fy = 365.456f;
  static float k1 = 0.0905474;
  static float k2 = -0.26819;
  static float k3 = 0.0950862;
  static float p1 = 0.0;
  static float p2 = 0.0;
}
于 2015-12-17T00:21:15.507 回答