Java:从 BufferedImage 到 IplImage

标签 java opencv

当我尝试将 BufferedImage 转换为 Iplimage 时,我得到了一个空的 Iplimage。转换本身由内置的 opencv 函数 完成。我现在的问题是:为什么它是空的,我该如何解决?

这是我的代码;您可以在最后一个函数 paint() 中找到转换。

编辑:

当我从 IplImage 中提取 BufferedImage 时,我再次获得 BufferedImage 并且可以显示它。那么,当我想将其显示为 IplImage 时,为什么它不显示任何内容?

package kitouch;

import org.OpenNI.*;
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.*;

class SimpleViewer extends Component {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private OutArg<ScriptNode> scriptNode;
    private Context context;
    private DepthGenerator depthGen;
    private byte[] imgbytes;
    private float histogram[];
    private IplImage depthImg =new IplImage();
    private BufferedImage bimg;
    int width, height;
    CanvasFrame frame = new CanvasFrame("Some Title");

    private final String SAMPLE_XML_FILE = "/Users/olivierjanssens/Development/Kinect/OpenNI/Samples/Config/SamplesConfig.xml";    
    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);
        }
    }

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


    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];
            }
        } catch (GeneralException e) {
            e.printStackTrace();
        }
    }


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

    public void paint(Graphics g) {
        DataBufferByte dataBuffer = new DataBufferByte(imgbytes, width*height);
        Raster raster = Raster.createPackedRaster(dataBuffer, width, height, 8, null);
        bimg.setData(raster);

        depthImg.createFrom(bimg); 
        frame.showImage(depthImg); //NULLPOINTER HERE BECAUSE depthImg is empty

       // WHEN DOING THIS I CAN SEE THE IMAGE, SO bimg is not empty
        //g.drawImage(bimg, 0, 0, null);
    }
}

我调用前面提到的代码的地方:

package kitouch;

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JFrame;

public class SimpleViewerApplication
{

    private SimpleViewer viewer;
    private boolean shouldRun = true;
    private JFrame frame;

    public SimpleViewerApplication (JFrame frame)
    {
        {
            this.frame = frame;
            frame.addKeyListener(new KeyListener()
            {
                @Override
                public void keyTyped(KeyEvent arg0) {}
                @Override
                public void keyReleased(KeyEvent arg0) {}
                @Override
                public void keyPressed(KeyEvent arg0) {
                    if (arg0.getKeyCode() == KeyEvent.VK_ESCAPE)
                    {
                        shouldRun = false;
                    }
                }
            });
        }
    }

    public static void main(String s[]) {
        JFrame f = new JFrame("OpenNI Simple Viewer");
        f.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {System.exit(0);}
        });
        SimpleViewerApplication app = new SimpleViewerApplication(f);

        app.viewer = new SimpleViewer();
        f.add("Center", app.viewer);
        f.pack();
        f.setVisible(true);

        app.run();
    }

    void run() {
        while(shouldRun) {
            viewer.updateDepth();
            viewer.repaint();
        }
        frame.dispose();
    }

}

异常:

Exception in thread "AWT-EventQueue-0" 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.SimpleViewer.paint(SimpleViewer.java:147)
    at javax.swing.JComponent.paintChildren(JComponent.java:876)
    at javax.swing.JComponent.paint(JComponent.java:1038)
    at javax.swing.JComponent.paintChildren(JComponent.java:862)
    at javax.swing.JComponent.paint(JComponent.java:1038)
    at javax.swing.JLayeredPane.paint(JLayeredPane.java:567)
    at javax.swing.JComponent.paintChildren(JComponent.java:862)
    at javax.swing.JComponent.paint(JComponent.java:1038)
    at java.awt.GraphicsCallback$PaintCallback.run(GraphicsCallback.java:34)
    at sun.awt.SunGraphicsCallback.runOneComponent(SunGraphicsCallback.java:60)
    at sun.awt.SunGraphicsCallback.runComponents(SunGraphicsCallback.java:97)
    at java.awt.Container.paint(Container.java:1793)
    at java.awt.Window.paint(Window.java:3375)
    at sun.awt.RepaintArea.paintComponent(RepaintArea.java:276)
    at sun.awt.RepaintArea.paint(RepaintArea.java:241)
    at apple.awt.ComponentModel.handleEvent(ComponentModel.java:263)
    at apple.awt.CWindow.handleEvent(CWindow.java:545)
    at java.awt.Component.dispatchEventImpl(Component.java:4811)
    at java.awt.Container.dispatchEventImpl(Container.java:2143)
    at java.awt.Window.dispatchEventImpl(Window.java:2478)
    at java.awt.Component.dispatchEvent(Component.java:4565)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:679)
    at java.awt.EventQueue.access$000(EventQueue.java:85)
    at java.awt.EventQueue$1.run(EventQueue.java:638)
    at java.awt.EventQueue$1.run(EventQueue.java:636)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:98)
    at java.awt.EventQueue$2.run(EventQueue.java:652)
    at java.awt.EventQueue$2.run(EventQueue.java:650)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:649)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:296)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:211)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:196)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:188)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

最佳答案

我正在使用 JavaCV 1.1,这就是我转换图像的方式:

IplImage toIplImage(BufferedImage bufImage) {

    ToIplImage iplConverter = new OpenCVFrameConverter.ToIplImage();
    Java2DFrameConverter java2dConverter = new Java2DFrameConverter();
    IplImage iplImage = iplConverter.convert(java2dConverter.convert(bufImage));
    return iplImage;
}

具体来说,这些是我的build.gradle中的依赖声明:

compile group: 'org.bytedeco', name: 'javacv', version: '1.1'
compile group: 'org.bytedeco.javacpp-presets', name: 'opencv', version: '3.0.0-1.1', classifier: "windows-x86"

关于Java:从 BufferedImage 到 IplImage,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8368078/

相关文章:

JAVA OOP继承树

java.lang.RuntimeException : Unable to instantiate activity ComponentInfo java build path

java - 带有嵌入式 tomcat 的 Spring Boot 应用程序

opencv - 更好地转换为灰色?

c++ - 是否有任何关于如何使用 OpenCV HAL 来加速我的代码的信息或示例或教程?

python - OpenCV像素 block 检测(检测白色像素 block )

c++ - OpenCV 图像处理

java - 获取http变量JSF

java - JSP将 "rendered"图像另存为

opencv - 绘制检测到的对象OpenCV?