简体   繁体   English

以看似随机的间隔获取NullPointerException,不知道为什么

[英]Getting a NullPointerException at seemingly random intervals, not sure why

I'm running an example from a Kinect library for Processing (http://www.shiffman.net/2010/11/14/kinect-and-processing/) and sometimes get a NullPointerException pointing to this line: 我正在从Kinect库中运行一个示例以进行处理(http://www.shiffman.net/2010/11/14/kinect-and-processing/),有时会得到一个NullPointerException指向此行:

  int rawDepth = depth[offset];

The depth array is created in this line: 深度数组在以下行中创建:

  int[] depth = kinect.getRawDepth();

I'm not exactly sure what a NullPointerException is, and much googling hasn't really helped. 我不确定NullPointerException是什么,并且很多谷歌搜索并没有真正帮助。 It seems odd to me that the code compiles 70% of the time and returns the error unpredictably. 对我来说,代码编译70%的时间并意外地返回错误似乎使我感到奇怪。 Could the hardware itself be affecting it? 硬件本身会影响它吗?

Here's the whole example if it helps: 这是整个示例,如果有帮助的话:

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

And here are the errors: 这是错误:

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)

You are getting a NullPointerException since the value of the depth array is null. 由于depth数组的值为null,因此您将获得NullPointerException。 You can see from the source code of the Kinect class, there is a chance of a null value being returned by the getRawDepth() method. 您可以从Kinect类的源代码中看到,getRawDepth()方法有可能返回空值。 It is likely that there is no image being displayed at the time. 当时可能没有图像显示。

The code can be found at: 可以在以下位置找到该代码:

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

Your code should check if the depth array is null before trying to process it. 您的代码应在尝试处理depth数组之前检查是否为null。 For example... 例如...

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

I would suggest using a Java Debugger so that you can see the state of the variables at the time the exception is thrown. 我建议使用Java调试器,以便在引发异常时可以看到变量的状态。 Some people also like to use log statements to output the values of the variables at different points in the application. 有些人还喜欢使用log语句在应用程序的不同位置输出变量的值。

You can then trace the problem back to a point where one of the values is not populated with a non-null value. 然后,您可以将问题追溯到其中一个值未填充非空值的情况。

The null pointer is happening when offset > kinect.getRawDepth(); 当offset> kinect.getRawDepth();时,将发生空指针。

You have a lot of code here, I'm not going to look at it all. 您在这里有很多代码,我将不介绍所有内容。 Why can you assume that offset is < kinect.getRawDepth()? 为什么可以假设offset为<kinect.getRawDepth()?

Edit : 编辑

On second though, @Asaph's comment is probably right. 第二点,@ Asaph的评论可能是正确的。

Null Pointer exception happens when depth[offset] does not exist or has not been allocated. depth[offset]不存在或尚未分配时,将发生空指针异常。 Check when depth[offset] is undefined and that is the cause of the nullpointer exception. 检查depth[offset]是否未定义,这是nullpointer异常的原因。

Check when kinect.getRawDepth(); 检查何时kinect.getRawDepth(); is greater than offset . 大于offset

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM