manikandan18ramalingam commited on
Commit
a216c73
·
verified ·
1 Parent(s): b5f6124

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +97 -92
app.py CHANGED
@@ -10,10 +10,7 @@ import uuid
10
  from object_detection import detectObjects, detectVideo
11
  from object_detection_count import detectObjectsAndCount
12
  from pose_analysis import process_gif
13
-
14
- # Traffic sign detection (image + video)
15
- from traffic_sign_detection import detectTrafficObjects, detectTrafficVideo
16
-
17
 
18
  # -----------------------------
19
  # Constants
@@ -33,23 +30,6 @@ TASK_TO_ASSET_SUBDIR = {
33
  IMAGE_EXTS = {".jpg", ".jpeg", ".png"}
34
  VIDEO_EXTS = {".mp4", ".mov", ".avi", ".gif"}
35
 
36
- # Per-tab allowed types for uploader + validation
37
- TAB_ALLOWED_EXTS = {
38
- "Object Detection": IMAGE_EXTS | VIDEO_EXTS, # image + video
39
- "Traffic Sign Detection": IMAGE_EXTS | VIDEO_EXTS, # image + video
40
- "Pose Analysis": VIDEO_EXTS, # video only
41
- "Object Counting": IMAGE_EXTS, # image only
42
- }
43
-
44
- # Streamlit uploader "type" expects extensions WITHOUT dots
45
- TAB_UPLOADER_TYPES = {
46
- "Object Detection": ["jpg", "jpeg", "png", "gif", "mp4", "avi", "mov"],
47
- "Traffic Sign Detection": ["jpg", "jpeg", "png", "gif", "mp4", "avi", "mov"],
48
- "Pose Analysis": ["gif", "mp4", "avi", "mov"],
49
- "Object Counting": ["jpg", "jpeg", "png"],
50
- }
51
-
52
-
53
  # -----------------------------
54
  # Helpers
55
  # -----------------------------
@@ -61,19 +41,15 @@ def check_file_size(file):
61
 
62
 
63
  def save_uploaded_file_to_temp(uploaded_file) -> str:
64
- """
65
- Save upload to a temp folder to avoid cluttering project root
66
- and reduce filename collisions.
67
- """
68
  safe_name = uploaded_file.name.replace("/", "_").replace("\\", "_")
69
- temp_dir = Path(tempfile.gettempdir()) / "streamlit_uploads"
70
- temp_dir.mkdir(parents=True, exist_ok=True)
71
 
72
- out_path = temp_dir / f"{uuid.uuid4().hex}_{safe_name}"
73
- with open(out_path, "wb") as f:
74
  f.write(uploaded_file.getbuffer())
75
 
76
- return str(out_path)
 
77
 
78
 
79
  def list_demo_files(task_name: str, limit: int = 6):
@@ -111,10 +87,14 @@ def is_h264(path: str) -> bool:
111
  out = subprocess.check_output(
112
  [
113
  "ffprobe",
114
- "-v", "error",
115
- "-select_streams", "v:0",
116
- "-show_entries", "stream=codec_name",
117
- "-of", "default=nk=1:nw=1",
 
 
 
 
118
  path,
119
  ],
120
  text=True,
@@ -131,23 +111,30 @@ def to_h264_mp4(input_path: str) -> str:
131
  - Uses a unique temp output so we don't overwrite assets or collide across reruns.
132
  """
133
  if shutil.which("ffmpeg") is None:
134
- st.warning("ffmpeg not found. Video may not play if not H.264.")
135
  return input_path
136
 
137
  out_path = str(Path(tempfile.gettempdir()) / f"{uuid.uuid4().hex}.mp4")
138
  cmd = [
139
  "ffmpeg",
140
  "-y",
141
- "-i", input_path,
142
- "-c:v", "libx264",
143
- "-pix_fmt", "yuv420p",
144
- "-movflags", "+faststart",
145
- "-c:a", "aac",
146
- "-b:a", "128k",
 
 
 
 
 
 
147
  out_path,
148
  ]
149
  try:
150
  subprocess.run(cmd, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
 
151
  if not Path(out_path).exists() or Path(out_path).stat().st_size < 1024:
152
  st.warning("Video conversion produced an empty file; showing original.")
153
  return input_path
@@ -162,6 +149,8 @@ def render_media(path: Path):
162
  if ext in IMAGE_EXTS:
163
  st.image(str(path), caption=path.name, use_container_width=True)
164
  elif ext in VIDEO_EXTS:
 
 
165
  playable = str(path)
166
  if not is_h264(playable):
167
  playable = to_h264_mp4(playable)
@@ -171,7 +160,10 @@ def render_media(path: Path):
171
 
172
  def render_showcase(tasks, per_task_limit=6):
173
  st.subheader("Example outputs (what to expect)")
174
- st.write("These are pre-generated results so you can see the expected output before uploading.")
 
 
 
175
 
176
  for task in tasks:
177
  st.markdown(f"### {task}")
@@ -179,8 +171,8 @@ def render_showcase(tasks, per_task_limit=6):
179
 
180
  if not demo_files:
181
  st.info(
182
- f"No demo files found for **{task}**. Add files under: "
183
- f"`{ASSETS_DIR / TASK_TO_ASSET_SUBDIR[task]}`"
184
  )
185
  continue
186
 
@@ -192,60 +184,55 @@ def render_showcase(tasks, per_task_limit=6):
192
  st.divider()
193
 
194
 
195
- def validate_file_for_tab(file_path: str, tab_name: str) -> bool:
196
- ext = Path(file_path).suffix.lower()
197
- allowed = TAB_ALLOWED_EXTS.get(tab_name, set())
198
- return ext in allowed
199
-
200
-
201
  def process_file(file_path, tab_name, confidence_score, progress_placeholder, class_type):
202
- """
203
- Enforces per-tab constraints:
204
- - Object Detection: image + video
205
- - Traffic Sign Detection: image + video
206
- - Pose Analysis: video only
207
- - Object Counting: image only
208
- """
209
- if not validate_file_for_tab(file_path, tab_name):
210
- allowed = ", ".join(sorted(TAB_ALLOWED_EXTS.get(tab_name, [])))
211
- st.error(f"Unsupported file for **{tab_name}**. Allowed: {allowed}")
212
- return None, None
213
-
214
  progress_placeholder.info(f"Processing... Please wait. (Confidence Score: {confidence_score})")
215
- time.sleep(0.5)
216
-
217
- ext = Path(file_path).suffix.lower()
218
 
219
  if tab_name == "Object Detection":
220
- progress_placeholder.empty()
221
- if ext in IMAGE_EXTS:
222
  img = detectObjects(file_path, confidence_score)
223
  return img, "image"
224
- else:
 
 
225
  out_video_path = detectVideo(file_path, confidence_score)
226
  return out_video_path, "video"
227
 
 
 
 
 
228
  elif tab_name == "Object Counting":
 
 
 
 
 
 
 
 
 
 
 
229
  progress_placeholder.empty()
230
- # image only
231
- img, count = detectObjectsAndCount(file_path, confidence_score, class_type)
232
- st.info(f"Count for class '{class_type}': {count}")
233
- return img, "image"
234
 
235
  elif tab_name == "Pose Analysis":
236
  progress_placeholder.empty()
237
- # video only
238
  out_video_path = process_gif(file_path, confidence_score)
239
  return out_video_path, "video"
240
 
241
  elif tab_name == "Traffic Sign Detection":
242
- progress_placeholder.empty()
243
- if ext in IMAGE_EXTS:
244
  img = detectTrafficObjects(file_path, confidence_score)
245
  return img, "image"
246
- else:
247
- out_video_path = detectTrafficVideo(file_path, confidence_score)
248
- return out_video_path, "video"
 
249
 
250
  st.error("Unknown tab selection.")
251
  return None, None
@@ -257,23 +244,30 @@ def process_file(file_path, tab_name, confidence_score, progress_placeholder, cl
257
  st.set_page_config(page_title="AI Video/Image Analysis Platform", layout="wide")
258
 
259
  st.title("AI Video/Image Analysis Platform")
260
- st.write("Upload a file and choose a tab for analysis.")
261
 
 
262
  tabs = st.tabs(TABS)
263
 
264
  for i, tab_name in enumerate(TABS):
265
  with tabs[i]:
266
  st.header(tab_name)
267
 
268
- uploader_label = "Upload an Image/Video"
269
- if tab_name == "Pose Analysis":
270
- uploader_label = "Upload a Video (Pose Analysis supports video only)"
 
 
 
 
271
  elif tab_name == "Object Counting":
272
- uploader_label = "Upload an Image (Object Counting supports images only)"
 
 
273
 
274
  uploaded_file = st.file_uploader(
275
- uploader_label,
276
- type=TAB_UPLOADER_TYPES[tab_name],
277
  key=f"uploader_{tab_name}",
278
  )
279
 
@@ -285,14 +279,9 @@ for i, tab_name in enumerate(TABS):
285
 
286
  st.success(f"Uploaded file: {uploaded_file.name} ({file_size:.2f} MB)")
287
 
 
288
  file_path = save_uploaded_file_to_temp(uploaded_file)
289
 
290
- # Validate again (hard guard)
291
- if not validate_file_for_tab(file_path, tab_name):
292
- allowed = ", ".join(sorted(TAB_ALLOWED_EXTS.get(tab_name, [])))
293
- st.error(f"Unsupported file for **{tab_name}**. Allowed: {allowed}")
294
- continue
295
-
296
  confidence_score = st.number_input(
297
  "Adjust Confidence Score",
298
  min_value=0.0,
@@ -312,11 +301,25 @@ for i, tab_name in enumerate(TABS):
312
  key=f"class_type_{tab_name}",
313
  )
314
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
315
  if st.button(f"Process {tab_name}", key=f"process_{tab_name}"):
316
  progress_placeholder = st.empty()
317
  with st.spinner("Processing... Please wait."):
318
  result, result_type = process_file(
319
- file_path,
320
  tab_name,
321
  confidence_score,
322
  progress_placeholder,
@@ -327,9 +330,11 @@ for i, tab_name in enumerate(TABS):
327
  st.success(f"{tab_name} completed successfully!")
328
 
329
  playable = result
 
330
  if not is_h264(playable):
331
  playable = to_h264_mp4(playable)
332
 
 
333
  st_video_file(playable, fmt="video/mp4")
334
 
335
  if result_type == "image" and result is not None:
 
10
  from object_detection import detectObjects, detectVideo
11
  from object_detection_count import detectObjectsAndCount
12
  from pose_analysis import process_gif
13
+ from traffic_sign_detection import detectTrafficObjects
 
 
 
14
 
15
  # -----------------------------
16
  # Constants
 
30
  IMAGE_EXTS = {".jpg", ".jpeg", ".png"}
31
  VIDEO_EXTS = {".mp4", ".mov", ".avi", ".gif"}
32
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  # -----------------------------
34
  # Helpers
35
  # -----------------------------
 
41
 
42
 
43
  def save_uploaded_file_to_temp(uploaded_file) -> str:
44
+ # NOTE: left exactly as you had it (do not change)
 
 
 
45
  safe_name = uploaded_file.name.replace("/", "_").replace("\\", "_")
46
+ save_path = "./"
 
47
 
48
+ with open(safe_name, "wb") as f:
 
49
  f.write(uploaded_file.getbuffer())
50
 
51
+ print("Saved uploaded file to:", safe_name)
52
+ return str(safe_name)
53
 
54
 
55
  def list_demo_files(task_name: str, limit: int = 6):
 
87
  out = subprocess.check_output(
88
  [
89
  "ffprobe",
90
+ "-v",
91
+ "error",
92
+ "-select_streams",
93
+ "v:0",
94
+ "-show_entries",
95
+ "stream=codec_name",
96
+ "-of",
97
+ "default=nk=1:nw=1",
98
  path,
99
  ],
100
  text=True,
 
111
  - Uses a unique temp output so we don't overwrite assets or collide across reruns.
112
  """
113
  if shutil.which("ffmpeg") is None:
114
+ st.warning("ffmpeg not found in this environment. Video may show black screen if not H.264.")
115
  return input_path
116
 
117
  out_path = str(Path(tempfile.gettempdir()) / f"{uuid.uuid4().hex}.mp4")
118
  cmd = [
119
  "ffmpeg",
120
  "-y",
121
+ "-i",
122
+ input_path,
123
+ "-c:v",
124
+ "libx264",
125
+ "-pix_fmt",
126
+ "yuv420p",
127
+ "-movflags",
128
+ "+faststart",
129
+ "-c:a",
130
+ "aac",
131
+ "-b:a",
132
+ "128k",
133
  out_path,
134
  ]
135
  try:
136
  subprocess.run(cmd, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
137
+ # Sanity check: ensure output exists and is not tiny/empty
138
  if not Path(out_path).exists() or Path(out_path).stat().st_size < 1024:
139
  st.warning("Video conversion produced an empty file; showing original.")
140
  return input_path
 
149
  if ext in IMAGE_EXTS:
150
  st.image(str(path), caption=path.name, use_container_width=True)
151
  elif ext in VIDEO_EXTS:
152
+ # IMPORTANT: do NOT try to "convert-and-overwrite" showcase assets.
153
+ # Only convert to a temp H.264 file if needed, then pass BYTES to Streamlit.
154
  playable = str(path)
155
  if not is_h264(playable):
156
  playable = to_h264_mp4(playable)
 
160
 
161
  def render_showcase(tasks, per_task_limit=6):
162
  st.subheader("Example outputs (what to expect)")
163
+ st.write(
164
+ "These are pre-generated results (detected/segmented/pose analyzed/traffic signs) "
165
+ "so you can see the expected output before uploading."
166
+ )
167
 
168
  for task in tasks:
169
  st.markdown(f"### {task}")
 
171
 
172
  if not demo_files:
173
  st.info(
174
+ f"No demo files found for **{task}**. Add images/videos under: "
175
+ f"{ASSETS_DIR / TASK_TO_ASSET_SUBDIR[task]}"
176
  )
177
  continue
178
 
 
184
  st.divider()
185
 
186
 
 
 
 
 
 
 
187
  def process_file(file_path, tab_name, confidence_score, progress_placeholder, class_type):
 
 
 
 
 
 
 
 
 
 
 
 
188
  progress_placeholder.info(f"Processing... Please wait. (Confidence Score: {confidence_score})")
189
+ time.sleep(1)
 
 
190
 
191
  if tab_name == "Object Detection":
192
+ if file_path.lower().endswith((".jpg", ".png", ".jpeg")):
193
+ progress_placeholder.empty()
194
  img = detectObjects(file_path, confidence_score)
195
  return img, "image"
196
+
197
+ elif file_path.lower().endswith((".mp4", ".avi", ".mov", ".gif")):
198
+ progress_placeholder.empty()
199
  out_video_path = detectVideo(file_path, confidence_score)
200
  return out_video_path, "video"
201
 
202
+ progress_placeholder.empty()
203
+ st.error("Unsupported file format! Please upload an image or video.")
204
+ return None, None
205
+
206
  elif tab_name == "Object Counting":
207
+ if file_path.lower().endswith((".jpg", ".png", ".jpeg")):
208
+ progress_placeholder.empty()
209
+ img, count = detectObjectsAndCount(file_path, confidence_score, class_type)
210
+ st.info(f"Count for class '{class_type}': {count}")
211
+ return img, "image"
212
+
213
+ elif file_path.lower().endswith((".mp4", ".avi", ".mov", ".gif")):
214
+ progress_placeholder.empty()
215
+ out_video_path = detectVideo(file_path, confidence_score)
216
+ return out_video_path, "video"
217
+
218
  progress_placeholder.empty()
219
+ st.error("Unsupported file format! Please upload an image or video.")
220
+ return None, None
 
 
221
 
222
  elif tab_name == "Pose Analysis":
223
  progress_placeholder.empty()
 
224
  out_video_path = process_gif(file_path, confidence_score)
225
  return out_video_path, "video"
226
 
227
  elif tab_name == "Traffic Sign Detection":
228
+ if file_path.lower().endswith((".jpg", ".png", ".jpeg")):
229
+ progress_placeholder.empty()
230
  img = detectTrafficObjects(file_path, confidence_score)
231
  return img, "image"
232
+
233
+ progress_placeholder.empty()
234
+ st.error("Unsupported file format! Please upload an image.")
235
+ return None, None
236
 
237
  st.error("Unknown tab selection.")
238
  return None, None
 
244
  st.set_page_config(page_title="AI Video/Image Analysis Platform", layout="wide")
245
 
246
  st.title("AI Video/Image Analysis Platform")
247
+ st.write("Upload an image or video and choose a tab for analysis.")
248
 
249
+ # Tabs for different functionalities
250
  tabs = st.tabs(TABS)
251
 
252
  for i, tab_name in enumerate(TABS):
253
  with tabs[i]:
254
  st.header(tab_name)
255
 
256
+ # -----------------------------
257
+ # MINIMAL CHANGE: per-tab uploader constraints
258
+ # -----------------------------
259
+ if tab_name in ["Object Detection", "Traffic Sign Detection"]:
260
+ allowed_types = ["jpg", "jpeg", "png", "gif", "mp4", "avi", "mov"] # image + video
261
+ elif tab_name == "Pose Analysis":
262
+ allowed_types = ["gif", "mp4", "avi", "mov"] # video only
263
  elif tab_name == "Object Counting":
264
+ allowed_types = ["jpg", "jpeg", "png"] # image only
265
+ else:
266
+ allowed_types = ["jpg", "jpeg", "png", "gif", "mp4", "avi", "mov"]
267
 
268
  uploaded_file = st.file_uploader(
269
+ "Upload an Image/Video",
270
+ type=allowed_types,
271
  key=f"uploader_{tab_name}",
272
  )
273
 
 
279
 
280
  st.success(f"Uploaded file: {uploaded_file.name} ({file_size:.2f} MB)")
281
 
282
+ # Save to temp and use the full path for downstream processing
283
  file_path = save_uploaded_file_to_temp(uploaded_file)
284
 
 
 
 
 
 
 
285
  confidence_score = st.number_input(
286
  "Adjust Confidence Score",
287
  min_value=0.0,
 
301
  key=f"class_type_{tab_name}",
302
  )
303
 
304
+ safe_name = uploaded_file.name.replace("/", "_").replace("\\", "_")
305
+ print("Process file called with", safe_name)
306
+
307
+ # -----------------------------
308
+ # MINIMAL CHANGE: hard guard (enforce per-tab constraints)
309
+ # -----------------------------
310
+ ext = os.path.splitext(safe_name)[1].lower()
311
+ if tab_name == "Pose Analysis" and ext in (".jpg", ".jpeg", ".png"):
312
+ st.error("Pose Analysis supports video only. Please upload mp4/mov/avi/gif.")
313
+ continue
314
+ if tab_name == "Object Counting" and ext in (".mp4", ".mov", ".avi", ".gif"):
315
+ st.error("Object Counting supports images only. Please upload jpg/jpeg/png.")
316
+ continue
317
+
318
  if st.button(f"Process {tab_name}", key=f"process_{tab_name}"):
319
  progress_placeholder = st.empty()
320
  with st.spinner("Processing... Please wait."):
321
  result, result_type = process_file(
322
+ safe_name,
323
  tab_name,
324
  confidence_score,
325
  progress_placeholder,
 
330
  st.success(f"{tab_name} completed successfully!")
331
 
332
  playable = result
333
+ # Convert ONLY if not already H.264 (or if ffprobe missing, this will attempt conversion)
334
  if not is_h264(playable):
335
  playable = to_h264_mp4(playable)
336
 
337
+ # Use bytes for reliability on Spaces
338
  st_video_file(playable, fmt="video/mp4")
339
 
340
  if result_type == "image" and result is not None: