SI の書き方は、研究室によって様々です。
丁寧に計算座標を何ページにも渡って貼り付けてくれる人もいれば、計算の input ファイルと output ファイルを supplementary material にしてくれる親切な研究グループもいます。
その一方で、非常に読み取りにくい細工を施してある SI も時折目にします。(意図的にやっているのか、pdf に変換される過程で自然に起こってしまっているのかは不明です。)
例えば、目には見えない改行コードがたくさん入っているとか、白色文字で特殊記号が入っているなどです。
今回の記事では、そのような悪質な SI を取り上げます。
実は、これらのファイルは python で OCR することによって簡単に座標情報を抽出することが出来るのです!
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
では、実際に使用している様子をご覧ください。
上記の動画は、
- SI の座標をスクリーンショットし、TS.png という名前で保存。
- OCR.py を利用して、画像ファイルを文字ファイルとして terminal 上に出力。
- terminal 上に出力された座標を “ctrl + c” でコピー。
- 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 で変換したのちに、出力情報をテキストエディタなどに貼り、ページ番号などを消してください。この部分のみ手動になってしまいますが、大した手間ではありません。