6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

画像内個人情報を黒消ししてみた(名前編)

Last updated at Posted at 2022-06-25

はじめに

画像内の個人情報を黒消ししてみます(Pythonで実装)。
画像内の人名や地名を見つけ、黒塗りするシンプルなものです。

※ 画像内個人情報を黒消ししてみた(電話番号編)はこちら

黒消し結果から

処理前の画像 処理後の画像
input.png output.png

使用したツール

  • Tesseract
    • さまざまなオペレーティングシステム上で動作する光学式文字認識(OCR)エンジン
    • Apache License下でリリースされたフリーソフトウェア
  • OpenCV
    • 画像処理・画像解析および機械学習等の機能を持つライブラリ
    • C/C++、Java、Python、MATLABで使用可能
    • POSIX準拠のUnix系OS、Linux、Windows、Android、iOS等をサポート
  • GiNZA
    • オープンソースの日本語自然言語処理ライブラリ
    • 高速かつ高精度な日本語の解析処理/依存構造(係り受け)解析/固有表現抽出
    • 高度なNLP技術を国際化されたフレームワーク上で利用可能
  • spaCy
    • 高度な自然言語処理を行うため、PythonとCythonで書かれたOSSライブラリ
    • 多言語解析処理と固有表現抽出のため、統計的ニューラルネットワークモデルや字句解析モデルを提供

開発環境

  • CPU: Intel(R) Core(TM) 3.30GHz(4コア8スレッド)
  • メモリ: 16 GB
  • OS: Windows 10
  • Python 3.10

事前準備

Tesserractをインストール

  • Tesseract OCR 64bit版をダウンロード
    tesseract-ocr-w64-setup-v5.1.0.20220510.exe(64 bit)

  • インストール時に、以下日本語オプションにチェックを入れる

    • Additional script data (download)
      • Japanese script
      • Japanese vertical script
    • Additional language data (download)
      • Japanese
      • Japanese (vertical)

Tesseract OCRのPythonラッパーpytesseractをインストール

pip3 install pytesseract

OpenCVのPythonラッパーopencv-pythonをインストール

pip3 install opencv-python

GiNZAの日本語モデルja_ginzaをインストール

pip3 install ja-ginza

サンプルコード

  • 実行方法
    • python redact.py
  • 実行結果
    • 入力画像: カレントディレクトリのinput.png
    • 標準出力: 抽出されたテキストと固有名詞の判定結果
    • 出力画像: カレントディレクトリにoutput.pngが生成される
  • ※ tesseract実行ファイルパスを通す必要あり
redact.py
import pytesseract as pt
import cv2
import re
import spacy

# tessdataディレクトリを指定
tessdata_dir_config = '--tessdata-dir "C:/Program Files/Tesseract-OCR/tessdata"'
# tesseract実行ファイルを指定
pt.pytesseract.tesseract_cmd = 'C:/Program Files/Tesseract-OCR/tesseract.exe'

# spaCyからGiNZAのja_ginzaモデルをロード
nlp = spacy.load('ja_ginza')

# 固有名詞の判定
def is_named_entity(text: str):
    # テキストをDocクラスに変換
    doc = nlp(text)
    # DocクラスはTokenクラスのイテレーター
    for token in doc:
        # 品詞タグから固有名詞の単語を抽出
        if token.pos_ in ['PROPN']:
            # token.textは日本語形態素の単位
            print(token.text, token.tag_, type(token))
            return True
    return False

# 黒消し処理
def redact(img: cv2.Mat, details: dict, idx: int):
    # 黒消し範囲
    (x, y, w, h) = (details['left'][idx], details['top'][idx],
                    details['width'][idx], details['height'][idx])
    start = (x, y)
    end = (x + w, y + h)
    color = (0, 0, 0)
    thickness = -1
    # 黒消し実施
    return cv2.rectangle(img, start, end, color, thickness)

def redact_image(infile: str, keys: list = None):
    # opencvで画像を読み込む
    img = cv2.imread(infile)
    # 画像をバイナリに変換
    bin_img = cv2.bitwise_not(img)
    # 画像からテキスト抽出(日本語と英語を指定、psm=6: 単一テキストブロックとみなす)
    details = pt.image_to_data(bin_img, output_type=pt.Output.DICT,
                               lang='jpn+eng', config=r'--psm 6')
    # マッチした回数
    matches = 0
    for idx in range(len(details['text'])):
        # 抽出テキストの信頼度スコアが30%以上のみ使用
        if float(details['conf'][idx]) > 30.0:
            print(details['text'][idx])
            if is_named_entity(details['text'][idx]):
                # 固有名詞を黒消し
                matches += 1
                img = redact(img, details, idx)
            elif keys:
                # 黒消しキーワードで検索
                for key in keys:
                    results = re.findall(key, details['text'][idx], re.IGNORECASE)
                    for result in results:
                        matches += 1
                        img = redact(img, details, idx)
    if matches > 0:
        redacted_img = img.copy()
        # 画像を保存
        cv2.imwrite("output.png", redacted_img)  

if __name__ == '__main__':
    # 画像内の固有名詞を黒消し
    redact_image(infile='input.png')
  • 実行結果
>python redact.py
T
123-4567
東京
東京 名詞-固有名詞-地名-一般 <class 'spacy.tokens.token.Token'>
都
東京
東京 名詞-固有名詞-地名-一般 <class 'spacy.tokens.token.Token'>
市
東京
東京 名詞-固有名詞-地名-一般 <class 'spacy.tokens.token.Token'>
町
1-2-3
桃太郎
桃太郎 名詞-固有名詞-人名-名 <class 'spacy.tokens.token.Token'>
様
電話
番号
000-1111-2222
>dir output.png

おわりに

画像内の名前など固有名詞を、黒消ししてみました。
いろいろ改善は必要ですが、ひとまず。

6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?