vivek9chavan commited on
Commit
a9cec68
·
verified ·
1 Parent(s): 12a3802

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +35 -59
app.py CHANGED
@@ -7,95 +7,81 @@ from dotenv import load_dotenv
7
  from google import genai
8
  from google.genai import types
9
 
10
- # Import our DINO processing function
11
- from dino_processor import process_video_with_dino
12
 
13
- # --- Configuration and Client Initialization ---
14
  load_dotenv()
15
  try:
16
- client = genai.Client(api_key=os.environ["GEMINI_API_KEY"])
17
  except KeyError:
18
  raise gr.Error("FATAL: GEMINI_API_KEY not found. Please set it in your Hugging Face Space secrets.")
19
 
 
 
20
  # --- Main Gradio Generator Function ---
21
  def full_analysis(video_file_path, user_observations):
22
  if not video_file_path:
23
- # Yield a single update and stop
24
- yield "Please upload a video first.", "", "", None, None
25
  return
26
 
27
- # --- Stage 1: Gemini Analysis (Fast) ---
28
  print("--- Starting Device Analysis ---")
29
  device_type, condition, reason = "Processing...", "Processing...", "Processing..."
30
-
31
- # Immediately update the UI to show that Gemini is working
32
- yield device_type, condition, reason, None, None
33
 
34
  uploaded_file = None
35
  try:
36
- uploaded_file = client.files.upload(file=video_file_path)
37
  while uploaded_file.state.name == "PROCESSING":
38
  time.sleep(5)
39
- uploaded_file = client.files.get(name=uploaded_file.name)
40
  if uploaded_file.state.name != "ACTIVE":
41
  raise Exception(f"File processing failed for Gemini. State: {uploaded_file.state.name}")
42
 
43
  prompt = f"""
44
- Analyze the provided video and the user's observations. Respond ONLY with a valid JSON object.
45
  User Observations: "{user_observations if user_observations else 'None'}"
46
- Follow these steps:
47
- 1. Identify the primary object. Is it an electronic device or a white good?
48
- 2. If YES, respond with a JSON object with keys: "device_type", "condition" (choose from "unusable", "poor", "functional", "good", "excellent"), and "reason" (a brief explanation).
49
- 3. If NO, respond with a JSON object with only ONE key: "device_type" starting with "Invalid: " (e.g., "Invalid: Water Bottle").
50
  """
51
-
52
- model_name = "gemini-2.5-flash"
53
  config = types.GenerateContentConfig(temperature=0.2, response_mime_type="application/json")
54
  contents = [uploaded_file, prompt]
55
-
56
- response = client.models.generate_content(model=f"models/{model_name}", contents=contents, config=config)
57
  parsed_json = json.loads(response.text)
58
-
59
  device_type = parsed_json.get("device_type", "N/A")
60
  if "Invalid:" in device_type:
61
- condition = "N/A"
62
- reason = "Object is not a valid electronic device or white good."
63
  else:
64
- condition = parsed_json.get("condition", "N/A")
65
- reason = parsed_json.get("reason", "N/A")
66
-
67
  print("--- Device Analysis Complete ---")
68
-
69
  except Exception as e:
70
  print(f"ERROR during Gemini processing: {e}")
71
  device_type, condition, reason = f"Error in Gemini processing: {e}", "", ""
72
  finally:
73
  if uploaded_file:
74
- client.files.delete(name=uploaded_file.name)
75
 
76
- # --- YIELD 1: Update UI with Gemini results ---
77
- # The DINO galleries are still empty (None) at this point.
78
- yield device_type, condition, reason, None, None
79
 
80
- # --- Stage 2: DINO Analysis (Slow) ---
81
  print("--- Starting DINO Analysis ---")
82
  try:
83
- dino_results = process_video_with_dino(video_file_path)
84
- overlay_images = [res[0] for res in dino_results]
85
- attention_maps = [res[1] for res in dino_results]
86
  print("--- DINO Analysis Complete ---")
87
  except Exception as e:
88
  print(f"ERROR during DINO processing: {e}")
89
- # If DINO fails, we still want to keep the Gemini results.
90
- # We can update one of the text fields to show the DINO error.
91
  reason += f" | DINO Error: {e}"
92
- overlay_images, attention_maps = None, None
93
 
94
- # --- YIELD 2: Final update with all results ---
95
- # This updates the galleries with the DINO images.
96
- yield device_type, condition, reason, overlay_images, attention_maps
97
 
98
- # --- Gradio Interface ---
99
  theme = gr.themes.Soft(
100
  primary_hue="green", secondary_hue="emerald"
101
  ).set(
@@ -111,10 +97,7 @@ with gr.Blocks(theme=theme) as demo:
111
  with gr.Row():
112
  with gr.Column(scale=1):
113
  video_input = gr.Video(label="Upload or Record Video", sources=["upload", "webcam"], format="mp4")
114
- observations_input = gr.Textbox(
115
- label="Optional: User Observations",
116
- placeholder="e.g., Device overheats, screen flickers..."
117
- )
118
  submit_button = gr.Button("Run Full Analysis", variant="primary")
119
 
120
  with gr.Column(scale=2):
@@ -126,26 +109,19 @@ with gr.Blocks(theme=theme) as demo:
126
 
127
  gr.Markdown("---")
128
 
129
- gr.Markdown("## DINO: Visual Feature Analysis")
130
- with gr.Row():
131
- with gr.Column():
132
- gr.Markdown("### Overlayed Heatmaps on Key Frames")
133
- overlay_gallery = gr.Gallery(label="Overlayed Heatmaps", elem_id="gallery", columns=5)
134
- with gr.Column():
135
- gr.Markdown("### Self-Attention Maps")
136
- attention_gallery = gr.Gallery(label="Self-Attention Maps", elem_id="gallery", columns=5)
137
 
138
- # The .click() event now points to a generator function.
139
- # Gradio will automatically handle the multiple `yield` statements.
140
  submit_button.click(
141
  fn=full_analysis,
142
  inputs=[video_input, observations_input],
 
143
  outputs=[
144
  device_type_output,
145
  condition_output,
146
  reason_output,
147
- overlay_gallery,
148
- attention_gallery
149
  ],
150
  show_progress='full'
151
  )
 
7
  from google import genai
8
  from google.genai import types
9
 
10
+ # Import the optimized DINO functions
11
+ from dino_processor import load_dino_model, process_video_with_dino
12
 
13
+ # --- Configuration and Initialization ---
14
  load_dotenv()
15
  try:
16
+ GEMINI_CLIENT = genai.Client(api_key=os.environ["GEMINI_API_KEY"])
17
  except KeyError:
18
  raise gr.Error("FATAL: GEMINI_API_KEY not found. Please set it in your Hugging Face Space secrets.")
19
 
20
+ DINO_MODEL, DINO_DEVICE = load_dino_model()
21
+
22
  # --- Main Gradio Generator Function ---
23
  def full_analysis(video_file_path, user_observations):
24
  if not video_file_path:
25
+ yield "Please upload a video first.", "", "", None
 
26
  return
27
 
28
+ # Stage 1: Gemini Analysis
29
  print("--- Starting Device Analysis ---")
30
  device_type, condition, reason = "Processing...", "Processing...", "Processing..."
31
+ yield device_type, condition, reason, None
 
 
32
 
33
  uploaded_file = None
34
  try:
35
+ uploaded_file = GEMINI_CLIENT.files.upload(file=video_file_path)
36
  while uploaded_file.state.name == "PROCESSING":
37
  time.sleep(5)
38
+ uploaded_file = GEMINI_CLIENT.files.get(name=uploaded_file.name)
39
  if uploaded_file.state.name != "ACTIVE":
40
  raise Exception(f"File processing failed for Gemini. State: {uploaded_file.state.name}")
41
 
42
  prompt = f"""
43
+ Analyze the provided video and user observations. Respond ONLY with a valid JSON object.
44
  User Observations: "{user_observations if user_observations else 'None'}"
45
+ Logic:
46
+ 1. Is the object an electronic device or white good?
47
+ 2. If YES: respond with JSON keys "device_type", "condition" (from "unusable", "poor", "functional", "good", "excellent"), and "reason".
48
+ 3. If NO: respond with JSON key "device_type" starting with "Invalid: ".
49
  """
50
+ model_name = "gemini-1.5-flash-latest" # Using a reliable public model
 
51
  config = types.GenerateContentConfig(temperature=0.2, response_mime_type="application/json")
52
  contents = [uploaded_file, prompt]
53
+ response = GEMINI_CLIENT.models.generate_content(model=f"models/{model_name}", contents=contents, config=config)
 
54
  parsed_json = json.loads(response.text)
 
55
  device_type = parsed_json.get("device_type", "N/A")
56
  if "Invalid:" in device_type:
57
+ condition, reason = "N/A", "Object is not a valid device."
 
58
  else:
59
+ condition, reason = parsed_json.get("condition", "N/A"), parsed_json.get("reason", "N/A")
 
 
60
  print("--- Device Analysis Complete ---")
 
61
  except Exception as e:
62
  print(f"ERROR during Gemini processing: {e}")
63
  device_type, condition, reason = f"Error in Gemini processing: {e}", "", ""
64
  finally:
65
  if uploaded_file:
66
+ GEMINI_CLIENT.files.delete(name=uploaded_file.name)
67
 
68
+ yield device_type, condition, reason, None
 
 
69
 
70
+ # Stage 2: DINO Analysis
71
  print("--- Starting DINO Analysis ---")
72
  try:
73
+ # OPTIMIZATION: This now returns a simple list of overlay image paths
74
+ overlay_images = process_video_with_dino(video_file_path, DINO_MODEL, DINO_DEVICE)
 
75
  print("--- DINO Analysis Complete ---")
76
  except Exception as e:
77
  print(f"ERROR during DINO processing: {e}")
 
 
78
  reason += f" | DINO Error: {e}"
79
+ overlay_images = None
80
 
81
+ # OPTIMIZATION: Final yield with only 4 items
82
+ yield device_type, condition, reason, overlay_images
 
83
 
84
+ # --- Gradio Interface (Simplified) ---
85
  theme = gr.themes.Soft(
86
  primary_hue="green", secondary_hue="emerald"
87
  ).set(
 
97
  with gr.Row():
98
  with gr.Column(scale=1):
99
  video_input = gr.Video(label="Upload or Record Video", sources=["upload", "webcam"], format="mp4")
100
+ observations_input = gr.Textbox(label="Optional: User Observations", placeholder="e.g., Device overheats...")
 
 
 
101
  submit_button = gr.Button("Run Full Analysis", variant="primary")
102
 
103
  with gr.Column(scale=2):
 
109
 
110
  gr.Markdown("---")
111
 
112
+ # OPTIMIZATION: Simplified DINO output section
113
+ gr.Markdown("## Overlayed Heatmaps on Key Frames")
114
+ overlay_gallery = gr.Gallery(label="Overlayed Heatmaps", elem_id="gallery", columns=3)
 
 
 
 
 
115
 
 
 
116
  submit_button.click(
117
  fn=full_analysis,
118
  inputs=[video_input, observations_input],
119
+ # OPTIMIZATION: Updated outputs list to have only 4 items
120
  outputs=[
121
  device_type_output,
122
  condition_output,
123
  reason_output,
124
+ overlay_gallery
 
125
  ],
126
  show_progress='full'
127
  )