2.
可以看出在train-images.idx3-ubyte中,第壹個數為32位的整數(魔數,圖片類型的數),第二個數為32位的整數(圖片的個數),第三和第四個也是32為的整數(分別代表圖片的行數和列數),接下來的都是壹個字節的無符號數(即像素,值域為0~255),因此,我們只需要依次獲取魔數和圖片的個數,然後獲取圖片的長和寬,最後逐個像素讀取就可以了。
3.如何使用Python解析數據呢? 首先需要安裝python的圖形處理庫PIL,這個庫支持像素級別的圖像處理,對於學習數字圖像處理有很大的幫助。安裝完成之後,就可以進行圖像的解析了。看壹下代碼:
4.首先打開文件,然後分別讀取魔數,圖片個數,以及行數和列數,在struct中,可以看到,使用了’>IIII’,這是什麽意思呢?意思就是使用大端規則,讀取四個整形數(Integer),如果要讀取壹個字節,則可以用’>B’(當然,這裏用沒用大端規則都是壹樣的,因此只有兩個或兩個以上的字節才有用)。
5.什麽是大端規則呢?不懂的可以百度壹下,這個不再贅述(/link?url=Bgg8b0vRr3b_SeGyOl8U4DmAbIQT9swGuNtD_21ctEI_NliqsQ-mKF73YT90EILF2EQy50mEua_M4z6Cma3rmK)
6.然後對於每張圖片,先創建壹張空白的圖片,其中的’L’代表這張圖片是灰度圖,最後逐個像素讀取,然後寫進空白圖片裏,最後保存圖片,就可以了
7.再來看壹下mnist標簽的數據結構:
可以發現,與上面的非常相似,只不過這裏每壹個字節變成了標簽而已(標簽大小為0~9)
8.好了,通過上述講解,最後我們可以通過python將mnist解析出來了,看壹下效果:
程序源代碼如下:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from PIL import Image
import struct
def read_image(filename):
f = open(filename, 'rb')
index = 0
buf = f.read()
f.close()
magic, images, rows, columns = struct.unpack_from('>IIII' , buf , index)
index += struct.calcsize('>IIII')
for i in xrange(images):
#for i in xrange(2000):
image = Image.new('L', (columns, rows))
for x in xrange(rows):
for y in xrange(columns):
image.putpixel((y, x), int(struct.unpack_from('>B', buf, index)[0]))
index += struct.calcsize('>B')
print 'save ' + str(i) + 'image'
image.save('test/' + str(i) + '.png')
def read_label(filename, saveFilename):
f = open(filename, 'rb')
index = 0
buf = f.read()
f.close()
magic, labels = struct.unpack_from('>II' , buf , index)
index += struct.calcsize('>II')
labelArr = [0] * labels
#labelArr = [0] * 2000
for x in xrange(labels):
#for x in xrange(2000):
labelArr[x] = int(struct.unpack_from('>B', buf, index)[0])
index += struct.calcsize('>B')
save = open(saveFilename, 'w')
save.write(','.join(map(lambda x: str(x), labelArr)))
save.write('\n')
save.close()
print 'save labels success'
if __name__ == '__main__':
read_image('t10k-images.idx3-ubyte')
read_label('t10k-labels.idx1-ubyte', 'test/label.txt')