2011-12-03 51 views
1

我想知道是否有人已經能夠在組合的java使用openniOpenCV的? 例如,你在IplImage等中獲得深度流......我目前正在努力做到這一點,但我不知道從哪裏開始。的Java:OpenCV的&openni

如果有人這樣做想要分享他們的知識或代碼,我將不勝感激。

我迄今爲止代碼:

/

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


} 

,並調用此代碼:

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

雖然我得到一個黑色的框架。所以它還沒有工作呢

當我不initalize IplImage像我這裏做,但只是IplImage depthImage = new IplImage();我得到這個錯誤:

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提前!

回答

1

我確實玩過OpenNI和Java,但是使用Processing和可用的包裝(SimpleOpenNIOpenCV),這些對我目前的適度需求來說很好。 這裏是一個非常簡單的例子:

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

注意這個OpenCV的包裝使用了OpenCV 1.0,你也可能想使用自己的Java類,而使用處理庫。在這種情況下,請嘗試使用JavaCV包裝。 關於深度流,如果您查看OpenNI附帶的org.OpenNI.Samples.SimpleViewer類,您會注意到來自OpenNI的深度字節被寫入BufferedImage,我想可以將其與OpenCV等集成在一起。

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

目前我正在查看BufferedImage,我相信一個BufferedImage可以轉換爲IplImage。哦,順便說一句,我使用javacv – Ojtwist

+0

當然,谷歌搜索** java iplimage **應該讓你[有趣的結果](http://www.morethantechnical.com/2009/05/14/combining-javas-bufferedimage-和opencvs-的IplImage /)。 –

+0

是真的,但有一個內置的轉換我試過:'depthImage.createFrom(bimg); frame.showImage(depthImage);' 我在updatedepth函數中做什麼。但是我得到一個空指針。所以必須繼續搜索 – Ojtwist