【Python実践プロジェクト】OCR(Tesseract)とPillowで画像内の個人情報に自動でモザイクをかける方法 🛡️

「ブログやSNSにスクリーンショットを載せたいけど、ユーザー名やメールアドレスを隠すのが面倒…」

「画像内の特定の文字を自動で見つけて、モザイクをかけるプログラムって作れないかな?」
「PythonでOCR(光学文字認識)ってどうやるの?」

こんにちは! Pythonプログラミング探検隊、隊長のPythonistaです! これまで私たちはPythonの様々な標準ライブラリや、NumPyのような強力な外部ライブラリを使ってきました。今回は、それらの知識を応用し、さらに一歩進んだ実用的なプロジェクトに挑戦します!

今回のテーマは、「OCR(光学文字認識)を利用して、画像内の特定のテキストに自動でモザイクをかけるツール」の開発です。Pythonの画像処理ライブラリPillowと、オープンソースのOCRエンジンであるTesseractを連携させることで、画像から文字を読み取り、指定した文字列の座標を特定して自動でモザイク処理を行います。この記事を最後まで読めば、面倒な手作業の画像加工から解放される、あなただけの便利ツールが手に入りますよ!


1. プロジェクトの概要と必要なツール(事前準備)

このプロジェクトでは、以下の2つの主要なライブラリと、OCRエンジン本体が必要です。まずは、開発を始める前に環境を整えましょう。

1.1. Tesseract OCR エンジンのインストール

まず、このプロジェクトの心臓部であるTesseract OCRエンジン本体を、お使いのシステムにインストールする必要があります。Tesseractは、画像からテキストを読み取るための非常に強力なオープンソースOCRエンジンです。

Ubuntu / Debian系 Linuxの場合:
ターミナルで以下のコマンドを実行します。日本語も認識できるように、日本語用のデータパックも一緒にインストールするのがおすすめです。

sudo apt update
sudo apt install tesseract-ocr tesseract-ocr-jpn

macOSの場合 (Homebrew使用):

brew install tesseract tesseract-lang

Windowsの場合:
Windows用のインストーラーが公開されています。以下のページなどからダウンロードしてインストールしてください。インストール時に、パスを通す設定や、日本語を含む追加言語の選択を忘れないようにしましょう。
Tesseract at UB Mannheim (Windows Installers)

インストール後、ターミナルやコマンドプロンプトでtesseract --versionと入力してバージョン情報が表示されれば成功です。

1.2. 必要なPythonライブラリのインストール

次に、PythonからTesseractを呼び出すためのライブラリと、画像処理を行うためのPillowをインストールします。お使いのPython環境(仮想環境など)で以下のコマンドを実行してください。

pip install Pillow pytesseract
  • Pillow: Pythonの画像処理におけるデファクトスタンダードライブラリです。
  • pytesseract: PythonからTesseract OCRエンジンを簡単に利用するためのラッパーライブラリです。

これで、開発の準備は完了です!


2. スクリプトの全体像(完成コード)

まずは、今回作成するスクリプトの全体像を見てみましょう。このコードをapply_mosaic.pyのようなファイル名で保存してください。各部分の詳しい解説はこの後でじっくり行います。

import pytesseract
from PIL import Image, ImageDraw

def apply_mosaic_to_text(image_path, target_text, mosaic_level=20):
    """
    画像内の指定されたテキストを検出し、その部分にモザイクをかけます。

    Args:
        image_path (str): 対象の画像ファイルパス。
        target_text (str): モザイクをかけたい文字列。
        mosaic_level (int): モザイクの粗さ。数値が大きいほど粗くなります。
    """
    try:
        # 画像を開く
        img = Image.open(image_path)
        img_rgb = img.convert("RGB") # Tesseractの精度向上のためRGBに変換
        draw = ImageDraw.Draw(img)

        print("画像からテキストを認識しています...")
        # OCRで画像から文字データ(位置情報を含む)を取得
        ocr_data = pytesseract.image_to_data(
            img_rgb, lang='jpn+eng', output_type=pytesseract.Output.DICT
        )

        found = False
        num_boxes = len(ocr_data['level'])
        # 認識された各単語をチェック
        for i in range(num_boxes):
            # 認識したテキストにターゲット文字列が含まれているか確認
            if target_text in ocr_data['text'][i]:
                found = True
                print(f"'{target_text}' を含む文字列 '{ocr_data['text'][i]}' を検出しました。")

                # モザイクをかける領域の座標を取得
                (x, y, w, h) = (
                    ocr_data['left'][i],
                    ocr_data['top'][i],
                    ocr_data['width'][i],
                    ocr_data['height'][i]
                )

                # 座標指定して元画像からその部分を切り出す
                box = (x, y, x + w, y + h)
                target_region = img.crop(box)

                # 切り出した領域を一度小さくリサイズ
                small_size = (
                    max(1, int(w / mosaic_level)),
                    max(1, int(h / mosaic_level))
                )
                small_region = target_region.resize(small_size, Image.Resampling.NEAREST)

                # 小さくした画像を元のサイズに拡大してモザイク効果を出す
                mosaic_region = small_region.resize(target_region.size, Image.Resampling.NEAREST)

                # 元の画像にモザイクをかけた領域を貼り付け
                img.paste(mosaic_region, box)

        if not found:
            print(f"画像内から '{target_text}' が検出されませんでした。")
            return

        # 拡張子を除いたファイル名を取得
        base_name, extension = os.path.splitext(image_path)
        output_path = f"{base_name}_mosaiced.{extension.lstrip('.')}"

        # モザイク処理した画像を保存
        img.save(output_path)
        print(f"モザイク処理が完了しました。出力ファイル: {output_path}")

    except FileNotFoundError:
        print(f"エラー: ファイル '{image_path}' が見つかりません。")
    except Exception as e:
        print(f"エラーが発生しました: {e}")

if __name__ == '__main__':
    # --- 設定項目 ---
    # モザイクをかけたい文字列
    TEXT_TO_HIDE = "モザイクをかけたい文字列"
# ---------------- # ユーザーに画像ファイルのパスを入力させる input_image_path = input("モザイクをかけたい画像ファイルのパスを入力してください: ") # 関数を実行 if input_image_path: apply_mosaic_to_text(input_image_path, TEXT_TO_HIDE)

3. コードの仕組みを徹底解説!

それでは、このスクリプトがどのように動作しているのか、重要な部分をステップバイステップで見ていきましょう。

3.1. OCRで文字情報を取得する

このスクリプトの心臓部が、pytesseractを使ったOCR処理です。

ocr_data = pytesseract.image_to_data(
    img_rgb, lang='jpn+eng', output_type=pytesseract.Output.DICT
)
  • pytesseract.image_to_data(): この関数は、画像からテキストを抽出するだけでなく、各単語(またはテキストブロック)の位置情報(左上のx, y座標、幅、高さ)や信頼度なども一緒に取得してくれます。
  • lang='jpn+eng': 日本語と英語の両方を認識対象として指定しています。これにより、両言語が混在した画像にも対応できます。
  • output_type=pytesseract.Output.DICT: 出力形式をPythonの辞書に指定しています。これにより、ocr_data['text']で認識されたテキストのリスト、ocr_data['left']で各テキストの左端のx座標のリスト、といった形でデータにアクセスできるようになり、非常に便利です。

3.2. ターゲット文字列の検出と座標取得

image_to_dataが返した辞書には、認識されたテキストブロックの情報がインデックスごとに格納されています。forループでこれを一つずつチェックしていきます。

for i in range(num_boxes):
    if target_text in ocr_data['text'][i]:
        # ...
        (x, y, w, h) = (
            ocr_data['left'][i],
            ocr_data['top'][i],
            ocr_data['width'][i],
            ocr_data['height'][i]
        )
        # ...

if target_text in ocr_data['text'][i]:の部分で、Tesseractが認識した一つのテキストブロック(単語やフレーズ)に、私たちが隠したい文字列が含まれているかをチェックしています。含まれていれば、同じインデックスiを使って、そのテキストブロックの座標(x, y)とサイズ(w, h)を取得します。

3.3. モザイク処理のアルゴリズム

座標が分かれば、あとはその領域にモザイクをかけるだけです。今回は、簡単ながら効果的な以下のアルゴリズムでモザイクを実現しています。

【画像推奨箇所: モザイクアルゴリズムの図解イメージ】

  1. 切り出し (Crop): まず、Pillowのcrop()メソッドを使って、モザイクをかけたい領域の画像を切り出します。
  2. 縮小 (Resize Small): 切り出した画像を、mosaic_levelで指定された粗さに従って、一度非常に小さいサイズにリサイズします。この時、補間方法としてImage.Resampling.NEARESTを指定するのがポイントです。これにより、色の平均化などが起こらず、ピクセルがブロック状になります。
  3. 拡大 (Resize Large): 小さくした画像を、元の切り出しサイズに再び拡大します。ここでもImage.Resampling.NEARESTを使うことで、ブロック状のピクセルがそのまま拡大され、モザイク効果が生まれます。
  4. 貼り付け (Paste): 最後に、生成されたモザイク画像を、元の画像の正しい位置にpaste()メソッドで貼り付けます。
box = (x, y, x + w, y + h)
target_region = img.crop(box)

small_size = (max(1, int(w / mosaic_level)), max(1, int(h / mosaic_level)))
small_region = target_region.resize(small_size, Image.Resampling.NEAREST)

mosaic_region = small_region.resize(target_region.size, Image.Resampling.NEAREST)

img.paste(mosaic_region, box)

mosaic_levelの値を大きくすると、中間のsmall_sizeがより小さくなるため、モザイクがより粗くなります。


4. スクリプトの使い方

  1. 上記のコード全体をapply_mosaic.pyとして保存します。
  2. コード内のTEXT_TO_HIDE = "モザイクをかけたい文字列"の部分を、あなたが実際に隠したい文字列に変更します。
  3. ターミナルを開き、以下のコマンドでスクリプトを実行します。
    python apply_mosaic.py
    
  4. 「モザイクをかけたい画像ファイルのパスを入力してください:」と表示されたら、処理したい画像のパス(例: /home/user/Pictures/my_screenshot.png)を入力してEnterキーを押します。
  5. 処理が完了すると、元の画像と同じ場所に「元のファイル名_mosaiced.拡張子」という名前で新しい画像が保存されます。

5. まとめとさらなる発展のヒント

今回は、Pillowpytesseractという2つの強力なライブラリを組み合わせて、実用的な「テキスト自動モザイクツール」を作成しました。このプロジェクトを通して、

  • PythonからOCRエンジンを利用する方法。
  • OCRで得られた位置情報を使って、画像内の特定の領域を操作する方法。
  • 簡単なアルゴリズムでモザイク効果を実装する方法。

といった、より高度で実践的なスキルを学ぶことができました。

このスクリプトは、さらに以下のような改良を加えることで、もっと便利なツールに進化させることができます。

  • 複数の文字列に対応: 隠したい文字列をリストで複数指定できるようにする。
  • 正規表現の活用: reモジュールを使って、メールアドレスや電話番号のような特定の「パターン」に一致するテキスト全てにモザイクをかける。
  • コマンドライン引数の利用: argparseモジュールを使って、隠したい文字列や画像パス、モザイクレベルなどを、スクリプト実行時にコマンドラインから指定できるようにする。
  • GUIの作成: TkinterPySimpleGUIなどを使って、ドラッグ&ドロップで画像を指定できるようなグラフィカルなアプリケーションにする。

学んだ知識を組み合わせることで、アイデアは無限に広がります。ぜひ、このスクリプトをあなた自身のニーズに合わせてカスタマイズしてみてください!

その他の投稿はこちら

コメント

このブログの人気の投稿

タイトルまとめ

これで迷わない!WindowsでPython環境構築する一番やさしい方法 #0

【Python標準ライブラリ完結!】11の冒険をありがとう!君のPython力が飛躍する「次の一歩」とは? 🚀