テッセラクトを使ってリングフィットアドベンチャーのモチベーションを維持したかった話

この記事は[リンク情報システム](https://www.lis.co.jp/)の2020新春アドベントカレンダー Tech Connectのリレー記事です。
engineer.hanzomon のグループメンバによってリレーされます。
（リンク情報システムのFacebookは[こちら](https://ja-jp.facebook.com/lis.co.jp/)から）

2020新春アドベントカレンダー Tech Connect インデックスは[こちら](https://qiita.com/dgkz/items/5131349d56354b33ee97)

29日の記事を担当しますshinmoです。よろしくお願いします。

##背景
突然ですが、リングフィットアドベンチャーってご存じでしょうか？
Nintendo Switch で発売されている、リングコンと呼ばれる専用の器具でゲームしながら運動できるという画期的なアレです。
12月に私も購入しまして、次の健康診断の結果を良くしよう！と意気込んでいたのですが、

意外と続かないんですね…。

買った最初のうちは2、3日に1回のペースでできていたんですが、だんだんやらない日の間隔が広がっていって今では1週間に1度やるかどうかといったところ。
せっかく買ったのにもったいないです。どうせだから文字認識の勉強と今後のモチベーションアップもかねて
何かpython でやってみます。画像認識ついでに運動の記録をグラフ化とかできたら面白そう。
![_log.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295384/e9850e5e-523e-b951-06ab-695b36663d1e.jpeg)
↑これを認識する(写真に写ったSwitchのアカウント名は隠してあります)

##準備
画像認識にはGoogleが開発している[テッセラクト](https://github.com/tesseract-ocr/)というものを使用します。
これはネットワークを使わずにローカル環境だけでできるみたいです。
モチベーションアップしたいのに、画像アップロードのためにややこしいネットワークとかの勉強が必要でなんかやる気が…、
なんてことにもならなさそうなのでうってつけですね。

とはいえ今使っているPCでpythonを使うのは初めてなので、pythonも一緒に準備します。

###pythonの準備
まずAnacondaをインストールします。
https://www.anaconda.com/distribution/ からAnaconda : python3.7をダウンロードします。
インストール先を適当な場所(今回はC直下)に指定して、あとはデフォルトのままでインストールしてしまいます。
ついでに、ものぐさな筆者はAnaconda のコンソールではなくコマンドプロンプトで済ませたいので、システム環境変数の```PATH```に次のように設定します。

```text:PATH
(省略); C:\Anaconda3\; C:\Anaconda3\Scripts
```

###テッセラクトの準備
次にテッセラクトです。
Windows で実行するので https://digi.bib.uni-mannheim.de/tesseract/ から
```tesseract-ocr-w64-setup-v5.0.0-alpha.20190708.exe``` をダウンロードします。
これも特に触ることなくデフォルトのままインストールします。完了すると ```C:\Program Files```の下に```Tesseract-OCR```フォルダができています。

さらに、このままでは日本語は認識してくれないので日本語のデータも準備します。
https://github.com/tesseract-ocr/tessdata_best
こちらのページにある jpn.traineddata をダウンロードし、
```C:\Program Files\Tesseract-OCR\tessdata``` に格納します。

ここでまたシステム環境変数に新しく```TESSDATA_PREFIX```を設定します。

```text:TESSDATA_PREFIX
C:\Program Files\Tesseract-OCR\tessdata
```

ここでシステム環境変数の設定を反映するため、一度PCを再起動。

###pyocrライブラリの準備
pythonとテッセラクトだけではまだ文字の認識はできません。なのでライブラリをインストールします。コマンドプロンプトで

```text:コマンドプロンプト
C:\> pip install pyocr
```

を実行し、pyocrライブラリをインストール。しかしまだあります。

###Pillowライブラリの準備
pyocrライブラリを使うにはPillowライブラリが必要です。
これ自体はどうやらAnacondaと一緒についてくるようなのですが、なにやらWindows10での使用がそのままではできないらしいです(やろうとしてエラー吐いた)。なのでこのライブラリも用意する必要があります。
まずはコマンドプロンプト上でpythonを実行し、次のようにコマンドを打ちます。

```text:コマンドプロンプト
C:\> python
>>> from pip._internal.pep425tags import get_supported
>>> get_supported()
```

すると以下のように返ってきます。

```
[('cp37', 'cp37m', 'win_amd64'), ('cp37', 'none', 'win_amd64'), ('py3', 'none', 'win_amd64'), ('cp37', 'none', 'any'), ('cp3', 'none', 'any'), ('py37', 'none', 'any'), ('py3', 'none', 'any'), ('py36', 'none', 'any'), ('py35', 'none', 'any'), ('py34', 'none', 'any'), ('py33', 'none', 'any'), ('py32', 'none', 'any'), ('py31', 'none', 'any'), ('py30', 'none', 'any')]
```

これの組み合わせに合うような.whlファイルを https://www.lfd.uci.edu/~gohlke/pythonlibs/ からダウンロードし、.whlファイルの置いてあるフォルダでコマンドを実行します。
今回は```C:\Ringfit```フォルダに格納したので、次のような感じになります。

```text:コマンドプロンプト
C:\Ringfit> pip install .\(ダウンロードした).whl
```

これでようやく準備ができました。

##実装
https://gitlab.gnome.org/World/OpenPaperwork/pyocr#usage
に記載されている内容をもとに画像を読み取れるように実装します。
ファイル名は適当に```Ringfit.py```としましょう。

```python:Ringfit.py
from PIL import Image
import sys
import codecs

import pyocr
import pyocr.builders

tools = pyocr.get_available_tools()
if len(tools) == 0:
    print("No OCR tool found")
    sys.exit(1)

tool = tools[0]
img_org = Image.open('Ringfit_log.jpg')
builder = pyocr.builders.TextBuilder(tesseract_layout=6)#tesseract_layoutの値で認識精度が変わる
txt = tool.image_to_string(img_org, lang='jpn', builder=builder)

with codecs.open("Ringfit.txt", 'w', encoding='utf-8') as file_descriptor:
    builder.write_file(file_descriptor, txt)
```

これを```C:\Ringfit```に保存します。ついでにこの実装だと画像が同じフォルダ内にある想定なので、
スマホで撮った写真を持ってきて```Ringfit_log.jpg```にリネームして同じフォルダに保存します。

![_log.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295384/974e56fb-e177-3265-cd05-08eb286b7735.jpeg)

##実行する
それでは実行してみましょう。

```
C:\Ringfit> python Ringfit.py
```

結果は…

```text:Ringfit.txt
ド 日 の 運動 結果 還 回 乙 太 を 電
リン グ コ ン 押 し こみ 383 回 (2323 回 " スク ワッ ト 2 凡 (782 史
) モモ アゲ アゲ 176 回 (657 加 際 リン グ コ ン 下 夫 し こみ _ 7 困 5
リン グ ア ロ ー 120 回 (150 回 ・ サイ レン ト ダ ッシュ _7096w442 角
* お な か 押し こみ ひね り ク イッ ク 。 52 回 (52 回 ) ・ サイ レン ト ジ ョ ギ ング 827 の 3402
* サゲ テ ブ ッシュ 48 回 (260 回 ~" サイ レン トモ モ 上 ザ 79 の の 232)
5 モモ デブ ッシュ 48 回 』 リン グ コ ン ヨ っ ぴり キープ 89 秘 (29g 避
還 スワ イシ ョ ウ 37 回 リン グ コ ン 上 引っ ぱ の 32 秒 (32 飛
バン ザイ サイ ド ベ ンド 18 回 " スク ワッ トキ ー プ 2Z 末 (33 和
論 英雄 1 の ポー スズ 14 回 (88 回 ・ リン グ コ ン 下 坊 し こみ キー プ 。 6 落 85 天
還 証 証 紀 ちな か し こみ 13 回 cog
… 臣 理 ーー ハバ w バ カッコ 内 は プレ イ 生 始 か ら の 皿 訂 値 で す 人 / のど 作 、。
ご 二 導 才 導 導 ンー ンー ンー 一 ンー ンー De
```

なにか変ですね。画像から余分な文字を削りもう一度。
![log2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295384/1604f03b-f4f3-5a8e-3bb0-1976161a8d11.jpeg)
どうなる…？

```text:Ringfit.txt
リン グ コ ン 押 し こみ 383 回 (2323 回 ) の スク ワット た 2 所 (785 幻 )
培 モモ アゲ アゲ 176 回 (657 回 ) め リン グ コ ン 下 巻 し こみ 7 幻 (72 細 )
六 リン グ ア ロ ー 120 回 (150 回 ) ・ サイ レン ト ダ ッシュ 7096(2792
・ お な か 押し こみ ひね り ク イッ ク _ 52 回 (52 回 ) ・ サイ レン ト ジ ョ ギ ング 827 カ 23207 ツ
・ サゲ テ プ ブッ シュ 48 回 (260 回 ) “ サイ レン トモ モ 上 げ 7 9 の (232 リ
5 モモ デブ ッシュ 48 回 (48 回 ) * リン グ コ ン ヨ っ ぱ ク キー プ 89 秒 299 秒 。
因 語 スワ イィ ショ ウー 57 回 本 リン クコ ン 上 引っ ぱり 大 環 鐘 識
固 商 症 パ ン ザ イサ イド ベン ド 18 回 Gsm。。 誰 ス クワ ッ ト キ ー プ 7 科 0
の スー geog) * リ ンク コン RC こみ も
```

ところどころできてはいますが、どうやらアイコンを文字と認識していたり、精度にも問題がありそうですね…。
tesseract_layoutの値を変えて試してもみましたが、うまくいきませんでした。

##終わりに
用意した画像もよくなかったのかもしれませんが、出力結果がよくありませんでした。
pythonにはグラフ化するライブラリがあることが分かっているので、出力結果をうまいこと加工して
グラフで表示出来たらいいなあと思うんですが…先は近くなさそうです。

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