0

Java、Kinect(OpenNI)、Processingを使った実際のプロジェクトに問題があります。
処理とJavaだけを使用すると、すべてが正常に機能し、つまずくことはなく、例外も発生しません。
しかし、(アプレットスタイルの処理に関するいくつかの問題を解決するために)JFrameで処理アプレットを投獄すると、次の問題が発生します。

  • 3秒ごとにkinectイメージがすぐにハングします(Javaがガベージコレクターを使用してメモリから何かをクリアしているように見えます)
  • 20秒後、アプリケーションが停止し、次のエラーが発生します。

    Exception in thread "Animation Thread" java.lang.OutOfMemoryError: Java heap space
    at java.awt.image.DataBufferInt.<init>(Unknown Source)
    at java.awt.image.Raster.createPackedRaster(Unknown Source)
    at java.awt.image.DirectColorModel.createCompatibleWritableRaster(Unknown Source)
    at java.awt.image.BufferedImage.<init>(Unknown Source)
    

視覚化に関する私の関連コードは次のとおりです。

public boolean drawGrayscaleImage(){    

    //init PApplet and build JFrame
    GrayscalePApplet grayscalePApplet = new  GrayscalePApplet ();
    grayscalePApplet.init();        
    this.grayscaleJFrame = this.initFrame(grayscalePApplet);

    //Set Uplink for PApplet and begin drawing
    grayscalePApplet.setGraphicP(this);     

    return false;
}

ここでは、ProcessingPAppletクラスからの描画関数です。

public void draw(){

    if(graphicP != null){
        //creat the relevant image Buffers for java and Processing
        BufferedImage image = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_BYTE_GRAY);           
        PImage pimage = new PImage(image.getWidth(),image.getHeight(),PConstants.ARGB);

        //fill up the databuffer using a converted Kinect Grayscale Image
        DataBufferByte dataBuffer = new DataBufferByte(graphicP.getImage(ImageType.GRAYSCALE), this.imageWidth * this.imageHeight);
        Raster raster = Raster.createPackedRaster(dataBuffer,imageWidth, imageHeight, 8, null);
        image.setData(raster);

        //draw image to Processing
        image.getRGB(0, 0, pimage.width, pimage.height, pimage.pixels, 0, pimage.width);
        pimage.updatePixels();
        image(pimage, 0, 0);

        // null everything to get Garbagecollection to work (?)
        image = null;
        pimage = null;
        dataBuffer = null;
    }
}

そのOutOfMemory例外を防ぐにはどうすればよいですか?
その例外の原因は何ですか?

4

1 に答える 1

0

私は完全なコードを見ることができないので、正確な仮定をすることはできませんが、私の推測では、問題はここにあります:

BufferedImage image = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_BYTE_GRAY);           
        PImage pimage = new PImage(image.getWidth(),image.getHeight(),PConstants.ARGB);

        //fill up the databuffer using a converted Kinect Grayscale Image
        DataBufferByte dataBuffer = new DataBufferByte(graphicP.getImage(ImageType.GRAYSCALE), this.imageWidth * this.imageHeight);
        Raster raster = Raster.createPackedRaster(dataBuffer,imageWidth, imageHeight, 8, null);
        image.setData(raster);

使用しているKinectAPI(OpenNI / libfreenect)はわかりませんが、それでも、フレームごとに新しいイメージを複数回作成するべきではありません(のようにdraw())。画像はすぐにメモリをいっぱいにし、常に複数の画像を必要とせず、更新を続ける2つの画像が必要です。たとえば、画像を一度初期化してsetup()から、それらの画像のピクセルを更新します。draw()

また、Processingを使用している場合は、 OpenNI用のSimpleOpenNIやlibfreenect用のdLibs(Win)/ OpenKinectなどのKinect処理ラッパーライブラリを確認することをお勧めします。これらのいずれかを使用して深度画像を表示する方がはるかに簡単です。

SimpleOpenNIの場合:

import SimpleOpenNI.*;

SimpleOpenNI  ni;

void setup(){
  ni = new SimpleOpenNI(this);
  ni.enableDepth()
  size(ni.depthWidth(), ni.depthHeight()); 
}

void draw(){
  ni.update();
  image(context.depthImage(),0,0);
}

dLibs freenectの場合:

import dLibs.freenect.toolbox.*;
import dLibs.freenect.constants.*;
import dLibs.freenect.interfaces.*;
import dLibs.freenect.*;

Kinect kinect;                     // main kinect-object
KinectFrameDepth kinectDepth;     // depth frame
PImage depthFrame;

void setup(){
  size(640,480);
  kinect = new Kinect(0);
  kinectDepth = new KinectFrameDepth(DEPTH_FORMAT._11BIT_);// create a depth instance
  kinectDepth.connect(kinect);  //connect the created depth instance to the main kinect
  depthFrame = createImage(DEPTH_FORMAT._11BIT_.getWidth(), DEPTH_FORMAT._11BIT_.getHeight(), RGB);
}
void draw(){
  assignPixels(depthFrame, kinectDepth);
  image(depthFrame, 0, 0);
}
void assignPixels(PImage img, Pixelable kinectDev){
  img.loadPixels();
  img.pixels = kinectDev.getPixels();  // assign pixels of the kinect device to the image
  img.updatePixels();
}
void dispose(){
  Kinect.shutDown(); 
  super.dispose();
}

OpenKinect P5の場合:

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

Kinect kinect;

void setup() {
  size(640,480);
  kinect = new Kinect(this);
  kinect.start();
  kinect.enableDepth(true);
}

void draw() {
  background(0);
  image(kinect.getDepthImage(),0,0);
}

void stop() {
  kinect.quit();
  super.stop();
}

適切な処理ラッパーを選択するために必要なOSと機能はどれかによって異なります。

シンプルなopenni SimpleOpenNIサンプル

diwi dlibs dLibs_freenect

OpenKinect P5 OpenKinect P5

于 2012-11-15T00:14:09.993 に答える