Q L*_*Liu 5 java file-io bitmap
我用Java构建了一个图像分类器,我想针对这里提供的图像进行测试:http://yann.lecun.com/exdb/mnist/
不幸的是,如果您下载train-images-idx3-ubyte.gz或任何其他3个文件,它们都是文件类型:.idx1-ubyte
第一个问题:我想知道是否有人可以给我关于如何将.idx1-ubyte转换为位图(.bmp)文件的说明?
第二个问题:或者我一般如何阅读这些文件?
有关IDX文件格式的信息:IDX文件格式是各种数字类型的向量和多维矩阵的简单格式.基本格式是:
magic number
size in dimension 0
size in dimension 1
size in dimension 2
.....
size in dimension N
data
Run Code Online (Sandbox Code Playgroud)
幻数是一个整数(MSB优先).前2个字节始终为0.
第三个字节编码数据的类型:
0x08: unsigned byte
0x09: signed byte
0x0B: short (2 bytes)
0x0C: int (4 bytes)
0x0D: float (4 bytes)
0x0E: double (8 bytes)
Run Code Online (Sandbox Code Playgroud)
第4个字节编码向量/矩阵的维数:1表示向量,2表示矩阵....
每个维度的大小为4字节整数(MSB优先,高端,与大多数非英特尔处理器一样).
数据存储在C数组中,即最后一维中的索引变化最快.
Ray*_*eeA 11
非常直截了当,正如WPrecht所说:"URL描述了你必须解码的格式".这是我的idx文件的ImageSet导出器,不是很干净,但它做了它必须做的事情.
public class IdxReader {
public static void main(String[] args) {
// TODO Auto-generated method stub
FileInputStream inImage = null;
FileInputStream inLabel = null;
String inputImagePath = "CBIR_Project/imagesRaw/MNIST/train-images-idx3-ubyte";
String inputLabelPath = "CBIR_Project/imagesRaw/MNIST/train-labels-idx1-ubyte";
String outputPath = "CBIR_Project/images/MNIST_Database_ARGB/";
int[] hashMap = new int[10];
try {
inImage = new FileInputStream(inputImagePath);
inLabel = new FileInputStream(inputLabelPath);
int magicNumberImages = (inImage.read() << 24) | (inImage.read() << 16) | (inImage.read() << 8) | (inImage.read());
int numberOfImages = (inImage.read() << 24) | (inImage.read() << 16) | (inImage.read() << 8) | (inImage.read());
int numberOfRows = (inImage.read() << 24) | (inImage.read() << 16) | (inImage.read() << 8) | (inImage.read());
int numberOfColumns = (inImage.read() << 24) | (inImage.read() << 16) | (inImage.read() << 8) | (inImage.read());
int magicNumberLabels = (inLabel.read() << 24) | (inLabel.read() << 16) | (inLabel.read() << 8) | (inLabel.read());
int numberOfLabels = (inLabel.read() << 24) | (inLabel.read() << 16) | (inLabel.read() << 8) | (inLabel.read());
BufferedImage image = new BufferedImage(numberOfColumns, numberOfRows, BufferedImage.TYPE_INT_ARGB);
int numberOfPixels = numberOfRows * numberOfColumns;
int[] imgPixels = new int[numberOfPixels];
for(int i = 0; i < numberOfImages; i++) {
if(i % 100 == 0) {System.out.println("Number of images extracted: " + i);}
for(int p = 0; p < numberOfPixels; p++) {
int gray = 255 - inImage.read();
imgPixels[p] = 0xFF000000 | (gray<<16) | (gray<<8) | gray;
}
image.setRGB(0, 0, numberOfColumns, numberOfRows, imgPixels, 0, numberOfColumns);
int label = inLabel.read();
hashMap[label]++;
File outputfile = new File(outputPath + label + "_0" + hashMap[label] + ".png");
ImageIO.write(image, "png", outputfile);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (inImage != null) {
try {
inImage.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (inLabel != null) {
try {
inLabel.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
URL 描述了您必须解码的格式,并且他们提到它是非标准的,因此明显的 Google 搜索不会出现任何使用代码。然而,它非常简单,带有标题,后跟 0-255 灰度值的 28x28 像素矩阵。
读出数据后(记住要注意字节顺序),创建 BMP 文件就很简单了。
我向您推荐以下文章:
他们的问题是关于颜色的,但是他们的代码已经适用于灰度,这就是您所需要的,您应该能够从该片段中得到一些东西。