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

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +57 -41
app.py CHANGED
@@ -10,93 +10,109 @@ DB_PATH = "my_db"
10
  if not os.path.exists(DB_PATH):
11
  os.makedirs(DB_PATH, exist_ok=True)
12
 
13
- # 処理フレムの間隔(例2なら2フレームに1回解析)
14
  frame_count = 0
15
 
16
  # --- 関数定義 ---
17
 
18
  def register_face(image, name):
19
- """英語名制限して保存する安全版"""
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
  image_bgr = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
29
  cv2.imwrite(file_path, image_bgr)
30
 
31
- # 登録後にキャッシュを削除
32
- if os.path.exists(os.path.join(DB_PATH, "ds_model_vgg_face.pkl")):
33
- os.remove(os.path.join(DB_PATH, "ds_model_vgg_face.pkl"))
 
34
 
35
- return f"「{safe_name}」を登録しました。②タブへ進んでください。"
36
  except Exception as e:
37
  return f"エラー: {str(e)}"
38
 
39
  def track_oshi(frame):
40
- """カメラ映像から推しを判定"""
41
  if frame is None:
42
  return None
43
 
44
  global frame_count
45
  frame_count += 1
46
 
47
- # 【修正箇所】演算子と変数名修正
48
- # 2フレームに1回だけ重い処理を行うことで動作を軽くする
49
- if frame_count % 2 != 0:
50
- return frame
 
 
 
 
51
 
52
  try:
53
- # 顔の検索(検出器高速なopencv
54
- results = DeepFace.find(
55
- img_path=frame,
56
- db_path=DB_PATH,
57
- enforce_detection=False,
58
- detector_backend='opencv',
59
- silent=True
60
- )
61
-
62
- output_frame = frame.copy()
63
-
64
- for df in results:
65
- if not df.empty:
 
66
  for _, row in df.iterrows():
67
  name = os.path.basename(row['identity']).split('.')[0]
68
- x, y, w, h = int(row['source_x']), int(row['source_y']), int(row['source_w']), int(row['source_h'])
 
 
 
69
 
70
- # 枠と名前を描画
71
- cv2.rectangle(output_frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
72
- cv2.putText(output_frame, f"TARGET: {name}", (x, y-10),
73
- cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
74
 
75
  return output_frame
76
 
77
  except Exception as e:
78
- return frame
 
 
 
79
 
80
- # --- UI (Gradio) ---
81
 
82
  with gr.Blocks() as demo:
83
- gr.Markdown("# 🎥 リアルタイ推し追跡")
 
84
 
85
  with gr.Tabs():
86
  with gr.TabItem("① 推し登録"):
87
  with gr.Row():
88
- reg_in = gr.Image(label="推しの写真")
89
- reg_name = gr.Textbox(label="名前(半角英数字)", value="oshi")
90
- reg_btn = gr.Button("登録")
91
- reg_status = gr.Textbox(label="ステータス")
92
  reg_btn.click(register_face, inputs=[reg_in, reg_name], outputs=reg_status)
93
 
94
  with gr.TabItem("② リアルタイム追跡"):
95
- gr.Markdown("カメラを起動して自分や推しを映してください。")
96
- input_video = gr.Image(sources=["webcam"], streaming=True)
97
- output_video = gr.Image(label="解析結果")
 
 
98
 
99
- # ストリーミング設定
100
  input_video.stream(track_oshi, inputs=[input_video], outputs=[output_video])
101
 
102
  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
 
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__":