当我尝试将 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)
答案 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);
效果很好。