【7セグメント編】デジタル数字文字検出(物体検出):画像の2値化・膨張処理・輪郭検出枠のカット設定

【7セグメント編】デジタル数字文字検出(物体検出):画像の2値化・膨張処理・輪郭検出枠のカット設定方法

 

動画:【4桁 – 7セグメント編】文字検出機能付きの連続デジタル数字画像認識プログラミング入門(Python・OpenCV・Keras・CNN)

 

 

【Python機械学習入門】文字検出機能付き:高精度の自作OCRを作ろう
7セグメントデジタル連続数字画像認識AI:1桁〜4桁以上 – 物体検出・抽出編
7 Segment Digits OCR


視聴時間:18分26秒

訂正:17分6秒〜17分22秒までの音声説明は間違えです… 今回のプログラムでは「ROI_img〜.png」で保存した画像を使って予測はしていません。(作成中の日本語OCRプログラムと勘違いしていました・・・ご了承ください)

使い方がわからない方は、動画を参照ください。

 




 

【動画の内容】
0:00 ダイジェスト
0:22 はじめに – オリジナルOCR開発の設計概略
0:46 ステップ1 – 文字検出の概略:画像の前処理など(OpenCV) ← ココ
6:33 ステップ2 – 文字検出の設定変更のチュートリアル
10:06 ステップ3 – 文字検出 + 連続文字認識(再学習について)
17:24 おわりに – 日本語 横書き・縦書き対応のプログラミング学習用OCR開発中(ノイズ除去・直線除去・角度補正・ブロック検出機能付き)

 

機械学習モデルのディープラーニング(深層学習)でおなじみの「畳み込みニューラルネットワーク」(CNN:Convolutional Neural Network)で、7セグメントのデジタル数字画像のオリジナルデータセットで作成した学習済みモデルを使って、1〜4桁以上の数字画像認識(画像分類)ができる文字検出(物体検出・輪郭検出)機能付きのOCRプログラムを開発するために、デジタル数字の静止画像から、数字の文字を検出できるプログラムを作成してみました。

既存のOCRプログラムで7セグメントのデジタル数字検出や画像認識をしてみても、思ったよりも上手く行かない経験をされる方もいるのではないかと思います。
一連のプログラムが、これから、計量器や時計、温度計をはじめとしたデジタル数字認識に挑戦したい方の参考になることがありましたら幸いです。

7 Segment Edition(Seven Segment Edition)
:Contour detection and object detection of “7-segment digital continuous numeric images” for creating high-precision orijinal OCR.
Introduction to Continuous Digital Number Display Image Recognition Python Programming.

 

 

サンプル画像・サンプルコードリンク:7セグメントデジタル数字画像数字の文字検出(物体検出)プログラム

 

 

文字検出・判定用のデジタル数字画像認サンプル画像


7セグメントのデジタル数字画像認識評価用サンプル画像です。
1桁〜4桁以上の画像などがあります。

 

すぐに使えるGoogle Colaboratoryサンプルコードリンク
7segment-digits-object-detection.ipynb | Google Colaboratory共有ファイル
(ファイル – ドライブにコピーを保存後にコピー環境で実行)

 

 

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

 

 

The MIT License

Copyright 2021 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.

 

 

【7セグメントのデジタル数字の文字検出(物体検出)用:Pythonサンプルコード】

 

 

OpenCVの輪郭検出機能などを使って、7セブメンとのデジタル数字の文字を検出できるプログラムです。
デフォルトの機能で検出してみると

・文字が切れているところまでを検出してしまう…

事象に悩まされるのではないかと思います。
うまく検出させるには、

・カスケード分類器を作成する方法
・テンプレートマッチング
・特徴点抽出による比較
(局所特徴量を利用した物体検出)

などと様々な方法があるようでしたが、今回は

2値化した画像の膨張処理(数字を膨張させることでデジタル数字特有の切れ目をなくす)
輪郭検出枠のカット設定(数字だけを検出するように縦横の大きさを指定)

を行うことでデジタル数字を検出できるようにしてみました。

 

 

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

 

 

python 3.6.9 〜 3.7.10
opencv(opencv-python)4.1.2
matplotlib 3.2.2
imutils 0.5.4

ローカル環境で、指定したバージョンのインストールが難しい場合、Python以外は最新のバージョンを入れてみてください。
また、Google Colaboratoryのサンプルコードではランタイム:GPUで実行しています。

 

 

① デジタル数字の文字検出をしたい画像ファイルをGoogle Colaboratoryにアップロードします。

 

 

以下のサンプル画像の圧縮ファイルをダウンロード後に、ファイルを解凍し、フォルダ内の画像ファイルをアップロードします。

 

文字検出・判定用のデジタル数字画像認サンプル画像


7セグメントのデジタル数字画像認識評価用サンプル画像です。
1桁〜4桁以上の画像などがあります。

 

 

② 7セグメントのデジタル数字文字検出(物体検出)プログラム:画像の2値化・膨張処理・輪郭検出枠のカット設定

 

 

# 輪郭検出・抽出のためのインポート
import cv2
import numpy as np
import matplotlib.pyplot as plt
from imutils import contours


# 画像の読み込み - デジタル数字の文字検出する画像
img = cv2.imread('4567.png' ) #ここを変更。文字検出したい画像のファイル名を入力します。

# 画像のリサイズ。4桁の数字を想定。1桁ごとに縦横100ピクセル
img = cv2.resize(img, (400,  100))  # 縦の高さ400ピクセル・横の幅 100ピクセルにリサイズ。

# モノクロ・グレースケール画像へ変換(2値化前の画像処理)
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 2値化(Binarization):白(1)黒(0)のシンプルな2値画像に変換
retval, img_binary = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)

# 白部分の膨張処理(Dilation):モルフォロジー変換 - 2値画像を対象
kernel = np.ones((5,5),np.uint8) # カーネル(構造的要素):全要素の値が1の縦横5ピクセルのカーネル
img_dilation = cv2.dilate(img_binary,kernel,iterations = 1) #「iterations=」繰り返し膨張処理を行う回数を指定

# 解説用のコメント(2値化)
print('\n【2値化処理画像 - Binarization】')
print('  画像の2値化と白部分の膨張をさせることで、途切れているデジタル数字を1文字として検出しやすいようにしています。')
print('  この段階で、数字が「白」として処理できていないと輪郭の検出がしにくいようでした。')

# 膨張処理後の2値化画像の表示
plt.imshow(cv2.cvtColor(img_dilation, cv2.COLOR_BGR2RGB))
plt.show()


# 輪郭の検出
#「findContours」の返り値「cnts(contours)」は輪郭毎の座標組・「hierarchy」は輪郭の階層構造
#「cv2.RETR_EXTERNAL」:最も外側の輪郭を返す
#「cv2.CHAIN_APPROX_SIMPLE」:輪郭上の全点の情報を保持しない。輪郭の情報を圧縮
cnts, hierarchy = cv2.findContours(img_dilation, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 輪郭の並べ替え(左から右へ並べる)
cnts, hierarchy = contours.sort_contours(cnts, method='left-to-right') 


# ROI(Region of Interest:興味領域・対象領域)抽出用の初期設定
ROI_index = 0

# 抽出した輪郭を「x, y, w(横の幅), h(縦の高さ)」の単純なリストに変換
result = []
for contour in cnts:  
    x, y, w, h = cv2.boundingRect(contour) # 外接矩形の左上の位置は(x,y),横の幅と縦の高さは(w,h)
    
    # 大きすぎる小さすぎる領域を除去。処理する画像サイズに合わせて微調整が必要
    # 以下は縦の高さ400ピクセル・横の幅 100ピクセルの画像を想定。
    # if not 40 < w < 130 ・ 60 < h < 120: # 横の幅の範囲40〜130ピクセル・縦の高さの範囲60〜120ピクセルの輪郭を残す
    if not 40 < w < 130:
      continue
    if not 60 < h < 120: #輪郭の描画は画像サイズを超えることもあるようでした。
      continue
    
    # ROI抽出:画像の切り抜きと保存 
    ROI = img[y:y+h, x:x+w]   
    cv2.imwrite('ROI_img{}.png'.format(ROI_index), ROI)
    ROI_index += 1

    #resultに要素を追加
    result.append([x, y, w, h])


# 画面に矩形の輪郭を描画 (描画機能:for〜cv2.rectangleまでの2行をコメントアウト、または削除すると輪郭の描画を無効にできます)
for x, y, w, h in result:
    cv2.rectangle(img, (x, y), (x+w, y+h), (100, 255, 100), 4)  # 色の指定はRGB(100, 255, 100)。「4」は 太さ。数字を大きくすると太い輪郭が描画される。


# 解説用のコメント(輪郭検出・抽出)
print('\n【輪郭検出・抽出結果 - Contours】')
print('  枠が大きすぎる場合・小さすぎる場合には輪郭を除去しています。画像によって微調整する必要があります。')
print('  輪郭検出は、ディスプレイ背景の光の加減による濃淡や、機器の色などが入ると検出しにくくなるようでした。')
print('  輪郭検出を成功させるためには、「ディスプレイ表示画面」のみで「ディスプレイの縦横の範囲が最小限」の場合に検出しやすいようでした。')

# 輪郭検出・抽出結果の表示
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.savefig('digit-pick.png', dpi=300)  # 抽出結果の画像ファイルも保存しています。「dpi」は何も指定しないと dpi=72
plt.show()

 

続いて、検出した7セグメントデジタル数字の文字判定ができるOCRプログラムを開発していきましょう。
上記のプログラムで画像認識させたい画像の文字検出が成功していれば、高精度のオリジナルデジタル数字認識OCRの作成も目前です。
【7セグメント編 – 自動文字検出・抽出OCR】連続文字判定(デジタル数字:1〜4桁以上の連続数字)+再学習

自分でも不思議ですが、意外と作れてしまうものなのですね 🙂

 

 

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

 

【4桁 – 7セグメント編】連続デジタル数字画像認識プログラミング入門講座(Python・OpenCV・Keras・CNN)| 一覧ページ