Java: BufferedImage to IplImage



当我尝试转换 buffereimage 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"

从buffereimage到Iplimage的转换似乎完成得很完美。问题是图像的显示。

不使用

frame.showImage(test);

i used

cvShowImage("test", test);

效果很好

depthImg.createFrom(bimg)IplImage类的静态方法,尝试用

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

效果很好

最新更新