Corin1998 commited on
Commit
b04cf7c
·
verified ·
1 Parent(s): 55048e0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +58 -79
app.py CHANGED
@@ -10,109 +10,88 @@ DB_PATH = "my_db"
10
  if not os.path.exists(DB_PATH):
11
  os.makedirs(DB_PATH, exist_ok=True)
12
 
13
- # グローバル変数:フレームを数える用
14
  frame_count = 0
 
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
- # 安全なファイル名を作成(英数字のみ)
 
 
 
25
  safe_name = "".join([c for c in name if c.isalnum()])
26
  file_path = os.path.join(DB_PATH, f"{safe_name}.jpg")
27
-
28
- # 保存
29
- image_bgr = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
30
- cv2.imwrite(file_path, image_bgr)
31
-
32
- # 【重要】新しい人が登録されたらDeepFaceのキャッシュを消す
33
- cache_file = os.path.join(DB_PATH, "ds_model_vgg_face.pkl")
34
- if os.path.exists(cache_file):
35
- os.remove(cache_file)
36
-
37
- return f"「{safe_name}」を登録完了! ②タブでカメラを映してください。"
38
  except Exception as e:
39
  return f"エラー: {str(e)}"
40
 
41
  def track_oshi(frame):
42
- """Webカメラの映像を解析して推しを探す"""
43
- if frame is None:
44
- return None
45
 
46
- global frame_count
47
  frame_count += 1
48
-
49
- # 表示用のコピーを作成
50
  output_frame = frame.copy()
51
 
52
- # 画面上に「AIが動いている証拠」を表示
53
- # これが動いていれば、システムはフリーズしていません
54
- status_text = f"Frame: {frame_count} | AI Scanning..."
55
- cv2.putText(output_frame, status_text, (10, 30),
56
- cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 0), 2)
57
-
58
- try:
59
- # 無料CPUだと重いため、10フレームに1回だけ「誰か?」を判定する
60
- # それ以外のフレームは、前回の結果を表示するか、スルーする
61
- if frame_count % 10 == 0:
62
- results = DeepFace.find(
63
- img_path=frame,
64
- db_path=DB_PATH,
65
- enforce_detection=False,
66
- detector_backend='opencv', # 最速の検出器
67
- silent=True
68
- )
69
-
70
- if results and not results[0].empty:
71
- df = results[0]
72
- # 検出された全員分ループ
73
- for _, row in df.iterrows():
74
- name = os.path.basename(row['identity']).split('.')[0]
75
- x = int(row['source_x'])
76
- y = int(row['source_y'])
77
- w = int(row['source_w'])
78
- h = int(row['source_h'])
79
-
80
- # 枠と名前を描画(目立つように太めの緑枠)
81
- cv2.rectangle(output_frame, (x, y), (x+w, y+h), (0, 255, 0), 4)
82
- cv2.putText(output_frame, f"TARGET: {name}", (x, y-15),
83
- cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 3)
84
-
85
- return output_frame
86
 
87
- except Exception as e:
88
- # エラーが起きた場合は画面に小さく表示
89
- cv2.putText(output_frame, "Searching...", (10, 60),
90
- cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1)
91
- return output_frame
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
 
93
- # --- UI (Gradio) の構築 ---
94
 
95
  with gr.Blocks() as demo:
96
- gr.Markdown("# 🎥 リアルタイム推し追跡 (Hugging Face版)")
97
- gr.Markdown("無料CPU環境のため、反応には数秒の遅延があります。カメラの前で少し静止してください。")
98
 
99
  with gr.Tabs():
100
- with gr.TabItem("① 推し登録"):
101
- with gr.Row():
102
- reg_in = gr.Image(label="推しの顔写真")
103
- reg_name = gr.Textbox(label="名前(半角英数字)", value="MyOshi")
104
- reg_btn = gr.Button("データベースに登録")
105
- reg_status = gr.Textbox(label="ログ")
106
- reg_btn.click(register_face, inputs=[reg_in, reg_name], outputs=reg_status)
107
 
108
- with gr.TabItem("② リアルタイム追跡"):
109
- with gr.Row():
110
- # 左側:自分のWebカメラ映像
111
- input_video = gr.Image(sources=["webcam"], streaming=True, label="Webカメラ(入力)")
112
- # 右側:AIの解析結果
113
- output_video = gr.Image(label="AI解析(結果)")
114
-
115
- # ストリーミング接続
116
  input_video.stream(track_oshi, inputs=[input_video], outputs=[output_video])
117
 
118
  if __name__ == "__main__":
 
10
  if not os.path.exists(DB_PATH):
11
  os.makedirs(DB_PATH, exist_ok=True)
12
 
13
+ # 処理を間引くためのカウンター
14
  frame_count = 0
15
+ last_status = "Waiting..."
16
 
17
  # --- 関数定義 ---
18
 
19
  def register_face(image, name):
20
+ """画像を1枚だけDBに保存する"""
21
  if image is None or name.strip() == "":
22
+ return "名前を入力してください。"
 
23
  try:
24
+ # DBを一度空にして、常に「最新の1枚」とだけ比較するようにする(超軽量化)
25
+ for f in os.listdir(DB_PATH):
26
+ os.remove(os.path.join(DB_PATH, f))
27
+
28
  safe_name = "".join([c for c in name if c.isalnum()])
29
  file_path = os.path.join(DB_PATH, f"{safe_name}.jpg")
30
+ cv2.imwrite(file_path, cv2.cvtColor(image, cv2.COLOR_RGB2BGR))
31
+ return f"「{safe_name}」をターゲットに設定しました!"
 
 
 
 
 
 
 
 
 
32
  except Exception as e:
33
  return f"エラー: {str(e)}"
34
 
35
  def track_oshi(frame):
36
+ """Webカメラの映像を解析(1対1の超軽量比較)"""
37
+ if frame is None: return None
 
38
 
39
+ global frame_count, last_status
40
  frame_count += 1
 
 
41
  output_frame = frame.copy()
42
 
43
+ # 画面に情報を表示
44
+ cv2.putText(output_frame, f"Frame: {frame_count}", (10, 30),
45
+ cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 255, 0), 2)
46
+ cv2.putText(output_frame, f"Status: {last_status}", (10, 60),
47
+ cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 255), 2)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
 
49
+ # 30フレーム(数秒〜10秒に一度)だけ解析を行う
50
+ if frame_count % 30 == 0:
51
+ db_images = [f for f in os.listdir(DB_PATH) if f.endswith(".jpg")]
52
+ if db_images:
53
+ last_status = "Analyzing..."
54
+ target_path = os.path.join(DB_PATH, db_images[0])
55
+ try:
56
+ # findではなく、最も軽い「verify」を使用
57
+ result = DeepFace.verify(
58
+ img1_path = frame,
59
+ img2_path = target_path,
60
+ enforce_detection = False,
61
+ detector_backend = 'opencv',
62
+ model_name = 'VGG-Face', # 最も標準的なモデル
63
+ silent = True
64
+ )
65
+
66
+ if result["verified"]:
67
+ last_status = "TARGET FOUND!"
68
+ # 画面中央に大きく表示
69
+ cv2.putText(output_frame, "MATCH!!!", (100, 200),
70
+ cv2.FONT_HERSHEY_SIMPLEX, 2.0, (0, 255, 0), 5)
71
+ else:
72
+ last_status = "Not Match"
73
+ except Exception as e:
74
+ last_status = "Scan Error"
75
+
76
+ return output_frame
77
 
78
+ # --- UI構築 ---
79
 
80
  with gr.Blocks() as demo:
81
+ gr.Markdown("# 🎥 超軽量版・推し認識プロトタイプ")
82
+ gr.Markdown("Hugging Faceの無料CPUでも動くよう、解析頻度を極限まで落としています。")
83
 
84
  with gr.Tabs():
85
+ with gr.TabItem("① ターゲット登録"):
86
+ reg_in = gr.Image(label="あなたの顔写真")
87
+ reg_name = gr.Textbox(label="名前(英数字)", value="Me")
88
+ reg_btn = gr.Button("この人をターゲットに設定")
89
+ reg_out = gr.Textbox(label="ログ")
90
+ reg_btn.click(register_face, inputs=[reg_in, reg_name], outputs=reg_out)
 
91
 
92
+ with gr.TabItem("② リアルタイム検証"):
93
+ input_video = gr.Image(sources=["webcam"], streaming=True)
94
+ output_video = gr.Image(label="解析結果(数秒に1回更新)")
 
 
 
 
 
95
  input_video.stream(track_oshi, inputs=[input_video], outputs=[output_video])
96
 
97
  if __name__ == "__main__":