読み取りにくい SI の座標を簡単表示【python で OCR】

SI の書き方は、研究室によって様々です。

丁寧に計算座標を何ページにも渡って貼り付けてくれる人もいれば、計算の input ファイルと output ファイルを supplementary material にしてくれる親切な研究グループもいます。

その一方で、非常に読み取りにくい細工を施してある SI も時折目にします。(意図的にやっているのか、pdf に変換される過程で自然に起こってしまっているのかは不明です。)

例えば、目には見えない改行コードがたくさん入っているとか、白色文字で特殊記号が入っているなどです。

今回の記事では、そのような悪質な SI を取り上げます。

実は、これらのファイルは pythonOCR することによって簡単に座標情報を抽出することが出来るのです!

SI がコピーできない

実際に悪質な SI に悪戦苦闘している様子をご覧ください。

SI をそのままコピーすると、変なところで改行されてしまいます。手動で改行を直していけば Gauss View で表示できる形式に直すことができますが、そんなこといちいちしていられません。

上記のように、pdf をうまくコピーできない場合には、いくつかの pdf viewer を試してみることをお勧めします(mac の Preview はうまくいかないことが多い)。

しかし、上記の動画中の SI はどの PDF viewer で開いてもダメでしたし、python の pyPDF でもうまく読み取れませんでした。。。

pyocr

コピーすると変な文字が入り込んでしまうものでも、人間の目ではきちんと読み取れる SI であれば、OCR で変換可能です!

OCR とは光学文字認識のことで、文章を画像として読み込み、文字コードに変換する仕組みのことを意味します。

python には OCR を実行することができる pyocr という便利なライブラリが存在します。

まずは、pip で pyocr を、homebrew で tesseract をインストールしましょう。

pip3 install pyocr
brew install tesseract

次に、以下のコードをコピーして、OCR.py という名前で保存しましょう!このコードは、参考文献1を参考に作りました。

from PIL import Image
import sys
import pyocr
import pyocr.builders

tools = pyocr.get_available_tools()
tool=tools[0]
#lang="eng"

txt = tool.image_to_string(Image.open(sys.argv[1]),lang="eng",builder=pyocr.builders.TextBuilder(tesseract_layout=6)
)
print( txt )

上記スクリプトは英語対応です。日本語の文章を読み取る場合は、”lang=jpn” に変更し、参考文献 2 を参照して tesseract の日本語ファイルをダウンロードしてください。

以下のコマンドで実行します。第二引数には、SI をスクリーンショットした画像ファイルを指定します。

python3 OCR.py filename.png

では、実際に使用している様子をご覧ください。

上記の動画は、

  1. SI の座標をスクリーンショットし、TS.png という名前で保存。
  2. OCR.py を利用して、画像ファイルを文字ファイルとして terminal 上に出力。
  3. terminal 上に出力された座標を “ctrl + c” でコピー。
  4. clip.py というクリップボード上の情報を Gauss View で可視化できる形式に直すスクリプトを利用して、Gauss View で表示。

という流れになっています。

clip.py

clip.py については、以下の記事を参照してください。

上記の動画で使用した clip.py のコードは以下のようになります。以前の記事で紹介したものから少し改変してありますし、汎用性はありません。

#!/usr/local/bin/python3
import pyperclip
import os
import time

#clipboard 上の情報を取得する
lines = pyperclip.paste().split("\n")
path = "/Users/hogehoge/clip_board_gv.com"

with open(path, mode='w') as f:
    f.write("# STO-3G\n\ntitle\n\n0 1\n")
    for line in lines:
        a = line.split(" ")
        if a[1] == "1":
            f.write("1\t" + a[2] + "\t" + a[3] + "\t" + a[4] + "\n")
        if a[1] == "6":
            f.write("6\t" + a[2] + "\t" + a[3] + "\t" + a[4] + "\n")
    f.write("\n\n\n")

os.system('open /Applications/gv/gview.app ' + path + ' &')
time.sleep(6)
os.system('rm ' + path)

hogehoge という部分を適切な path に置き換えてください。Gauss View の path も同様に書き換えてください。

コツ

clip.py 実行時に “IndexError: list index out of range” というエラーが出る場合は、下図のように座標情報の最後の改行を読み取らないようにコピーしてください。

また、上述のスクリプトを用いてもうまく SI を読み取れないという場合には、スクリーンショットをやり直してください。

なるべく大きな画面でスクリーンショットするのがコツです。小さな画像だと解像度が悪く、OCR がうまくいきません。

座標情報がページをまたいで掲載されている場合は、座標全体をスクリーンショットして OCR で変換したのちに、出力情報をテキストエディタなどに貼り、ページ番号などを消してください。この部分のみ手動になってしまいますが、大した手間ではありません。

参考文献

  1. PythonでOCR
  2. Macでスクリーンショットからテキストを抽出して貼り付ける

管理人: