pythonでつくる数字判別アプリで6桁の数字を判別させてみた

![ff.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/969670/123354ad-b961-7609-423e-9a4a930ffcef.png)


はじめまして。
devと申します。

Qiitaへの投稿は初めてです。
この投稿がどなたかの役に立てばと思い、記事を作成しています。

今回はOCRを利用した数字判別アプリについてご紹介します。

<h2>アプリについて</h2>
ごく単純ですが、入力された画像をOCR(Google cloud vision api)で判別し、答えを返すWebアプリです。


<h3>作成理由</h3>
車のスピードメーターみたいなアナログなメーターを読み取れたら便利ですよね。
サービスとしては既に提供されているようだけど、「自分も少し近いことしてみたいなぁ」と思ったのが発端。

でもメーターの読み取りって難易度高そう。初めてのアプリなので、「まずはアナログな走行距離数字を読み取ってみよう！」という訳で数字の識別にチャレンジです。


<h3>基本機能</h3>
6桁数字の画像を選んでポチれば、読み取った数字をWeb画面に返します。

例えばこんな画像を読み取れます。
![sample1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/969670/0ad8d69e-8a4c-b673-b4e3-6442a6aa0fda.png)
![sample2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/969670/5604740d-f4a7-790a-2195-9394902f2828.png)


作って感じたのは<b>「Google cloud vision api」を使えばこんな簡単に高精度のアプリができるんだ！</b>ってことですね。

簡単ながら、精度もGOOD(le)！


しかも、数字だけでなく文字も判定できちゃいます。

だからこんなのもOK

![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/969670/00da04b4-9113-bda7-098d-125ab8a0d1c8.png)
![あ1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/969670/68db0816-c549-3c6b-b66c-a07693d29928.png)


<h3>でも何に使えるの？</h3>
お遊びアプリなので、このままでは「何にも使えません」　笑


発展形としては「書類NOの通し番号読み取り」や「伝票読み取り」にも使えるかと思います。

別に「Google cloud vision api」を使わずとも「Tesseract」や、その他フリーソフトでもOCR機能は実現できますね。



<h2>実装環境</h2>
html
css
Flask

<h3>選択肢</h3>
数字を読み取るために、以下の2つを検討しました。
・mnistの学習データ
・OCR

<h4>mnistデータセットを使って学習させる</h4>
mnistの場合、学習させるのは比較的容易です。
ただし桁数を表現するために、1桁目、2桁目といった物体検出が必要。

学習データは以下のような方法で保存できます。
■[参考]

```python:mnist学習のサンプルコード
from keras.datasets import mnist
from keras.models import Sequential, load_model
from keras.layers.core import Dense, Activation, Flatten
from keras.layers import Conv2D, MaxPooling2D, Dropout, Reshape
from keras.utils import np_utils
import numpy as np
(X_train, y_train),(X_test, y_test) = mnist.load_data()
X_train = np.array(X_train)/255
X_test = np.array(X_test)/255
y_train = np_utils.to_categorical(y_train)
y_test = np_utils.to_categorical(y_test)
model = Sequential()
model.add(Reshape((28,28,1),input_shape=(28,28)))
model.add(Conv2D(32,(3,3)))
model.add(Activation("relu"))
model.add(Conv2D(32,(3,3)))
model.add(Activation("relu"))
model.add(MaxPooling2D((2,2)))
model.add(Dropout(0.5))
model.add(Conv2D(16,(3,3)))
model.add(Activation("relu"))
model.add(MaxPooling2D((2,2)))
model.add(Dropout(0.5))
model.add(Flatten())
model.add(Dense(784))
model.add(Activation("relu"))
model.add(Dropout(0.5))
model.add(Dense(10))
model.add(Activation("softmax"))
model.compile(loss="categorical_crossentropy", optimizer="sgd", metrics=["accuracy"])
hist = model.fit(X_train, y_train, batch_size=200,
                 verbose=1, epochs=1, validation_split=0.1)
score = model.evaluate(X_test, y_test, verbose=1)
print('Test loss:', score[0])
print("test accuracy：", score[1])
model.save("C:/test/mnist_main.h5")
```

<h4>OCRを使って判別させる</h4>
何よりも手っ取り早いのがOCR。
GoogleのAPIを使うので精度も高く、作りこむ必要がありません。
桁数も気にせず読み取ってくれます。

用途次第では十分利用できますね！
※「Google cloud vision api」実装は[こちら](https://qiita.com/yoshi_yast/items/bd5e1e91ac9f64157203 "こちら")を参考にさせていただきました。

<h2>精度</h2>
精度を確認するために1000文字の数字を確認しました。
![1000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/969670/e4dba485-359e-b3d8-c1e5-e5c1c32ff511.png)

■条件
画像サイズ:1,024x768
フォント:游ゴシック
文字サイズ:16x23pixel(WH)
文字間:5pixel
行間:11pix3l

■結果
精度:100%
※文字サイズを半分にしても100%でした。

高い精度を出すことができたので、次は同条件でフォントを変えてみました。

■結果
mspゴシック:100%
msp明朝:100%
fugaz one:100%
ink free:99.9%
np b:99.6%

どれも高い精度ですが、「np b」フォントは他に比べて精度が落ちました。
なぜでしょうか？

![np-b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/969670/3f9de1bb-0b8f-19a5-4571-877a8358d557.png)


原因は「1」の形です。
「｜(パイプ)」や「I(アイ)」と認識されている箇所がありました。

■その他1
ink freeは下記のような手書き風文字ですが、精度は99.9%と高かったことから、標準的なフォントには対応しているのかもしれません。
![ink_free.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/969670/49bdf037-c96d-10f5-268d-965d1b5f82b7.png)


■その他2
下記のような文字間、行間を1pixelにした文字も別途試してみましたが、結果は100%。
※文字サイズ:12x14pixel(WH)
![1000_marin1_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/969670/fc19e64e-fe54-1c21-e7a9-5d30a1085f77.png)

うん。十分使えますね！


精度に関してはWeb上にたくさん情報がありますので、いろいろ探してみましょう。

＜参考にさせていただいた記事＞
(https://qiita.com/saken649/items/4bfd215bf943c36a52ab "画像による文字識別の違い")
(https://qiita.com/se_fy/items/963b295bbd13101c044b "画像サイズによるスループット")


<h2>Google Cloud Vision APIについて</h2>
設定自体はとても簡単。
APIkeyを取得すれば利用できます。
※請求に関する設定は有効にしないとエラーを返し、利用できないのでご注意ください。

料金自体もかなり安いようです。
月1,000回(ユニット)までは無料。
以降は1,000ユニット毎に1.5$。回数レンジに応じて料金がかわります。

お小遣い程度で運用できそうですね。
ですが、念のた利用料のアラート設定は有効にしておきましょう。
(事故防止)

<h2>今後の発展</h2>
業務に合わせて、書類の通しNoを読み取る機能が実装できると役に立ちそうだなと思ってます。
空き時間をみて学習させてみるつもりです。