# 学習データの用意
import struct
from PIL import Image, ImageEnhance
import glob, os
# 出力ディレクトリの用意
outdir = '/content/drive/My Drive/画像認識/DL_data/png-etl1/'
if not os.path.exists(outdir):
os.mkdir(outdir)
# ETL1ディレクトリ以下のファイルを処理する
files = glob.glob('/content/drive/My Drive/画像認識/DL_data/ETL1/*')
for fname in files:
if fname == "/content/drive/My Drive/画像認識/DL_data/ETL1/ETL1INFO":
continue
print(fname)
# ETL1のデータファイルを開く
f = open(fname, 'rb')
f.seek(0)
while True:
# メタデータ+画像データの組を1つずつ読む
s = f.read(2052)
if not s:
break
# バイナリデータなので、Pythonが理解できるように抽出
r = struct.unpack('>H2sH6BI4H4B4x2016s4x', s)
code_ascii = r[1]
code_jis = r[3]
# 画像データとして取り出す
iF = Image.frombytes('F', (64, 63), r[18], 'bit', 4)
iP = iF.convert('L')
# 画像を鮮明にして保存
dir = outdir + '/' + str(code_jis)
if not os.path.exists(dir):
os.mkdir(dir)
fn = "{0:02x}-{1:02x}-{2:04x}.png".format(code_jis, r[0], r[2])
fullpath = dir + '/' + fn
if os.path.exists(fullpath):
continue
enhancer = ImageEnhance.Brightness(iP)
iE = enhancer.enhance(16)
iE.save(fullpath, 'PNG')
print('OK')
f.close()
# ダウンロード画像のリサイズ
import numpy as np
import cv2
import matplotlib.pyplot as plt
import pickle
import glob, os
# 保存先や画像サイズの指定
out_dir = "/content/drive/My Drive/画像認識/DL_data/png-etl1" # 画像データがあるディレクトリ
im_size = 25 # 画像サイズ
save_file = out_dir + "/katakana.pickle" # 保存先
plt.figure(figsize=(9, 17)) # notebookeへの出力画像を大きくする
# カタカナの画像が入っているディレクトリから画像を取得
kanadir = list(range(177, 220+1))
kanadir.append(166) # ヲ
kanadir.append(221) # ン
result = []
for i, code in enumerate(kanadir):
img_dir = out_dir + '/' + str(code)
fs = glob.glob(img_dir + '/*')
print('dir=', img_dir)
# 画像を読み込んでグレイスケールに変換しリサイズ
for j, f in enumerate(fs):
img = cv2.imread(f)
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img = cv2.resize(img_gray, (im_size, im_size))
result.append([i, img])
# notebookに画像出力
if j == 3:
plt.subplot(11, 5, i+1)
plt.title(str(i))
plt.imshow(img, cmap='gray')
# ラベルと画像のデータを保存
f = open(save_file, "wb")
pickle.dump(result, f)
f.close()
plt.show()
print('OK')
import numpy as np
import cv2, pickle
from sklearn.model_selection import train_test_split
import keras
# データファイルと画像サイズの指定
data_file = "/content/drive/My Drive/画像認識/DL_data/png-etl1/katakana.pickle"
im_size = 25
in_size = im_size * im_size
out_size = 46 # ア〜ンまでの文字数
# 保存した画像データ一覧を読み込む
data = pickle.load(open(data_file, "rb"))
data[0][1].shape
print(np.min(data[0][1]))
print(np.max(data[0][1]))
data[0][0]
# アのインデックスは0
# 画像データを1次元化し、0-1の範囲に正規化
y = []
x = []
for d in data:
(num, img) = d # インデックスと画像データ取り出し
img = img.reshape(-1).astype('float') / 255 # 1次元化して正規化
y.append(keras.utils.to_categorical(num, out_size))
x.append(img)
x = np.array(x)
y = np.array(y)
x.shape
y.shape
# 学習用とテスト用に分離
x_train, x_test, y_train, y_test = train_test_split(
x, y, test_size=0.2, shuffle=True
)
# モデル定義
Dense = keras.layers.Dense
model = keras.models.Sequential()
model.add(Dense(512, activation='relu', input_shape=(in_size,)))
model.add(Dense(out_size, activation='softmax'))
# コンパイル後、学習
model.compile(
loss='categorical_crossentropy',
optimizer='adam',
metrics=['accuracy']
)
model.fit(x_train, y_train,
batch_size=20,
epochs=50,
verbose=1,
validation_data=(x_test, y_test)
)
# 評価
score = model.evaluate(x_test, y_test, verbose=1)
print(score[1],' : ', score[0])
import numpy as np
import cv2, pickle
from sklearn.model_selection import train_test_split
import keras
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras.optimizers import RMSprop
from keras.datasets import mnist
import matplotlib.pyplot as plt
# データファイルと画像サイズの指定
data_file = "/content/drive/My Drive/画像認識/DL_data/png-etl1/katakana.pickle"
im_size = 25
out_size = 46 # ア〜ンまでの文字数
im_color = 1 # 画像の色空間/グレイスケール
in_shape = (im_size, im_size, im_color)
# カタカナ画像のデータセット読み込み
f = open(data_file, "rb")
data = pickle.load(f)
f.close()
# 各画像データを3次元に変換し、正規化
y = []
x = []
for d in data:
(num, img) = d
img = img.astype('float').reshape(im_size, im_size, im_color) / 255
y.append(keras.utils.to_categorical(num, out_size))
x.append(img)
x = np.array(x)
y = np.array(y)
x[0].shape
# データ分割
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2)
# CNNモデル定義
model = Sequential()
model.add(Conv2D(32,
kernel_size=(3,3),
activation='relu',
input_shape=in_shape))
model.add(Conv2D(64, (3,3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(out_size, activation='softmax'))
# コンパイル
model.compile(
loss='categorical_crossentropy',
optimizer=RMSprop(),
metrics=['accuracy']
)
# 学習
hist = model.fit(
x_train, y_train,
batch_size=128,
epochs=12,
verbose=1,
validation_data=(x_test, y_test)
)
# 評価
score = model.evaluate(x_test, y_test, verbose=1)
print(score[1], ' : ', score[0])
# 学習推移をプロット
# 正解率
plt.plot(hist.history['accuracy'])
plt.plot(hist.history['val_accuracy'])
plt.title('Accuracy')
plt.legend(['train', 'test'], loc='upper left')
plt.show()
# ロス
plt.plot(hist.history['loss'])
plt.plot(hist.history['val_loss'])
plt.title('Loss')
plt.legend(['train', 'test'], loc='upper left')
plt.show()
model.summary()