【问题标题】:Java: opencv & openniJava:opencv 和 openni
【发布时间】:2011-12-03 11:24:16
【问题描述】:

我想知道是否有人能够在 java 中将 openniopencv 结合使用? 例如,您在 IplImage 等中获得深度流......我目前正在尝试这样做,但我不确定从哪里开始。

如果有人愿意分享他们的知识或一些代码,我将不胜感激。

到目前为止我的代码:

/

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

虽然我得到了一个黑框。所以还是不行

当我没有像这里那样初始化 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)

提前谢谢!

【问题讨论】:

    标签: java opencv openni


    【解决方案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);
            }
        }
    

    【讨论】:

    • 目前我正在研究 BufferedImage,我相信 BufferedImage 可以转换为 IplImage。哦,顺便说一句,我正在使用 javacv
    • 当然,谷歌搜索 java iplimage 应该会得到 interesting results
    • true,但我尝试了一个内置转换:'depthImage.createFrom(bimg); frame.showImage(depthImage);'我在 updatedepth 函数中做的。但是我得到了一个空指针。所以必须继续搜索
    • 我已经在问题中添加了我的代码,也许你可以看看它? (我没有得到一个空指针 atm 只有一个黑屏)
    • 很遗憾现在无法在我使用的计算机上进行测试,但您能否检查一下是否可以在屏幕上显示 bimg(或 bimg 的 BufferedImage)?如果可行,则问题出在 depthImage.createFrom() 上,或者字节数组以某种方式无法通过,但首先,首先确保 bimg 不为空/空。 HTH
    猜你喜欢
    • 1970-01-01
    • 2023-03-04
    • 2013-01-16
    • 1970-01-01
    • 1970-01-01
    • 2011-08-30
    • 1970-01-01
    • 2013-10-11
    • 1970-01-01
    相关资源
    最近更新 更多