我用 Java 构建了一个图像分类器,我想针对此处提供的图像进行测试:http://yann.lecun.com/exdb/mnist/
不幸的是,如果您下载 train-images-idx3-ubyte.gz 或其他 3 个文件中的任何一个,它们都是文件类型:.idx1-ubyte
第一个问题: 我想知道是否有人可以指导我如何将 .idx1-ubyte 转换为位图 (.bmp) 文件?
第二个问题: 或者我一般如何阅读这些文件?
关于 IDX 文件格式的信息: IDX 文件格式是一种用于各种数值类型的 vector 和多维矩阵的简单格式。 基本格式为:
magic number
size in dimension 0
size in dimension 1
size in dimension 2
.....
size in dimension N
data
魔数(Magic Number)是一个整数(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)
第 4 个字节编码 vector/矩阵的维数:1 表示 vector ,2 表示矩阵....
每个维度的大小都是 4 字节整数(MSB 优先,高位优先,就像在大多数非英特尔处理器中一样)。
数据的存储方式类似于 C 数组,即最后一个维度的索引变化最快。
最佳答案
非常直截了当,正如 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();
}
}
}
}
}
关于java - 在 Java 中读取 IDX 文件类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17279049/