Java: BufferedImage转换为IplImage

4
当我尝试将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)
3个回答

5
我正在使用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"

1

看起来从BufferedImage到IplImage的转换已经完美完成了。问题在于图像的显示。

不要使用

frame.showImage(test);

我使用了

cvShowImage("test", test);

它完美地运行。


0

depthImg.createFrom(bimg)IplImage 类的静态方法,请尝试将其替换为

depthImg = IplImage.createFrom(bimg); 
frame.showImage(depthImg);

它完美地工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接