EnsekiTT Blog

EnsekiTTが書くブログです。

Python+OpenCVのディープラーニング(CNN)でテキスト領域検出をやってみた話

つまりなにしたの?

PythonOpenCV Contribに含まれているディープラーニングベースのテキスト領域を検出するCNNを試してみた。
思いの外ガバガバ判定で、領域を使ったアプリケーションを考えるなら結構大変そうだなって感じだった。
f:id:ensekitt:20180702032657j:plain

なんでやろうとおもったの?

OpenCV Contribにはまだ正式版には入っていないけど面白いのがいろいろ含まれているので最近はどんなのがあるのかな
と眺めていたら見つけた。OCRの前にテキスト領域を検出できると精度が上がるらしいので、試してみようと思った。
github.com

やったこと

Webカメラの画像をテキスト検出用のConvolutional Neural Networkに突っ込んで、
画像にテキストエリアを表示してみることにした。

準備

ネットワーク構造のファイルとCaffeのモデルファイルが必要
それぞれContribのGithubDropboxからダウンロードしてくる。
github.com
www.dropbox.com
これらは以下のコードと同じディレクトリに入れておく。

コード

# OpenCV のインポート
import cv2
import numpy as np

# VideoCaptureのインスタンスを作成する。
# 引数でカメラを選べれる。
cap = cv2.VideoCapture(0)

# CNNを用意する
textSpotter = cv2.text.TextDetectorCNN_create("textbox.prototxt", "TextBoxes_icdar13.caffemodel")
thres = 0.6

while True:
  # VideoCaptureから1フレーム読み込む
    ret, frame = cap.read()
    # スクリーンショットを撮りたい関係で1/4サイズに縮小
    frame = cv2.resize(frame, (int(frame.shape[1]/2), int(frame.shape[0]/2)))
    vis      = frame.copy()
    # 検出する
    rects, outProbs = textSpotter.detect(frame);

    # 四角を描画する
    for r in range(np.shape(rects)[0]):
        if outProbs[r] > thres:
            rect = rects[r]
            cv2.rectangle(vis, (rect[0],rect[1]), (rect[0] + rect[2], rect[1] + rect[3]), (255, 0, 0), 2)

    # テキストエリアを表示する
    cv2.imshow('TextArea Detection', vis)

    # キー入力を1ms待って、k が27(ESC)だったらBreakする
    k = cv2.waitKey(1)
    if k == 27:
        break

# キャプチャをリリースして、ウィンドウをすべて閉じる
cap.release()
cv2.destroyAllWindows()

できました。

f:id:ensekitt:20180702031642p:plain
f:id:ensekitt:20180702033214p:plain

やってみてどうだった?

割と簡単だと思っていたけどやってみるとコレはかなり前処理をちゃんとやらないといけないな?という気分になった。
学習は英語でされているので日本語が微妙な感じになるのはそりゃそうかなと思う。
縦に連なるエッジは割と文字と認識されやすいようでバーコードとかも文字として認識されていることがあった。

クリエイティブ・コモンズ・ライセンス
この 作品 は クリエイティブ・コモンズ 表示 4.0 国際 ライセンスの下に提供されています。