2011-12-03 3 views
1

Je me demandais si quelqu'un a pu utiliser OpenNI en combinaison avec OpenCV dans java? Par exemple que vous obtenez le flux de profondeur dans un IplImage etc ... J'essaie actuellement de le faire, mais je ne sais pas par où commencer.Java: OpenCV & OpenNI

Si quelqu'un qui a fait cela veut partager ses connaissances ou du code, je serais reconnaissant.

Mon code à ce jour:

/

* 
* To change this template, choose Tools | Templates 
* and open the template in the editor. 


/** 
* 
* @author olivierjanssens 
*/ 

package kitouch; 

import com.googlecode.javacpp.Loader; 
import com.googlecode.javacv.*; 
import com.googlecode.javacv.cpp.*; 
import static com.googlecode.javacv.cpp.opencv_core.*; 
import static com.googlecode.javacv.cpp.opencv_imgproc.*; 
import static com.googlecode.javacv.cpp.opencv_calib3d.*; 
import static com.googlecode.javacv.cpp.opencv_objdetect.*; 
import java.nio.ShortBuffer; 
import java.awt.*; 
import java.awt.image.*; 
import org.OpenNI.*; 
import javax.swing.JFrame; 

public class KiTouch { 

    private Context context; 
    private final String SAMPLE_XML_FILE = "/Users/olivierjanssens/Development/Kinect/OpenNI/Samples/Config/SamplesConfig.xml";  
    private OutArg<ScriptNode> scriptNode; 
    private DepthGenerator depthGen; 
    private BufferedImage bimg; 
    int width, height; 
    IplImage depthImage; 
    private float histogram[]; 
    private byte[] imgbytes; 
    CanvasFrame frame = new CanvasFrame("Some Title"); 

    public KiTouch() { 
     try { 
      scriptNode = new OutArg<ScriptNode>(); 
      context = Context.createFromXmlFile(SAMPLE_XML_FILE, scriptNode); 

      depthGen = DepthGenerator.create(context); 
      DepthMetaData depthMD = depthGen.getMetaData(); 

      histogram = new float[10000]; 
      width = depthMD.getFullXRes(); 
      height = depthMD.getFullYRes(); 

      imgbytes = new byte[width*height]; 

      DataBufferByte dataBuffer = new DataBufferByte(imgbytes, width*height); 
      Raster raster = Raster.createPackedRaster(dataBuffer, width, height, 8, null); 
      bimg = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY); 
      bimg.setData(raster); 
      depthImage = IplImage.create(width, height, IPL_DEPTH_8U, 1); 

     } catch (GeneralException e) { 
      e.printStackTrace(); 
      System.exit(1); 
     } 


    } 


    private void calcHist(DepthMetaData depthMD) 
    { 
     // reset 
     for (int i = 0; i < histogram.length; ++i) 
      histogram[i] = 0; 

     ShortBuffer depth = depthMD.getData().createShortBuffer(); 
     depth.rewind(); 

     int points = 0; 
     while(depth.remaining() > 0) 
     { 
      short depthVal = depth.get(); 
      if (depthVal != 0) 
      { 
       histogram[depthVal]++; 
       points++; 
      } 
     } 

     for (int i = 1; i < histogram.length; i++) 
     { 
      histogram[i] += histogram[i-1]; 
     } 

     if (points > 0) 
     { 
      for (int i = 1; i < histogram.length; i++) 
      { 
       histogram[i] = (int)(256 * (1.0f - (histogram[i]/(float)points))); 
      } 
     } 
    } 

    public Dimension getPreferredSize() { 
     return new Dimension(width, height); 
    } 

    void updateDepth() 
    { 
     try { 
      DepthMetaData depthMD = depthGen.getMetaData(); 

      context.waitAnyUpdateAll(); 

      calcHist(depthMD); 
      ShortBuffer depth = depthMD.getData().createShortBuffer(); 
      depth.rewind(); 

      while(depth.remaining() > 0) 
      { 
       int pos = depth.position(); 
       short pixel = depth.get(); 
       imgbytes[pos] = (byte)histogram[pixel]; 
      } 
      depthImage.createFrom(bimg); 
      frame.showImage(depthImage); 

     } catch (GeneralException e) { 
      e.printStackTrace(); 
     } 
    } 


} 

et appeler ce code:

/* 
* To change this template, choose Tools | Templates 
* and open the template in the editor. 
*/ 
package kitouch; 

import org.OpenNI.GeneralException; 

/** 
* 
* @author olivierjanssens 
*/ 
public class kiTouchApp { 
    public static void main(String s[]) throws GeneralException { 
     KiTouch kit = new KiTouch(); 


      while(true) { 
      kit.updateDepth(); 
     } 
    } 
} 

Bien que je reçois un cadre noir. Donc ça ne marche pas encore

Quand je n'initialise pas l'image IplImage comme je le fais ici mais juste IplImage depthImage = new IplImage(); j'obtiens cette erreur:

Exception in thread "main" java.lang.NullPointerException 
at java.awt.image.BufferedImage.<init>(BufferedImage.java:613) 
at com.googlecode.javacv.cpp.opencv_core$IplImage.getBufferedImage(opencv_core.java:1005) 
at com.googlecode.javacv.cpp.opencv_core$IplImage.getBufferedImage(opencv_core.java:931) 
at com.googlecode.javacv.CanvasFrame.showImage(CanvasFrame.java:331) 
at kitouch.KiTouch.paint(KiTouch.java:138) 
at kitouch.kiTouchApp.main(kiTouchApp.java:21) 

Thx à l'avance!

Répondre

1

j'ai joué avec OpenNI et Java, mais en utilisant Processing et les emballages disponibles (SimpleOpenNI et OpenCV) qui, pour mes besoins modestes en ce moment bien. Voici un exemple très simple:

import hypermedia.video.*; 
import SimpleOpenNI.*; 

SimpleOpenNI ni; 
OpenCV cv; 
PImage user; 
void setup() 
{ 
    ni = new SimpleOpenNI(this); 
    ni.enableScene(); 
    background(200,0,0); 
    strokeWeight(4); 
    size(ni.sceneWidth() , ni.sceneHeight()); 
    cv = new OpenCV(this); 
    cv.allocate(width,height); 
} 
void draw() 
{ 
    //OpenNI 
    ni.update(); 
    user = ni.sceneImage(); 
    //OpenCV 
    cv.copy(user); 
    cv.blur(OpenCV.BLUR, 17); 
    Blob[] blobs = cv.blobs(width,height, OpenCV.MAX_VERTICES, true, OpenCV.MAX_VERTICES*4); 

    //diplay 
    image(cv.image(),0,0); 
    //* 
    fill(255); 
    for(Blob b : blobs){ 
    beginShape(); 
     for(java.awt.Point p : b.points) vertex(p.x,p.y); 
    endShape(CLOSE); 
    } 
    //*/ 
} 

Notez que cette enveloppe OpenCV utilise OpenCV 1.0 et vous voudrez peut-être utiliser vos propres classes Java, plutôt utiliser la bibliothèque de traitement. Dans ce cas, essayez l'emballage JavaCV. En ce qui concerne le flux de profondeur, si vous regardez dans la classe org.OpenNI.Samples.SimpleViewer qui vient avec OpenNI, vous remarquerez que les octets de profondeur d'OpenNI sont écrits dans un BufferedImage, que j'imagine être intégré avec OpenCV, etc.

public SimpleViewer() { 

     try { 
      scriptNode = new OutArg<ScriptNode>(); 
      context = Context.createFromXmlFile(SAMPLE_XML_FILE, scriptNode); 

      depthGen = DepthGenerator.create(context); 
      DepthMetaData depthMD = depthGen.getMetaData(); 

      histogram = new float[10000]; 
      width = depthMD.getFullXRes(); 
      height = depthMD.getFullYRes(); 

      imgbytes = new byte[width*height]; 

      DataBufferByte dataBuffer = new DataBufferByte(imgbytes, width*height); 
      Raster raster = Raster.createPackedRaster(dataBuffer, width, height, 8, null); 
      bimg = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY); 
      bimg.setData(raster); 

     } catch (GeneralException e) { 
      e.printStackTrace(); 
      System.exit(1); 
     } 
    } 
+0

Actuellement, je regarde dans le BufferedImage, je crois qu'un BufferedImage peut être converti en IplImage. Oh et btw j'utilise le javacv – Ojtwist

+0

Bien sûr, googling pour ** java iplimage ** devrait vous obtenir [résultats intéressants] (http://www.morethantechnical.com/2009/05/14/combining-javas-bufferedimage- et-opencvs-iplimage /). –

+0

vrai, mais il y a une conversion intégrée j'ai essayé: 'depthImage.createFrom (bimg); frame.showImage (depthImage); ' Ce que je fais dans la fonction updateepth. Mais je reçois un nullpointer cependant. Donc, pour continuer à chercher – Ojtwist