Java:IlapImage的BufferedImage

时间:2011-12-03 13:50:34

标签: 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)

3 个答案:

答案 0 :(得分:5)

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

.GroupBy()

具体来说,这些是我context.Set<Person>() .Join(context.Set<Address>(), x => x.Id, x => x.PersonId, (person, addresses) => new { Person = person, Addresses = addresses.DefaultIfEmpty() }) .GroupBy(x => x.Person, x => x.Addresses); 中的依赖声明:

IplImage toIplImage(BufferedImage bufImage) {

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

答案 1 :(得分:1)

似乎从bufferedImage到Iplimage的转换完美无缺。问题是显示图像。

而不是使用

frame.showImage(test);

我用过

cvShowImage("test", test);

它完美无缺。

答案 2 :(得分:0)

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

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

效果很好。