pytesseract(OCR)で不要なスクリーンショットを判別した
macOS Venrura 13.3
Python3.9
tesseract 5.3.1
pytesseract 0.3.10
やりたいこと
以前、MacでWeb画面のスクリーンショットを自動で撮り続けたいという記事を書きました。順調にスクショを取り続けています。ただ、データが1日で1.5GBくらい増えてしまうので整理したいです。また、失敗している画像がけっこうあります。
- 毎分取得していて、3ヶ月分くらいある。1日1440ファイルx90日くらい
- 明らかに意図外の画面を別フォルダ移動させる(削除はマニュアル操作にする)
- ある程度自動化したい
やったこと
- OCRで文字を読んで不要なファイルを選別する
- tesseract, pytesseractを使う
インストール
tesseractのインストール方法。これはプラットフォームごとに違うので下記参考に。
Macの場合
# 本体
brew install tesseract
# 日本語も読めるようにするにはこれを追加
brew install tesseract-lang
Ubuntuの場合
https://github.com/tesseract-ocr/tessdata/tree/main にあるjpn.traineddata
(40MBくらい)をダウンロードして、下記いずれかのtessdata
のフォルダに入れます。
Various types of training data can be found on GitHub. Unpack and copy the .traineddata file into a ‘tessdata’ directory. The exact directory will depend both on the type of training data, and your Linux distribution.
Possibilities are:
/usr/share/tesseract-ocr/tessdata
/usr/share/tessdata
/usr/share/tesseract-ocr/4.00/tessdata.
Pythonのライブラリをインストール
pip install Pillow # 画像の取得
pip install pytesseract # OCR
pip install tqdm # 進捗ゲージの表示
デモ
この画面で試してみます。左側に日本語のサインイン画面、右側に英語でElastiCacheの宣伝が入っています。
コード
OCRの部分
画像の中から読めた分をtext
で返します。このコード単体で確認用に使えます。
custom_oem_psm_config
でOCRの設定が変えられますが、書いてある設定値で固定になるかもしれません。
import pytesseract
from PIL import Image
def ocr_image(image_path):
img = Image.open(image_path)
custom_oem_psm_config = r"--oem 3 --psm 6 -l eng+jpn"
text = pytesseract.image_to_string(img, config=custom_oem_psm_config)
return text
image_path = "xxxx.png"
text = ocr_image(image_path)
print(text)
上の画像に対するOCR結果はこうなります。あまり正確とは言えませんが・・・。
aws
へ ー プ
IAM ユ ー ザ ー と し て サ イ ン イ ン
DATABASE
ア カ ウ ン ト D ⑫ 柘 ま た は ア カ ヵ ウ ン ト エ イ リ ,
7” Save today with
es Amazon ElastiCache
ュ ー ダ ー 鉄 け は
data tiering
ス ヮ ー ド Achieve 60%+ savings with
' Amazon ElastiCache data tiering
as compared to running
ロ こ の o ア カ ヵ ウ ン ト を 記 誌 す る at maximum utilization ③
on R6g nodes ve a Dyer
| サ イ シ ィ ン | [冒「 臺臺
ee
‘RBH 7911S Y— © 1996-2023, Amazon Web Services, Inc. or its affiliates.
文字を抽出して全部使うのには厳しいですが、今回の目的は判別だけなので、この画像にだけ出てくる文字をピックアップして、それが揃えば判別できるのでOKとします。
例えば、抽出したテキストに"記 誌 す る"が揃っていればこの画面だと判別できそうです(※場合による)。判定のコードは以下を使います。
OCRされた結果はスペースが入っていますが、text = text.replace(" ", "")
などでスペースを消してから判定しています。keywordsの中に判定する複数の文字列を入れてもよいですが、今は1つだけにします。
keywords = ["記誌する"]
if all(key in text for key in keywords):
# 揃った
フォルダにあるPngを全部調べる
- original_dirからdestination_dirに移動
- keywordsが揃わなかったファイルをshutilで別フォルダに移動(あとで手動で消す想定)
- tqdmで進捗確認
import glob
import os
import shutil
import pytesseract
from PIL import Image
from tqdm import tqdm
def ocr_image(image_path):
img = Image.open(image_path)
custom_oem_psm_config = r"--oem 3 --psm 6 -l eng+jpn"
text = pytesseract.image_to_string(img, config=custom_oem_psm_config)
return text
def move_file(image_file, destination_dir):
# print("Move:", image_file)
shutil.move(image_file, os.path.join(destination_dir, os.path.basename(image_file)))
original_dir = "/path/to/original/dir"
destination_dir = "/path/to/temp/dir"
keywords = ["記誌する"]
image_files = sorted(glob.glob(os.path.join(original_dir, "**", "*.png"), recursive=True))
# Loop over the files with a progress bar from tqdm
for image_file in tqdm(image_files, total=len(image_files), unit="file"):
text = ocr_image(image_file)
text = text.replace(" ", "")
if all(key in text for key in keywords):
move_file(image_file, destination_dir)
まとめ
- pytesseractを使って、OCRでスクリーンショットの判別をできるようになりました
- 判定の基準をいろいろ試すのがちょっと大変かもしれません
- 時間がかかるのが課題です。1ファイル4〜8秒かかります
- 目視、手動でやったほうが早い場合もあるかも?
Discussion