見出し画像

【Python】画像から人の顔を検出して別の画像に置き換えるプログラムを作ってみた

画像の人の顔を加工して消したい!

Pythonなら簡単にできますよ(^^)

プログラミング副業挑戦中の そばごろう です。

twitter ☛https://twitter.com/sobagoro1

今回はChatGPTにPythonで画像から人の顔を検出し別の画像に置き換えプログラムを書いてもらう手順をまとめます。

1.ChatGPTを起動

https://chat.openai.com/

2.以下のプロンプトを入力

Pythonで以下のプログラムを書いて
1.ポップアップで画像を指定
2.ポップアップで置き換える画像を指定
3.画像の中に人の顔があれば2.で指定した置き換える
4.置き換えた画像を別名(元画像のファイル名+実行日時)にして元ファイルがあったフォルダに保存する
5.置き換えが完了したことをポップアップで表示する
※顔認識にはopencv-pythonを使用

ChatGPTに入力したプロンプト

3.ChatGPTの返事を確認する

すぐに返答が表示されました。

何回かやり取りして使い勝手が良いプログラムに修正しました。

以下のリンクでChatGPTとのやり取りを共有します。

4.プログラムソースの修正

ChatGPTが作成したソースを実行すると、指定したフォルダに全角文字(日本語)が含まれるとエラーになりました。

以下記事を参考にimread、imwriteメソッドに対策を加えたところエラーは起きなくなりました。

最終的なソース

import cv2
import os
import datetime
import tkinter as tk
from tkinter import filedialog, messagebox
import numpy as np  

def imread2Byte(filename, flags=cv2.IMREAD_COLOR, dtype=np.uint8):
    try:
        n = np.fromfile(filename, dtype)
        img = cv2.imdecode(n, flags)
        return img
    except Exception as e:
        print(e)
        return None
    
def imwrite2Byte(filename, img, params=None):
    try:
        ext = os.path.splitext(filename)[1]
        result, n = cv2.imencode(ext, img, params)

        if result:
            with open(filename, mode='w+b') as f:
                n.tofile(f)
            return True
        else:
            return False
    except Exception as e:
        print(e)
        return False

def replace_faces(input_path, replacement_path, output_folder):
    # 画像読み込み
    image = imread2Byte(input_path)
    replacement_image = imread2Byte(replacement_path)

    # Haarcascadesを使用して顔検出器を初期化
    face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
    
    # 顔検出
    gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    faces = face_cascade.detectMultiScale(gray_image, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
    
    if len(faces) == 0:
        messagebox.showinfo("Info", "顔が検出されませんでした。")
        return

    # 置き換え処理
    for (x, y, w, h) in faces:
        resized_replacement = cv2.resize(replacement_image, (w, h))
        image[y:y+h, x:x+w] = resized_replacement
    
    # 出力ファイル名を作成
    output_filename = os.path.splitext(os.path.basename(input_path))[0] + '_' + datetime.datetime.now().strftime('%Y%m%d%H%M%S') + '.png'
    output_path = os.path.join(output_folder, output_filename)
    
    # 画像保存
    imwrite2Byte(output_path, image)
    
    messagebox.showinfo("Info", "置き換えが完了し、画像が保存されました。")

def select_image(title):
    file_path = filedialog.askopenfilename(title=title, filetypes=[("Image files", "*.jpg *.jpeg *.png")])
    return file_path

def main():
    root = tk.Tk()
    root.withdraw()  # ルートウィンドウを非表示にする
    
    input_image_path = select_image("変換したい画像を選択")
    if not input_image_path:
        return
    
    replacement_image_path = select_image("顔を隠す画像を選択")
    if not replacement_image_path:
        return
    
    output_folder = os.path.dirname(input_image_path)
    
    replace_faces(input_image_path, replacement_image_path, output_folder)

if __name__ == "__main__":
    main()

5.作成したプログラムの動作確認

作成したソースをVS Codeで動作確認します。

デバッグ実行ボタンを押すとフォルダ選択のポップアップが表示されました。

変換したい画像を選択します。

変換のテストにはコチラのサイトの画像を使用しました

続けて顔を隠すのに使う画像を選択します。

すぐに完了メッセージが表示されました。

置き換え前ファイルがあったフォルダに顔が隠された画像が保管されていました。

複数人が映っている画像でも問題なく動きました。

目が映っていない顔は検出しずらいようで以下の画像ではうまく変換ができませんでした。

6.今回できなかったこと

プログラムをexe化するとエラーになる

プログラムをexe化して実行すると以下のエラーになりました(VS Code上はエラーなく稼働)。

色々調べて修正しましたが今の私の知識では解消できませんでした。

cv2.error: OpenCV(4.8.0) D:\a\opencv-python\opencv-python\opencv\modules\objdetect\src\cascadedetect.cpp:1689: error: (-215:Assertion failed) !empty() in function 'cv::CascadeClassifier::detectMultiScale'

顔を隠す画像をexe内に組み込む

顔を隠すのに決まった画像を設定し、それをexeの中に組み込めないかと考えましたが実現できませんでした。

【参考にした記事】

絵文字を使って顔を隠す

画像の代わりに絵文字(☺)で顔を隠すことができないかと検討しました。

しかし、結局「絵文字の画像」をどこかに持つ必要があり、それをexe化することが自分の知識ではできませんでした。

私のスキルが上がって解決できたら追記しますm(__)m

まとめ

ChatGPTにPythonで画像から人の顔を検出し別の画像に置き換えプログラムを書いてもらう手順をまとめました。

うまくいかない部分もありましたが色々調べて学ぶことができました。

同じように勉強中の方の参考になればうれしいです。

私のプロフィール↓

勉強メモ シリーズ↓

ChatGPTを使ったプログラミング↓

最後まで閲覧ありがとうございましたm(__)m

この記事が気に入ったらサポートをしてみませんか?