How to pass a number of java.awt.image.BufferedImage's to Matlab
I'm writing a Java application for real-time image processing. I'd like to be able to validate the algorithms used or present data I acquire in the Java app with Matlab afterwar开发者_Go百科ds. In the Java app I'm using java.awt.image.BufferedImage
's to process data internally. The program usually runs about 1-2 minutes and grabs data at 25Hz, 160x120 pixels 8-bit grayscale, so each frame raster weights 19200 bytes, making it 30MB of acquired data per minute.
What's the best way to make this data available to Matlab?
My aim is to have a Matlab array with all the frames in it at the end. I've considered storing frames in an uncompressed avi (which I don't know how to do yet), but maybe there is an easier, established, way of doing it? I've already read this, but wouldn't know how to use it yet or if this is the right way to handle multiple frames.
Thanks for any help.
You should be able to store the images in an array in memory - as long as you make sure you give the JVM enough heap memory (-Xmx option to java).
Once you have captured the images, you can write them to disk using, e.g.: ImageIO.write(bufferedImage, "png", file)
If you put them all in the directory with a simple filename e.g. "img-00001.png", "img-00002.png", then you should be able to load in the sequence of images in Matlab.
I think I found a pretty clean solution for my problem, so I'll publish it as an answer myself. There is a simple open source java framework for .mat file exporting called JMatIO (also available at SourceForge, but here be sure to download the newest version 0.2). It allows to easily export data in .mat format which is then available to Matlab in a straightforward manner. If you have any problems using it, due to little documentation, download the source from here:
svn co https://jmatio.svn.sourceforge.net/svnroot/jmatio jmatio
and take a look at unit tests, they show how it can be used.
Back to my problem: I needed to upload a burst of frames to Matlab. An image in Matlab is a 2D matrix, so a burst of them would be a 3D matrix. I didn't figure out how to export Java arrays as 3D martices in Matlab though, so I exported each java.awt.image.BufferedImage
as a row in Matlab, which is easily done. It takes some trivial data manipulation in Matlab to represent the data as one would want to afterwards (matrix transpose and reshape function). Take a look at the code snippet below. The function export will buffer 100 frames and if called again after that it'll export them to a file with 8-bit color depth.
public class MatFileExporter {
private BufferedImage frame;
private int[][] frames;
private int frameSize;
private int numFrames = 100;
private int frameNumber = 0;
protected void export() {
//This will only work with 8-bit coded SampleModels, change if needed
if (frames == null) {
frameSize = frame.getData().getWidth() * frame.getHeight();
frames = new int[numFrames][frameSize];
}
if (frameNumber < numFrames) {
frame.getData().getPixels(0, 0, frame.getWidth(),
frame.getHeight(), frames[frameNumber++]);
} else {
byte[][] framesByte = new byte[numFrames][frameSize];
for (int i=0; i<numFrames; i++) {
for (int j=0; j<frameSize; j++) {
framesByte[i][j] = (byte) frames[i][j];
}
}
MLUInt8 array = new MLUInt8("frames", framesByte);
ArrayList<MLArray> list = new ArrayList<MLArray>();
list.add(array);
new MatFileWriter( "frames.mat", list );
}
}
}
Feel free to use and change it, hope it helps someone. Incremental .mat-file writing is also supported, consult the source code for that.
精彩评论