Есть ли справочная библиотека команд для daniel shiffmans openkinect

Я пытаюсь обновить сценарий, созданный Луисом Кальсадой еще в 2010 году. Он изменил файл примера облака точек Дэниела Шиффмана, чтобы собирать данные облака точек в виде текстовых файлов. Вот учебник http://moullinex.tumblr.com/post/3180520798/catalina-music-video

Проблема в том, что все команды кажутся устаревшими, например Kinect.enabledepth(true); после изменения на kinect2.initDepth(true) возвращается как ошибка «неприменимо для аргументов (логическое значение)», или если я удалю это, то следующая строка возвращает сообщение об ошибке «функция processDepthImage (логическое значение) не существует», и я не могу найти эквивалентную команду в файлах примеров

Есть ли какая-то справочная библиотека, где я могу увидеть все возможные команды (и даже лучше те команды, эквивалентные предшественникам), чтобы я мог просмотреть команды обновления скрипта для работы с новой библиотекой openkinect, если нет, то это даже возможная задача чтобы я завершил процессинг-новичок?

http://pastebin.com/7GNZAdz7


person Thomas Savage    schedule 16.12.2015    source источник


Ответы (1)


Вот несколько вещей, которые помогут:

  1. Ознакомьтесь с доступной документацией и учебными пособиями.
  2. Если этого недостаточно и javadocs/reference недоступны, просмотрите общедоступные методы в исходный код и прочитайте комментарии над ними
  3. В Processing 3 вы можете использовать автозаполнение для просмотра доступных методов и свойств во всем коде (включая библиотеки). Вы даже можете включить автодополнение Ctrl+Space (если вы настроили его в настройках)

Обработка 3 настроек

Это может показать, почему функция initDepth(true) «не применима для аргументов (логических)». Используя функцию завершения обработки 3, вы можете увидеть, что на самом деле функция initDepth() существует, но она не принимает аргументов (поэтому удалите true).

Автозаполнение оболочки обработки Kinect2

Используя тот же метод, вы можете легко обнаружить, что некоторые функции из Kinect (v1) отсутствуют в классе Kinect2 (например, 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;
}
person George Profenza    schedule 17.12.2015