MNIST

ETL文字データベース (etlcdb)を画像に変換する

日本版MNISTとも言えるETL文字データベース

を、機械学習の学習・モデルの教育などに使用されている方も多いと思います。

ですが、こちらの配布データは古き良き時代を思い出させるバイナリファイルで、モダンな私たちが扱うにはいささか苦痛を伴います。

にETL8B用の解説がありますが、他のデータに対するモノが見つかりませんでした。

きっと、いろんな人が沢山の車輪を作ってきたことと思うので、超絶雑なコードですが、メモ代わりに上げておきます。

元々のデータは64 x 63と中途半端なので、64 x 64または128 x 128にresizeしてもよいかも。その辺はお好みで。

要Python3, Pillow, Numpy。


  • ETL1, 6, 7兼用

「あ」と「A」が両方「A」というディレクトリに入ったりするが、そんなに多くないから(A, I, U, E, O, N)、適当に手動で修正してください。


#!/usr/bin/env python3

import struct
import numpy as np
import os
import sys
from PIL import Image

assert(len(sys.argv) == 2)
filename = sys.argv[1]

RECORD_SIZE = 2052
i = 0
print("Reading {}".format(filename))
with open(filename, 'rb') as f:
while True:
s = f.read(RECORD_SIZE)
if s is None or len(s) < RECORD_SIZE:
break
r = struct.unpack(">H2sHBBBBBBIHHHHBBBBHH2016s4x", s)
img = Image.frombytes('F', (64, 63), r[20], 'bit', (4, 0))
img = img.convert('L')
img = img.point(lambda x: 255 - (x << 4))
i = i + 1
dirname = r[1].decode('utf-8')
dirname = dirname.replace('\0', '')
dirname = dirname.replace(' ', '')
dirname = dirname.replace('\\', 'YEN')
dirname = dirname.replace('+', 'PLUS')
dirname = dirname.replace('-', 'MINUS')
dirname = dirname.replace('*', 'ASTERISK')
try:
os.makedirs(f"extract/{dirname}")
except:
pass
imagefile = f"extract/{dirname}/{filename}_{i:0>6}.png"
print(imagefile)
img.save(imagefile)


  • ETL 8G, 9G用

JISこーど…。


#!/usr/bin/env python3

import struct
import numpy as np
import os
import sys
from PIL import Image

assert(len(sys.argv) == 2)
filename = sys.argv[1]

RECORD_SIZE = 8199
i = 0
print("Reading {}".format(filename))
with open(filename, 'rb') as f:
while True:
s = f.read(RECORD_SIZE)
if s is None or len(s) < RECORD_SIZE:
break
r = struct.unpack(">HH8sIBBBBHHHHBB30x8128s11x", s)
img = Image.frombytes('F', (128, 127), r[14], 'bit', (4, 0))
img = img.convert('L')
img = img.point(lambda x: 255 - (x << 4))
i = i + 1
dirname = b'\x1b$B' + r[1].to_bytes(2, 'big') + b'\x1b(B'
dirname = dirname.decode("iso-2022-jp")
try:
os.makedirs(f"extract/{dirname}")
except:
pass
imagefile = f"extract/{dirname}/{filename}_{i:0>6}.png"
print(imagefile)
img.save(imagefile)