Получение исключения NullPointerException с, казалось бы, случайными интервалами, не знаю почему - PullRequest
2 голосов
/ 03 января 2011

Я запускаю пример из библиотеки Kinect для обработки (http://www.shiffman.net/2010/11/14/kinect-and-processing/) и иногда получаю исключение NullPointerException, указывающее на эту строку:

  int rawDepth = depth[offset];

В этой строке создается массив глубины:

  int[] depth = kinect.getRawDepth();

Я не совсем уверен, что такое исключение NullPointerException, и много прибегая к помощи на самом деле не помогло. Мне кажется странным, что код компилируется 70% времени и непредсказуемо возвращает ошибку. Может ли само оборудованиеповлиять на это?

Вот целый пример, если это поможет:

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

import org.openkinect.*;
import org.openkinect.processing.*;

// Kinect Library object
Kinect kinect;

float a = 0;

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

void setup() {
  size(800,600,P3D);
  kinect = new Kinect(this);
  kinect.start();
  kinect.enableDepth(true);
  // We don't need the grayscale image in this example
  // so this makes it more efficient
  kinect.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("Kinect FR: " + (int)kinect.getDepthFPS() + "\nProcessing FR: " + (int)frameRate,10,16);

  // Get the raw depth as array of integers
  int[] depth = kinect.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);

  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(255);
      pushMatrix();
      // Scale up by 200
      float factor = 200;
      translate(v.x*factor,v.y*factor,factor-v.z*factor);
      // Draw a point
      point(0,0);
      popMatrix();
    }
  }

  // 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() {
  kinect.quit();
  super.stop();
}

А вот ошибки:

processing.app.debug.RunnerException: NullPointerException
    at processing.app.Sketch.placeException(Sketch.java:1543)
    at processing.app.debug.Runner.findException(Runner.java:583)
    at processing.app.debug.Runner.reportException(Runner.java:558)
    at processing.app.debug.Runner.exception(Runner.java:498)
    at processing.app.debug.EventThread.exceptionEvent(EventThread.java:367)
    at processing.app.debug.EventThread.handleEvent(EventThread.java:255)
    at processing.app.debug.EventThread.run(EventThread.java:89)
Exception in thread "Animation Thread" java.lang.NullPointerException
    at org.openkinect.processing.Kinect.enableDepth(Kinect.java:70)
    at PointCloud.setup(PointCloud.java:48)
    at processing.core.PApplet.handleDraw(PApplet.java:1583)
    at processing.core.PApplet.run(PApplet.java:1503)
    at java.lang.Thread.run(Thread.java:637)

Ответы [ 4 ]

3 голосов
/ 03 января 2011

Вы получаете исключение NullPointerException, поскольку значение массива глубины равно нулю.Как видно из исходного кода класса Kinect, существует вероятность возврата нулевого значения методом getRawDepth ().Вероятно, в это время изображение не отображается.

Код можно найти по адресу:

https://github.com/shiffman/libfreenect/blob/master/wrappers/java/processing/KinectProcessing/src/org/openkinect/processing/Kinect.java

Ваш код должен проверить, является ли массив глубинявляется нулевым, прежде чем пытаться его обработать.Например ...

int[] depth = kinect.getRawDepth();

if (depth == null) {
  // do something here where you handle there being no image
} else {
  // 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);

  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(255);
      pushMatrix();
      // Scale up by 200
      float factor = 200;
      translate(v.x*factor,v.y*factor,factor-v.z*factor);
      // Draw a point
      point(0,0);
      popMatrix();
    }
  }

  // Rotate
  a += 0.015f;
}
1 голос
/ 03 января 2011

Исключение нулевого указателя возникает, когда depth[offset] не существует или не был выделен.Проверьте, когда depth[offset] не определено и это является причиной исключения нулевого указателя.

Проверьте, когда kinect.getRawDepth(); больше offset.

1 голос
/ 03 января 2011

Нулевой указатель возникает, когда offset> kinect.getRawDepth ();

У вас много кода здесь, я не буду на все это смотреть.Почему вы можете предположить, что смещение равно

Редактировать :

Во-вторых, комментарий @ Asaph, вероятно, прав.

1 голос
/ 03 января 2011

Я бы предложил использовать отладчик Java, чтобы вы могли видеть состояние переменных в момент выдачи исключения. Некоторые люди также любят использовать операторы log для вывода значений переменных в разных точках приложения.

Затем можно проследить проблему до точки, в которой одно из значений не заполнено ненулевым значением.

...