Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -5,135 +5,94 @@ import numpy as np
|
|
| 5 |
import os
|
| 6 |
import shutil
|
| 7 |
|
| 8 |
-
#
|
| 9 |
-
# 登録した画像を保存する簡易データベースフォルダ
|
| 10 |
DB_PATH = "my_db"
|
| 11 |
|
| 12 |
-
#
|
| 13 |
-
if
|
| 14 |
shutil.rmtree(DB_PATH)
|
| 15 |
os.makedirs(DB_PATH, exist_ok=True)
|
| 16 |
|
| 17 |
-
#
|
|
|
|
| 18 |
def register_face(image, name):
|
| 19 |
-
"""
|
| 20 |
-
画像をアップロードして、DBフォルダに保存する関数
|
| 21 |
-
"""
|
| 22 |
if image is None or name.strip() == "":
|
| 23 |
return "画像と名前を入力してください。"
|
| 24 |
-
|
| 25 |
try:
|
| 26 |
-
#
|
| 27 |
image_bgr = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
cv2/imwrite(file_path, image_bgr)
|
| 33 |
-
|
| 34 |
-
return f"「{name}」さんを登録しました!"
|
| 35 |
-
|
| 36 |
except Exception as e:
|
| 37 |
return f"エラーが発生しました: {str(e)}"
|
| 38 |
|
| 39 |
def recognize_face(target_image):
|
| 40 |
-
"""
|
| 41 |
-
ターゲット画像の中から、登録済みの顔を探す関数
|
| 42 |
-
"""
|
| 43 |
if target_image is None:
|
| 44 |
return None, "画像をアップロードしてください。"
|
| 45 |
-
|
| 46 |
-
# DBフォルダがからの場合は何もしない
|
| 47 |
if not os.listdir(DB_PATH):
|
| 48 |
-
return target_image, "
|
| 49 |
|
| 50 |
try:
|
| 51 |
-
#
|
| 52 |
-
#enforce_detection=False:顔がみるからなくてもエラーにしない
|
| 53 |
results = DeepFace.find(img_path=target_image, db_path=DB_PATH, enforce_detection=False, silent=True)
|
| 54 |
-
|
| 55 |
-
# 結果を描画するためのコピーを作成
|
| 56 |
output_image = target_image.copy()
|
| 57 |
-
|
| 58 |
found_names = []
|
| 59 |
|
| 60 |
-
# resultsはリストで帰ってくる(複数人検出に対応)
|
| 61 |
for df in results:
|
| 62 |
if df.empty: continue
|
| 63 |
-
|
| 64 |
-
# 見つかった顔の数だけループ
|
| 65 |
for index, row in df.iterrows():
|
| 66 |
-
#
|
| 67 |
-
|
| 68 |
-
name = os.path.basename(
|
| 69 |
found_names.append(name)
|
| 70 |
-
|
| 71 |
-
#
|
| 72 |
-
x = row['source_x']
|
| 73 |
-
y
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
#枠の描写(緑色)
|
| 78 |
-
cv2.rectangle(output_image, (x, y), (x + w, y + h), (0, 255, 0), 3)
|
| 79 |
-
#名前の描写
|
| 80 |
-
cv2.putText(output_image, name, (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2)
|
| 81 |
-
|
| 82 |
-
if found_names:
|
| 83 |
message = "登録された推しは見つかりませんでした。"
|
| 84 |
else:
|
| 85 |
-
message = f"
|
| 86 |
|
| 87 |
return output_image, message
|
| 88 |
|
| 89 |
except Exception as e:
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
gr.
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
rec_image_input = gr.Image(label="テキスト画像(探したい写真)")
|
| 119 |
-
rec_button = gr.Button("推しを探す!")
|
| 120 |
-
with gr.Column():
|
| 121 |
-
rec_image_output = gr.Image(label="検出結果")
|
| 122 |
-
rec_output_text = gr.Textbox(label="結果メッセージ")
|
| 123 |
-
|
| 124 |
-
rec_button.click(
|
| 125 |
-
recognize_face,
|
| 126 |
-
inputs=[rec_image_input],
|
| 127 |
-
outputs=[rec_image_output, rec_output_text]
|
| 128 |
-
)
|
| 129 |
-
|
| 130 |
-
#タブでまとめる
|
| 131 |
-
demo = gr.TabbeInterface(
|
| 132 |
-
[register_tab, recognize_tab],
|
| 133 |
-
["①推し登録", "②推しを探す"],
|
| 134 |
-
title="推し認識AIプロトタイプ(DeepFace Demo)"
|
| 135 |
-
)
|
| 136 |
-
|
| 137 |
-
# アプリの起動
|
| 138 |
if __name__ == "__main__":
|
| 139 |
demo.launch()
|
|
|
|
| 5 |
import os
|
| 6 |
import shutil
|
| 7 |
|
| 8 |
+
# --- 設定 ---
|
|
|
|
| 9 |
DB_PATH = "my_db"
|
| 10 |
|
| 11 |
+
# 起動時にDBフォルダをリセット(Hugging Faceの環境をクリーンに保つため)
|
| 12 |
+
if os.path.exists(DB_PATH):
|
| 13 |
shutil.rmtree(DB_PATH)
|
| 14 |
os.makedirs(DB_PATH, exist_ok=True)
|
| 15 |
|
| 16 |
+
# --- 関数定義 ---
|
| 17 |
+
|
| 18 |
def register_face(image, name):
|
| 19 |
+
"""画像をDBフォルダに保存する"""
|
|
|
|
|
|
|
| 20 |
if image is None or name.strip() == "":
|
| 21 |
return "画像と名前を入力してください。"
|
| 22 |
+
|
| 23 |
try:
|
| 24 |
+
# OpenCV形式に変換して保存
|
| 25 |
image_bgr = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
|
| 26 |
+
# ここを修正:os.path.join です(スラッシュは不要)
|
| 27 |
+
file_path = os.path.join(DB_PATH, f"{name}.jpg")
|
| 28 |
+
cv2.imwrite(file_path, image_bgr)
|
| 29 |
+
return f"「{name}」さんを登録しました!"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
except Exception as e:
|
| 31 |
return f"エラーが発生しました: {str(e)}"
|
| 32 |
|
| 33 |
def recognize_face(target_image):
|
| 34 |
+
"""画像から登録済みの顔を探す"""
|
|
|
|
|
|
|
| 35 |
if target_image is None:
|
| 36 |
return None, "画像をアップロードしてください。"
|
| 37 |
+
|
|
|
|
| 38 |
if not os.listdir(DB_PATH):
|
| 39 |
+
return target_image, "まだ誰も登録されていません。「推し登録」タブで登録してください。"
|
| 40 |
|
| 41 |
try:
|
| 42 |
+
# 認識の実行
|
|
|
|
| 43 |
results = DeepFace.find(img_path=target_image, db_path=DB_PATH, enforce_detection=False, silent=True)
|
| 44 |
+
|
|
|
|
| 45 |
output_image = target_image.copy()
|
|
|
|
| 46 |
found_names = []
|
| 47 |
|
|
|
|
| 48 |
for df in results:
|
| 49 |
if df.empty: continue
|
|
|
|
|
|
|
| 50 |
for index, row in df.iterrows():
|
| 51 |
+
# 登録名を取得
|
| 52 |
+
full_path = row['identity']
|
| 53 |
+
name = os.path.basename(full_path).split('.')[0]
|
| 54 |
found_names.append(name)
|
| 55 |
+
|
| 56 |
+
# 座標の取得と描画
|
| 57 |
+
x, y, w, h = int(row['source_x']), int(row['source_y']), int(row['source_w']), int(row['source_h'])
|
| 58 |
+
cv2.rectangle(output_image, (x, y), (x+w, y+h), (0, 255, 0), 3)
|
| 59 |
+
cv2.putText(output_image, name, (x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2)
|
| 60 |
+
|
| 61 |
+
if not found_names:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 62 |
message = "登録された推しは見つかりませんでした。"
|
| 63 |
else:
|
| 64 |
+
message = f"発見しました!: {', '.join(set(found_names))}"
|
| 65 |
|
| 66 |
return output_image, message
|
| 67 |
|
| 68 |
except Exception as e:
|
| 69 |
+
return target_image, f"認識エラー: {str(e)}"
|
| 70 |
+
|
| 71 |
+
# --- UI (Gradio) の構築 ---
|
| 72 |
+
|
| 73 |
+
with gr.Blocks() as demo:
|
| 74 |
+
gr.Markdown("# 🌟 推し認識AIプロトタイプ")
|
| 75 |
+
gr.Markdown("まずは『推し登録』で写真をアップし、その後『推しを探す』で判定してください。")
|
| 76 |
+
|
| 77 |
+
with gr.Tabs():
|
| 78 |
+
with gr.TabItem("① 推し登録"):
|
| 79 |
+
with gr.Row():
|
| 80 |
+
reg_input_img = gr.Image(label="推しの写真")
|
| 81 |
+
reg_input_name = gr.Textbox(label="推しの名前")
|
| 82 |
+
reg_btn = gr.Button("データベースに登録")
|
| 83 |
+
reg_status = gr.Textbox(label="登録状況")
|
| 84 |
+
|
| 85 |
+
reg_btn.click(register_face, inputs=[reg_input_img, reg_input_name], outputs=reg_status)
|
| 86 |
+
|
| 87 |
+
with gr.TabItem("② 推しを探す"):
|
| 88 |
+
with gr.Row():
|
| 89 |
+
rec_input_img = gr.Image(label="判定したい画像")
|
| 90 |
+
rec_output_img = gr.Image(label="判定結果")
|
| 91 |
+
rec_btn = gr.Button("推しを検索!")
|
| 92 |
+
rec_status = gr.Textbox(label="結果メッセージ")
|
| 93 |
+
|
| 94 |
+
rec_btn.click(recognize_face, inputs=[rec_input_img], outputs=[rec_output_img, rec_status])
|
| 95 |
+
|
| 96 |
+
# アプリ起動
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 97 |
if __name__ == "__main__":
|
| 98 |
demo.launch()
|