技術解説

文字の検出と認識を同時に行う「CCN」を動かしてみた

技術解説

こんにちは。Aniecaです。

今回は「Convolutional Character Networks」というモデルを動かしてみました。
ソースを公開しています。

Convolutional Character Networks とは

非常にざっくり言うと、画像の中から
文字が書いてある領域を見つけ出し、その文字を認識するモデルです。
元論文はこちら

CVPR に採択されていること、既存の多くのデータセットに対して SOTA を達成していることから(個人的に)注目の論文です。

ICCV は 2019 年 10 月 26 日現在、審査中のようです。

論文より引用。文字単位と単語単位での認識ができるようです。

今までにも高精度な「文字の検出を行うモデル」、「文字の認識を行うモデル」は提案されていました。

しかし、単体のモデルとして最適化された二つのモデルを組み合わせても精度に限界があると筆者は指摘しています。

本論文のネットワークはこれらを同時に訓練して解くため、そういった個別最適化による精度の限界を越えることができたようです。

実際に動かしてみる

では、さっそく動かしてみましょう!

ちなみに、ソースは公開されているのですが現時点で学習用のコードがなく、論文中にも損失関数に関する記載がないため、独自のデータセットの学習ができないようです。これについてはしばらく待つしかなさそうです。

今回は作者が公開している pretrained model を使って何枚か画像を認識してみたいと思います!

環境は Google Colaboratory を使います。

まずは、ランタイムをGPUに変更しましょう。

「ランタイム」タブをクリック
「ランタイムのタイプを変更」をクリック
「ハードウェアアクセラレータ」トグルを「GPU」に変更
「保存」をクリック

次に、ソースの取得、必要なモジュールのインストール、重みファイルの取得を行います。

また、認識したい画像を格納するディレクトリを作っておきます。

!git clone https://github.com/MalongTech/research-charnet.git
%cd research-charnet/
!pip install torch torchvision pyclipper yacs
!python setup.py build develop
!bash download_weights.sh
!mkdir image_dir

サイドバーの「ファイル」タブを見ると、 research-charnet というディレクトリができています。

これをクリックすると中にあるディレクトリが確認できます。
1. image_dirディレクトリを右クリック
2. アップロードをクリック
3. 画像を選択

今回はこんな画像を用意しました。

1枚目は比較的簡単そうな道路標識です。
2枚目は細かめの文字が書かれた道路標識です。
3枚目は Google Chrome の初期画面です。

学習データにおそらく日本語がないので、2枚は英語の標識を持ってきました。


道路標識を瞬時に読んでテキスト化できると自動運転にも役立つのではないでしょうか。

3枚目は自分の Google Chromeの初期画面です。


自然画像で学習されているようだったので、こういった画面のキャプションが読めるのかを確認です。


キャプションが読めれば紙をスキャンした画像なんかも読めるのかもしれませんね。

認識は以下で実行します。

!mkdir result_dir
!python tools/test_net.py configs/icdar2015_hourglass88.yaml image_dir result_dir

簡単ですね。

実行が完了したら、結果を見てみましょう。

以下のコマンドで確認ができます。

input_paths = glob('image_dir/*')
input_paths.sort()
result_paths = glob('result_dir/*.txt')
result_paths.sort()

for input_path, result_path in zip(input_paths, result_paths):
  print(input_path, result_path)
  image = Image.open(input_path).convert('RGBA')
  draw = ImageDraw.Draw(image)
  font = ImageFont.truetype(
      '/usr/local/lib/python3.6/dist-packages/imgaug/DejaVuSans.ttf', 
      16)

  with open(result_path) as f:
    lines = f.readlines()
  
  for line in lines:
    factors = line.strip().split(',')
    coords = list(map(int, factors[:-1]))
    label = factors[-1]
    draw.polygon(
        [tuple(coords[0:2]), tuple(coords[2:4]), tuple(coords[4:6]), tuple(coords[6:8])], 
        outline=(255,0,0,200)
    )
    fs = font.getsize(label)
    c = coords[6], coords[7], coords[6] + fs[0], coords[7] + fs[1]
    draw.rectangle(c, fill=(255,0,0, 127))
    draw.text(tuple(coords[6:8]), label, fill=(255,0,127), font=font)
    print(label)

  plt.figure(figsize=(16,9))
  plt.imshow(image, interpolation="LANCZOS")
  image.save(result_path.replace('txt', 'png'))
  plt.show()

結果はNotebookに出力されます。

また、result_dir内に画像とテキストが保存されます。

それでは、ダウンロードした画像をみてみましょう。

以下のようになりました。

結果1。うまく認識できている。
結果2。結果が重なってしまっているが細かくても読めているようだ。
ただ、右の速度表記が認識できていない。
結果3。大きすぎる文字や日本語は読めないのだろうか。

はい。こんな感じになりました。

かなり認識が早い(体感 2 ~ 3 秒)のと、細かい文字も割と読めているので驚きました。

短い文字が読めないことが気になりましたが、3文字以下は読まないように設定されているようです。

設定次第では読めるようになるかも?

あとは、大きい文字も読めていませんでした。

これは理由がパッと分かりませんが画像のサイズに対して大きすぎる文字は読めないのでしょうか。。?

終わりに

まだまだ課題はあるように感じますが、なかなか出てこなかった End2End のモデルなので非常に期待しています。

今後学習用のコードが公開されたら日本語のデータセットでモデルを作ってみたいですね。

今回は以上です。


ここまで読んでいただきありがとうございました。

コメント

タイトルとURLをコピーしました