【4桁】連続数字画像認識プログラミング入門(Python・OpenCV・SVM)

【4桁】連続数字画像認識プログラミング入門(Python・OpenCV・SVM)

 

動画:【4桁に挑戦】手書き連続数字画像認識プログラミング入門(Python・OpenCV・SVM)

 


視聴時間:2分36秒

機械学習モデルのサポートベクターマシーン(SVM:support vector machine)で手書き数字画像を学習後、800 × 200(横800 × 縦200)の画像に4等分に数字が配置されている場合に活用できる、4桁の数字を認識できる簡単なプログラムを作成してみました。

 




 

【追記:2021年3月3日】

初期のコードは、力ずくな感じのするプログラムでしたが、予測する処理を関数化しfor文でシンプルなプログラムにしたコードも追加しておきました。日々の学習にお役立てください。

【追記:2022年1月11日】

コメント頂きましたので「2桁」版の数字認識プログラムへの改変例のサンプルコードを公開しておきました。
2桁版のプログラム【手書き連続数字画像認識プログラム:Pythonサンプルコード】」を参照ください。

【追記:2022年1月15日】

CSV形式のファイルに、出力結果を保存できるサンプルコードも公開しておきました。
CSV形式ファイルに結果を保存版【手書き連続数字画像認識プログラム:Pythonサンプルコード】」を参照ください。

 

今回のプログラムは、以前YouTubeに投稿させていただいた以下の数字画像認識プログラムを改変して作っています。
興味のある方は、併せてご活用ください。

Pythonで機械学習・人工知能(AI)プログラミング入門 | scikit-learn SVM 学習データの確認〜画像認識(数値予測)編 by RehabC – デジタルで遊ぶ。(YouTube動画)

 

 

サンプル画像・サンプルコードリンク:手書き連続数字画像認識プログラム

 

【4桁】連続数字画像認識プログラミング入門(Python・OpenCV・SVM)で試せるサンプル画像です。
動画のデモで利用した画像です。

 


「2桁」版の数字認識プログラムで使う用のサンプル画像です。
【2桁版の手書き数字画像認識用プログラム】のコードで使用します。

 

すぐに使えるGoogle Colaboratoryサンプルコードリンク

SVM-4digits-recognition.ipynb | Google Colaboratory
(手書き連続数字画像認識プログラム)

 

数字画像認識 – 4桁の連続数字認識(連続文字認識):
800 × 200(横800 × 縦200)の画像を4等分し、個別に認識した結果をまとめて表示させることで4桁の連続数字を認識できるプログラムです。

print(‘認識結果(予測結果):’, int(n1), int(n2), ‘.’ ,int(n3), int(n4))
などとプログラムを変更すると小数点も入れられます。

学習データが手書き数字文字のため、デジタルの数字(7セグメント)は認識しにくいかもしれません。
追記 – はじめ
2021年2月12日 CNNで7セグメントのオリジナル学習済みモデルを作成できるプログラムなどを作成中です。お楽しみに♪

7セグメントのデジタル数字画像認識プログラム - 4桁の連続数字認識(連続文字認識)
2021年2月13日にとりあえずの形はできました。
今後チュートリアルを作ります。

→ 2021年2月14日 記事を公開しました。
【4桁 – 7セグメント編】連続デジタル数字画像認識プログラミング入門(Python・OpenCV・Keras・CNN)

追記 – おわり
 

・機械学習モデル:SVM(Support Vector Machine:サポートベクターマシン )
・データセット:手書き数字画像

 

 

バージョン情報(Python・各種ライブラリ)

 

 

python 3.6.9
sklearn(scikit-learn)0.22.2.post1
opencv-python 4.1.2
PIL 7.0.0
matplotlib 3.2.2

ローカル環境で、指定したバージョンのインストールが難しい場合、Python以外は最新のバージョンを入れてみてください。

 

 

【プログラムのライセンス】

 

 

The MIT License

Copyright 2020 child programmer

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

 

 

初期のプログラム【4桁の手書き連続数字画像認識プログラム:Pythonサンプルコード】

 

 

OpenCVの座標系とトリミングの関係

 

import sklearn.datasets
import sklearn.svm
import numpy
import PIL.Image
import matplotlib.pyplot as plt
import cv2

# 画像の読み込みとリサイズ(画像を横の幅800・高さ200ピクセルにリサイズする場合のプログラム例です)
img = cv2.imread('4508_800*200.png') #ここに数字画像認識をしたい画像を入れます(事前に4等分を考慮して撮影した画像を利用)
img = cv2.resize(img, (800,  200)) # サイズが調整されていない画像を入れた場合のエラー予防を追加
#img = cv2.resize(img, (400,  100)) 


# 画像のトリミング [y1:y2, x1:x2]  (img = cv2.resize(img, (800,  200)) を使った場合のプログラム例
data1 = img[0:200, 0:200]     #yの範囲(縦)が0〜200・xの範囲(横)が0〜200までをトリミング
data2 = img[0:200, 200:400] #yの範囲(縦)が0〜200・xの範囲(横)が200〜400までをトリミング
data3 = img[0:200, 400:600] #yの範囲(縦)が0〜200・xの範囲(横)が400〜600までをトリミング
data4 = img[0:200, 600:800] #yの範囲(縦)が0〜200・xの範囲(横)が600〜800までをトリミング

#(img = cv2.resize(img, (400,  100)) を使った場合のプログラム例
#data1 = img[0:100, 0:100]     #yの範囲(縦)が0〜100・xの範囲(横)が0〜100までをトリミング
#data2 = img[0:100, 100:200] #yの範囲(縦)が0〜100・xの範囲(横)が100〜200までをトリミング
#data3 = img[0:100, 200:300] #yの範囲(縦)が0〜100・xの範囲(横)が200〜300までをトリミング
#data4 = img[0:100, 300:400] #yの範囲(縦)が0〜100・xの範囲(横)が300〜400までをトリミング


# トリミングした画像を保存
cv2.imwrite('data1.png', data1)
cv2.imwrite('data2.png', data2)
cv2.imwrite('data3.png', data3)
cv2.imwrite('data4.png', data4)


# 4桁目の画像の数値リスト化(データ化)と、手書き数字のデータセットでの学習と予測
gazou = PIL.Image.open('data1.png').convert("L")
gazou = gazou.resize((8,8),PIL.Image.ANTIALIAS)
suuti = numpy.asarray(gazou, dtype = float)
suuti = numpy.floor(16 - 16 * (suuti / 256))
suuti = suuti.flatten()

suuji = sklearn.datasets.load_digits()
ai = sklearn.svm.SVC(gamma = 0.001)
ai.fit(suuji.data, suuji.target)
n1 = ai.predict(suuti.reshape(1, -1))


# 3桁目の画像の数値リスト化(データ化)と予測
gazou = PIL.Image.open('data2.png').convert("L")
gazou = gazou.resize((8,8),PIL.Image.ANTIALIAS)
suuti = numpy.asarray(gazou, dtype = float)
suuti = numpy.floor(16 - 16 * (suuti / 256))
suuti = suuti.flatten()

n2 = ai.predict(suuti.reshape(1, -1))


# 2桁目の画像の数値リスト化(データ化)と予測
gazou = PIL.Image.open('data3.png').convert("L")
gazou = gazou.resize((8,8),PIL.Image.ANTIALIAS)
suuti = numpy.asarray(gazou, dtype = float)
suuti = numpy.floor(16 - 16 * (suuti / 256))
suuti = suuti.flatten()

n3 = ai.predict(suuti.reshape(1, -1))


# 1桁目の画像の数値リスト化(データ化)と予測
gazou = PIL.Image.open('data4.png').convert("L")
gazou = gazou.resize((8,8),PIL.Image.ANTIALIAS)
suuti = numpy.asarray(gazou, dtype = float)
suuti = numpy.floor(16 - 16 * (suuti / 256))
suuti = suuti.flatten()

n4 = ai.predict(suuti.reshape(1, -1))

# 結果の表示(個別に認識した結果を4桁目から順番に並べています)
print('認識結果(予測結果):', int(n1), int(n2), int(n3), int(n4))

print('\n\n【今回認識した元の画像】')


# 元の画像を4分割でトリミングした画像の表示:複数の画像を表示させる
img_list=[data1, data2, data3, data4]
for bangou, imagenamae in enumerate(img_list):
    plt.subplot(2, 4, bangou+1) # (行数,列数,何番目に画像を表示させるか)
    plt.axis("off") # 画像の軸をオフ
    plt.title('data' +str(bangou+1))
    plt.imshow(cv2.cvtColor(imagenamae, cv2.COLOR_BGR2RGB)) 

 

出力結果

 

出力結果:初期のプログラム【4桁の手書き連続数字画像認識プログラム:Pythonサンプルコード】

 

 

改変したプログラム【4桁の手書き連続数字画像認識プログラム:Pythonサンプルコード】

 

 

OpenCVの座標系とトリミングの関係

 

関数化してfor文で結果を出力させる際に、それぞれの認識結果が縦に出力されるのが難点でしたが、「end=’ ‘」の記述で横一列に出力できることがわかったので上記のコードをシンプルに改変しておきました。
これで見た目がスッキリしましたね。

 

import sklearn.datasets
import sklearn.svm
import numpy
import PIL.Image
import matplotlib.pyplot as plt
import cv2

# 画像の読み込みとリサイズ(画像を横の幅800・高さ200ピクセルにリサイズする場合のプログラム例です)
img = cv2.imread('9638_800*200.png') #ここに数字画像認識をしたい画像を入れます(事前に4等分を考慮して撮影した画像を利用)
img = cv2.resize(img, (800,  200)) # サイズが調整されていない画像を入れた場合のエラー予防を追加
#img = cv2.resize(img, (400,  100)) 


# 画像のトリミング [y1:y2, x1:x2]  (img = cv2.resize(img, (800,  200)) を使った場合のプログラム例
data1 = img[0:200, 0:200]     #yの範囲(縦)が0〜200・xの範囲(横)が0〜200までをトリミング
data2 = img[0:200, 200:400] #yの範囲(縦)が0〜200・xの範囲(横)が200〜400までをトリミング
data3 = img[0:200, 400:600] #yの範囲(縦)が0〜200・xの範囲(横)が400〜600までをトリミング
data4 = img[0:200, 600:800] #yの範囲(縦)が0〜200・xの範囲(横)が600〜800までをトリミング

#(img = cv2.resize(img, (400,  100)) を使った場合のプログラム例
#data1 = img[0:100, 0:100]     #yの範囲(縦)が0〜100・xの範囲(横)が0〜100までをトリミング
#data2 = img[0:100, 100:200] #yの範囲(縦)が0〜100・xの範囲(横)が100〜200までをトリミング
#data3 = img[0:100, 200:300] #yの範囲(縦)が0〜100・xの範囲(横)が200〜300までをトリミング
#data4 = img[0:100, 300:400] #yの範囲(縦)が0〜100・xの範囲(横)が300〜400までをトリミング


# トリミングした画像を保存
cv2.imwrite('data1.png', data1)
cv2.imwrite('data2.png', data2)
cv2.imwrite('data3.png', data3)
cv2.imwrite('data4.png', data4)


# 手書き数字のデータセットで学習
suuji = sklearn.datasets.load_digits()
ai = sklearn.svm.SVC(gamma = 0.001)
ai.fit(suuji.data, suuji.target)


# 1〜4桁目の画像の数値リスト化(データ化)と予測。何度も実行する処理を関数化
# 結果を出力させる際に関数を使ってfor文で何枚も予測させると、縦に結果が出力されるのが難点でしたが、「end=' '」の記述で解決しました
print('認識結果(予測結果):\n')

def cognition_img(input_file):
  gazou = PIL.Image.open(input_file).convert("L")
  gazou = gazou.resize((8,8),PIL.Image.ANTIALIAS)
  suuti = numpy.asarray(gazou, dtype = float)
  suuti = numpy.floor(16 - 16 * (suuti / 256))
  suuti = suuti.flatten()
  n = ai.predict(suuti.reshape(1, -1))
  print(int(n), end=' ')  # 横一列に表示させるため「, end=' '」を使います
  return


import glob
import os

# 元の画像から切り取った4つの画像「data1.png」〜「data4.png」を取得
img_list = glob.glob('data*png')
# data1〜data4を順番に並べる
img_list =  sorted(img_list)
# 画像を予測する関数「cognition_img」に「data1.png〜data4.png」を順番に入れる  
for file in img_list:
  cognition_img(file)


print('\n\n【今回認識した元の画像】')


# 元の画像を4分割でトリミングした画像の表示:複数の画像を表示させる
img_list=[data1, data2, data3, data4]
for bangou, imagenamae in enumerate(img_list):
    plt.subplot(2, 4, bangou+1) # (行数,列数,何番目に画像を表示させるか)
    plt.axis("off") # 画像の軸をオフ
    plt.title('data' +str(bangou+1))
    plt.imshow(cv2.cvtColor(imagenamae, cv2.COLOR_BGR2RGB)) 

 

出力結果

 

出力結果:改変したプログラム【4桁の手書き連続数字画像認識プログラム:Pythonサンプルコード】

 

 

2桁版のプログラム【手書き連続数字画像認識プログラム:Pythonサンプルコード】

 

 

【2桁版の手書き数字画像認識用プログラム】

コメント頂きましたので、2桁用のサンプルプログラムも作成してみました。 ポイントとしては、

・「# 画像の読み込みとリサイズ」で2桁を想定した画像サイズに変更
・「data1」「data2」のみにしてプログラムに変更

をしています。
詳しくは、プログラム内のコメントをご確認ください。
プログラムを実行する際には、2桁の画像を使ってください。

2桁用のサンプル画像も公開中です。時短などにお役立てください。

2桁用サンプル画像のダウンロード:
サンプル画像:【2桁版】手書き連続数字画像認識プログラミング入門(Python・OpenCV・SVM)
(ダウンロードした圧縮ファイルをパソコン内で解凍後に、認識させたい画像ファイルを事前にアップロードしておきます)

 

import sklearn.datasets
import sklearn.svm
import numpy
import PIL.Image
import matplotlib.pyplot as plt
import cv2

# 画像の読み込みとリサイズ(画像を横の幅400・高さ200ピクセルにリサイズする場合のプログラム例です)
img = cv2.imread('45.png') #ここに数字画像認識をしたい画像を入れます(事前に2等分を考慮して撮影した画像を利用)→【変更点】2桁の画像を使います
# img = cv2.resize(img, (800,  200)) # サイズが調整されていない画像を入れた場合のエラー予防を追加
img = cv2.resize(img, (400,  200)) # →【変更点】2桁を想定した画像サイズに変更


# 画像のトリミング [y1:y2, x1:x2]  (img = cv2.resize(img, (400,  200)) を使った場合のプログラム例
data1 = img[0:200, 0:200]     #yの範囲(縦)が0〜200・xの範囲(横)が0〜200までをトリミング
data2 = img[0:200, 200:400] #yの範囲(縦)が0〜200・xの範囲(横)が200〜400までをトリミング
# data3 = img[0:200, 400:600] #yの範囲(縦)が0〜200・xの範囲(横)が400〜600までをトリミング→【変更点】コメントアウト(プログラムの無効化)
# data4 = img[0:200, 600:800] #yの範囲(縦)が0〜200・xの範囲(横)が600〜800までをトリミング→【変更点】コメントアウト(プログラムの無効化)



# トリミングした画像を保存
cv2.imwrite('data1.png', data1)
cv2.imwrite('data2.png', data2)
# cv2.imwrite('data3.png', data3) #→【変更点】コメントアウト(プログラムの無効化)
# cv2.imwrite('data4.png', data4) #→【変更点】コメントアウト(プログラムの無効化)



# # 4桁目の画像の数値リスト化(データ化)と、手書き数字のデータセットでの学習と予測→【変更点】4桁目はないので、コメントアウト(プログラムの無効化)
# gazou = PIL.Image.open('data1.png').convert("L")
# gazou = gazou.resize((8,8),PIL.Image.ANTIALIAS)
# suuti = numpy.asarray(gazou, dtype = float)
# suuti = numpy.floor(16 - 16 * (suuti / 256))
# suuti = suuti.flatten()

# suuji = sklearn.datasets.load_digits()
# ai = sklearn.svm.SVC(gamma = 0.001)
# ai.fit(suuji.data, suuji.target)
# n1 = ai.predict(suuti.reshape(1, -1))


# # 3桁目の画像の数値リスト化(データ化)と予測→【変更点】3桁目はないので、コメントアウト(プログラムの無効化)
# gazou = PIL.Image.open('data2.png').convert("L")
# gazou = gazou.resize((8,8),PIL.Image.ANTIALIAS)
# suuti = numpy.asarray(gazou, dtype = float)
# suuti = numpy.floor(16 - 16 * (suuti / 256))
# suuti = suuti.flatten()

# n2 = ai.predict(suuti.reshape(1, -1))


# 2桁目の画像の数値リスト化(データ化)と予測
gazou = PIL.Image.open('data1.png').convert("L")
gazou = gazou.resize((8,8),PIL.Image.ANTIALIAS)
suuti = numpy.asarray(gazou, dtype = float)
suuti = numpy.floor(16 - 16 * (suuti / 256))
suuti = suuti.flatten()

suuji = sklearn.datasets.load_digits() #→【変更点】4桁目で記述していたコードを、認識する最初の2桁目のプログラムに追記
ai = sklearn.svm.SVC(gamma = 0.001)
ai.fit(suuji.data, suuji.target)
n1 = ai.predict(suuti.reshape(1, -1))



# 1桁目の画像の数値リスト化(データ化)と予測
gazou = PIL.Image.open('data2.png').convert("L")
gazou = gazou.resize((8,8),PIL.Image.ANTIALIAS)
suuti = numpy.asarray(gazou, dtype = float)
suuti = numpy.floor(16 - 16 * (suuti / 256))
suuti = suuti.flatten()

n2 = ai.predict(suuti.reshape(1, -1))

# 結果の表示(個別に認識した結果を4桁目から順番に並べています) →【変更点】2桁なので「 int(n1), int(n2)」のみに変更
print('認識結果(予測結果):', int(n1), int(n2))

print('\n\n【今回認識した元の画像】')


# 元の画像を4分割でトリミングした画像の表示:複数の画像を表示させる→【変更点】2桁なので「img_list=[data1, data2]」のみに変更
img_list=[data1, data2]
for bangou, imagenamae in enumerate(img_list):
    plt.subplot(2, 2, bangou+1) # (行数,列数,何番目に画像を表示させるか) →【変更点】2桁認識なので「列数」を「2」に指定。(「4」のままでも使えます。「4」の場合には画像が小さくなります)
    plt.axis("off") # 画像の軸をオフ
    plt.title('data' +str(bangou+1))
    plt.imshow(cv2.cvtColor(imagenamae, cv2.COLOR_BGR2RGB)) 

 

出力結果

 

認識結果(予測結果): 4 5

出力結果:2桁版のプログラム【手書き連続数字画像認識プログラム:Pythonサンプルコード】

 

 

CSV形式ファイルに結果を保存版【手書き連続数字画像認識プログラム:Pythonサンプルコード】

 

 

【CSV形式ファイルなどに4桁の手書き数字画像認識した出力結果を保存できるプログラム】

 

出力結果を保存して、自動化・・・・

などと業務効率化を考えている方もいるのではないかと思います。

1桁なら、比較的簡単にCSV形式のファイルに保存して使えるのではないかと思いますが、数桁になると、頭を使わないと1つのセル内に出力結果がまとまらずに、思い通りの自動化ができない経験をされている方も多いのではないかと思います。
以前、他のプログラムのチュートリアル動画に、結果を保存する方法について質問を頂いていましたが、ようやく関連するプログラムをまとめることができました。
コメントくださった方は、「スプレッドシート」への出力でしたが、Googleスプレッドシートでは、CSV形式のファイルもインポートできるようでしたので、今回はとりあえずCSV形式で出力する方法をまとめておきます。
出力結果をまとめて保存できると、面白いですね。

import sklearn.datasets
import sklearn.svm
import numpy
import PIL.Image
import matplotlib.pyplot as plt
import cv2

# 画像の読み込みとリサイズ(画像を横の幅800・高さ200ピクセルにリサイズする場合のプログラム例です)
img = cv2.imread('4508_800*200.png') #ここに数字画像認識をしたい画像を入れます(事前に4等分を考慮して撮影した画像を利用)
img = cv2.resize(img, (800,  200)) # サイズが調整されていない画像を入れた場合のエラー予防を追加
#img = cv2.resize(img, (400,  100)) 


# 画像のトリミング [y1:y2, x1:x2]  (img = cv2.resize(img, (800,  200)) を使った場合のプログラム例
data1 = img[0:200, 0:200]     #yの範囲(縦)が0〜200・xの範囲(横)が0〜200までをトリミング
data2 = img[0:200, 200:400] #yの範囲(縦)が0〜200・xの範囲(横)が200〜400までをトリミング
data3 = img[0:200, 400:600] #yの範囲(縦)が0〜200・xの範囲(横)が400〜600までをトリミング
data4 = img[0:200, 600:800] #yの範囲(縦)が0〜200・xの範囲(横)が600〜800までをトリミング

#(img = cv2.resize(img, (400,  100)) を使った場合のプログラム例
#data1 = img[0:100, 0:100]     #yの範囲(縦)が0〜100・xの範囲(横)が0〜100までをトリミング
#data2 = img[0:100, 100:200] #yの範囲(縦)が0〜100・xの範囲(横)が100〜200までをトリミング
#data3 = img[0:100, 200:300] #yの範囲(縦)が0〜100・xの範囲(横)が200〜300までをトリミング
#data4 = img[0:100, 300:400] #yの範囲(縦)が0〜100・xの範囲(横)が300〜400までをトリミング


# トリミングした画像を保存
cv2.imwrite('data1.png', data1)
cv2.imwrite('data2.png', data2)
cv2.imwrite('data3.png', data3)
cv2.imwrite('data4.png', data4)


# 4桁目の画像の数値リスト化(データ化)と、手書き数字のデータセットでの学習と予測
gazou = PIL.Image.open('data1.png').convert("L")
gazou = gazou.resize((8,8),PIL.Image.ANTIALIAS)
suuti = numpy.asarray(gazou, dtype = float)
suuti = numpy.floor(16 - 16 * (suuti / 256))
suuti = suuti.flatten()

suuji = sklearn.datasets.load_digits()
ai = sklearn.svm.SVC(gamma = 0.001)
ai.fit(suuji.data, suuji.target)
n1 = ai.predict(suuti.reshape(1, -1))


# 3桁目の画像の数値リスト化(データ化)と予測
gazou = PIL.Image.open('data2.png').convert("L")
gazou = gazou.resize((8,8),PIL.Image.ANTIALIAS)
suuti = numpy.asarray(gazou, dtype = float)
suuti = numpy.floor(16 - 16 * (suuti / 256))
suuti = suuti.flatten()

n2 = ai.predict(suuti.reshape(1, -1))


# 2桁目の画像の数値リスト化(データ化)と予測
gazou = PIL.Image.open('data3.png').convert("L")
gazou = gazou.resize((8,8),PIL.Image.ANTIALIAS)
suuti = numpy.asarray(gazou, dtype = float)
suuti = numpy.floor(16 - 16 * (suuti / 256))
suuti = suuti.flatten()

n3 = ai.predict(suuti.reshape(1, -1))


# 1桁目の画像の数値リスト化(データ化)と予測
gazou = PIL.Image.open('data4.png').convert("L")
gazou = gazou.resize((8,8),PIL.Image.ANTIALIAS)
suuti = numpy.asarray(gazou, dtype = float)
suuti = numpy.floor(16 - 16 * (suuti / 256))
suuti = suuti.flatten()

n4 = ai.predict(suuti.reshape(1, -1))



# 結果の表示(個別に認識した結果を4桁目から順番に並べています)
print('認識結果(予測結果):', int(n1), int(n2), int(n3), int(n4))





#### はじめ:CSVファイルに出力結果を追加するための処理を追加 ####

# CSVファイルに出力結果を追加
# コード内の「OCR_OUTPUT.csv」のところを「OCR_OUTPUT.txt」にするとテキストファイル形式にできます
import csv 
from pathlib import Path

def print_output():
    print(Path('OCR_OUTPUT.csv').read_text())

# 「OCR_OUTPUT.csv」(ヘッダー名:OCR_OUTPUT)というファイルの作成と出力結果の保存
# ここの処理では、各桁の出力結果が各セルに分散されている状態(例:「4, 5, 0, 8」などとコンマで区切られている状態)
with open('OCR_OUTPUT.csv', 'a', newline='') as f:
  writer = csv.writer(f)
  writer.writerow([int(n1), int(n2), int(n3), int(n4)])
print('\n\n【CSVファイルへ保存するための処理】(OCR_OUTPUT.csv)')
print('\n[保存処理中・・・]\n新たな出力結果に関しては「,」(コンマ)の処理が未実施の状態\n')
print_output()


# CSVファイルの出力結果から「,」(コンマ)を削除し、1つのセル内に出力結果を表示
ocr_output_file = 'OCR_OUTPUT.csv'
with open(ocr_output_file) as f:
    data_lines = f.read()

# 文字を置換:「,」(コンマ)を「」(空白)に置換することで「,」を削除
data_lines = data_lines.replace(',', '')

# 読み込んだファイル名のまま保存
with open(ocr_output_file, mode="w") as f:
    f.write(data_lines)
print('\n[保存完了]\n新たな出力結果に対して「,」(コンマ)を削除し、1セル内に結果をまとめる処理を実行\n')
print_output()

#### ここまで:CSVファイルに出力結果を追加するための処理を追加 ####



print('\n\n【今回認識した元の画像】')


# 元の画像を4分割でトリミングした画像の表示:複数の画像を表示させる
img_list=[data1, data2, data3, data4]
for bangou, imagenamae in enumerate(img_list):
    plt.subplot(2, 4, bangou+1) # (行数,列数,何番目に画像を表示させるか)
    plt.axis("off") # 画像の軸をオフ
    plt.title('data' +str(bangou+1))
    plt.imshow(cv2.cvtColor(imagenamae, cv2.COLOR_BGR2RGB)) 

 

出力結果

 

認識結果(予測結果): 4508

 

認識結果(予測結果):CSV形式ファイルなどに4桁の手書き数字画像認識した出力結果を保存できるプログラム

 

保存処理中:CSV形式ファイルなどに4桁の手書き数字画像認識した出力結果を保存できるプログラム

 

保存処理完了:CSV形式ファイルなどに4桁の手書き数字画像認識した出力結果を保存できるプログラム

 

【今回認識した元の画像】:CSV形式ファイルなどに4桁の手書き数字画像認識した出力結果を保存できるプログラム

 

出力結果の保存:CSV形式ファイルなどに4桁の手書き数字画像認識した出力結果を保存できるプログラム

 

 

by 子供プログラマー | プログラミング入門ウェブ教室

 

 

【Python等】OCRプログラミング入門講座(一覧)

次は、7セグメントのデジタル数字のOCRに挑戦
【4桁 – 7セグメント編】連続デジタル数字画像認識プログラミング入門(Python・OpenCV・Keras・CNN)

縦書き・横書き対応の日本語手書き文字のOCR開発に挑戦
【日本語手書きOCR編】連続文字画像認識プログラミング入門(Python・OpenCV・Keras・CNN)

 

【音声認識】

【Python入門】日本語の文字起こしのやり方(音声認識:音声ファイル編)サンプルコード 

 

【音声合成】

【PyTorch入門】日本語のテキスト音声合成(E2E-TTS)- ESPnet・Tacotron 2版