如何将图片做成类似train-images-idx3-ubyte形式
使用过caffe2的人都知道,caffe2可以对图像进行处理,但是caffe2并不接受直接使用图片进行训练。在使用之前,需要将图片保存成一种特殊的二进制形式,图片文件和二进制文件之间的转换存在一种固定的协议。
如何把一个二进制文件解析成图片文件,在这篇博http://blog.csdn.net/u014046170/article/details/47445919中有详尽的描述,现在我们实现的是如何通过图片做成二进制文件。
# -*- coding: utf-8 -*-
from PIL import Image
import struct
import os
imageFilePath="H:\\file1\\"
numOfImage=1187
numOfLabel=1187
rows=60
columns=90
imageUbyte="train-images-idx3-ubyte"
labelUbyte="train-labels-idx1-ubyte"
label="label.txt"
def readImage():
print os.getcwd()
file=open(imageUbyte,"wb")
file.write(struct.pack('i',50855936))
file.write(struct.pack('i',numOfImage))
file.write(struct.pack('i',rows))
file.write(struct.pack('i',columns))
for i in xrange(numOfImage):
lene=Image.open(imageFilePath+str(i+1000)+".jpg")
#lene=lene.convert("L")
#if not os.path.exists()
for j in xrange(rows):
for k in xrange(columns):
file.write(struct.pack('B',lene.getpixel((k,j))))
#print lene.mode,lene.size,lene.format
file.close()
print("create "+imageUbyte+" success")
def readLabel():
fileubyte=open(labelUbyte,"wb")
filetxt=open(label,"r")
fileubyte.write(struct.pack('i',17301504))
fileubyte.write(struct.pack('i',numOfLabel))
for i in xrange(numOfLabel):
initdata=filetxt.read(1)
fileubyte.write(struct.pack('B',int(initdata)))
filetxt.read(1)
fileubyte.close()
filetxt.close()
print("create "+labelUbyte+" success")
if __name__ == '__main__':
readImage()
readLabel()
print("create files finished")
需要注意,当前目录需要有一个file1文件夹保存着jpg图片文件,numOfImage和numOfLabel表示图片数量和标签数量,label.txt表示标签文件,在当前目录下。rows和columns表示图片像素数量。
需要注意,如果是在大端法机器上生成的文件才是符合文件转换协议的,目前大多数intel机器是小端法,在这种情况下,生成的文件需要作部分改变才能满足要求,train-images-idx3-ubyte文件的第5-16个字节是小端法生成的,所以需要train-images-idx3-ubyte的第5-16字节中,每相邻4个字节一组,每组中第1个字节和第4个字节交换,第2个字节和第3个字节交换,才能满足要求。在train-labels-idx1-ubyte中是第5-8字节中第1个字节和第4个字节交换,第2个字节和第3个字节交换,才能满足要求。