Spaces:
Runtime error
Runtime error
fouadmahmoud283-ai commited on
Commit ยท
945aa5a
1
Parent(s): 7f27589
fixing camera n1235
Browse files- requirements.txt +1 -0
- src/streamlit_app.py +62 -77
requirements.txt
CHANGED
|
@@ -1,6 +1,7 @@
|
|
| 1 |
altair
|
| 2 |
pandas
|
| 3 |
streamlit
|
|
|
|
| 4 |
torch
|
| 5 |
torchvision
|
| 6 |
opencv-python-headless
|
|
|
|
| 1 |
altair
|
| 2 |
pandas
|
| 3 |
streamlit
|
| 4 |
+
streamlit-webrtc
|
| 5 |
torch
|
| 6 |
torchvision
|
| 7 |
opencv-python-headless
|
src/streamlit_app.py
CHANGED
|
@@ -14,6 +14,9 @@ import os
|
|
| 14 |
import logging
|
| 15 |
import warnings
|
| 16 |
import requests
|
|
|
|
|
|
|
|
|
|
| 17 |
|
| 18 |
# Suppress WebRTC/asyncio warnings and errors
|
| 19 |
logging.getLogger('aioice').setLevel(logging.CRITICAL)
|
|
@@ -320,6 +323,32 @@ def create_confidence_chart(detections):
|
|
| 320 |
|
| 321 |
return fig
|
| 322 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 323 |
# Main app
|
| 324 |
def main():
|
| 325 |
# Header
|
|
@@ -493,89 +522,45 @@ def main():
|
|
| 493 |
|
| 494 |
with tab2:
|
| 495 |
st.markdown("### ๐น Realtime Camera Detection")
|
| 496 |
-
st.caption("
|
| 497 |
-
|
| 498 |
-
camera_image = st.camera_input(
|
| 499 |
-
"Capture an image",
|
| 500 |
-
key="camera_input"
|
| 501 |
-
)
|
| 502 |
-
|
| 503 |
-
if camera_image is not None:
|
| 504 |
-
try:
|
| 505 |
-
image = Image.open(camera_image)
|
| 506 |
-
except Exception as e:
|
| 507 |
-
st.error(f"Could not read camera image: {e}")
|
| 508 |
-
image = None
|
| 509 |
-
|
| 510 |
-
if image is not None:
|
| 511 |
-
col1, col2 = st.columns(2)
|
| 512 |
-
|
| 513 |
-
with col1:
|
| 514 |
-
st.markdown("#### ๐ธ Captured Image")
|
| 515 |
-
st.image(image, width=500)
|
| 516 |
-
|
| 517 |
-
# Load model
|
| 518 |
-
if st.session_state.model is None:
|
| 519 |
-
with st.spinner("๐ค Loading AI model..."):
|
| 520 |
-
st.session_state.model = load_model(conf_threshold)
|
| 521 |
-
|
| 522 |
-
if st.session_state.model is not None:
|
| 523 |
-
# Process image
|
| 524 |
-
with st.spinner("๐ Analyzing image for obstacles..."):
|
| 525 |
-
start_time = time.time()
|
| 526 |
-
rendered_img, detections, results = process_image(image, st.session_state.model, conf_threshold)
|
| 527 |
-
processing_time = time.time() - start_time
|
| 528 |
-
|
| 529 |
-
with col2:
|
| 530 |
-
st.markdown("#### ๐ฏ Detection Results")
|
| 531 |
-
if rendered_img is not None:
|
| 532 |
-
st.image(rendered_img, width=500)
|
| 533 |
-
|
| 534 |
-
# Generate navigation advice
|
| 535 |
-
advice, safety_level = get_navigation_advice(detections, image.width)
|
| 536 |
|
| 537 |
-
|
| 538 |
-
|
| 539 |
-
|
| 540 |
-
st.markdown(f'<div class="safety-alert"><strong>{safety_level}</strong></div>', unsafe_allow_html=True)
|
| 541 |
-
elif "CAUTION" in safety_level:
|
| 542 |
-
st.markdown(f'<div style="background: #fff3cd; color: #856404; padding: 1rem; border-radius: 8px; border-left: 4px solid #ffc107;"><strong>{safety_level}</strong></div>', unsafe_allow_html=True)
|
| 543 |
-
else:
|
| 544 |
-
st.markdown(f'<div class="success-alert"><strong>{safety_level}</strong></div>', unsafe_allow_html=True)
|
| 545 |
-
|
| 546 |
-
# Display navigation advice
|
| 547 |
-
st.markdown("### ๐งญ Navigation Advice")
|
| 548 |
-
for advice_text in advice:
|
| 549 |
-
st.markdown(f'<div class="detection-box">{advice_text}</div>', unsafe_allow_html=True)
|
| 550 |
-
|
| 551 |
-
# Performance metrics
|
| 552 |
-
st.markdown("### โก Performance Metrics")
|
| 553 |
-
perf_col1, perf_col2, perf_col3, perf_col4 = st.columns(4)
|
| 554 |
-
|
| 555 |
-
with perf_col1:
|
| 556 |
-
st.metric("โฑ๏ธ Processing Time", f"{processing_time:.2f}s")
|
| 557 |
-
|
| 558 |
-
with perf_col2:
|
| 559 |
-
fps = 1 / processing_time if processing_time > 0 else 0
|
| 560 |
-
st.metric("๐ฌ Estimated FPS", f"{fps:.1f}")
|
| 561 |
|
| 562 |
-
|
| 563 |
-
|
| 564 |
-
|
|
|
|
|
|
|
|
|
|
| 565 |
|
| 566 |
-
|
| 567 |
-
|
| 568 |
-
|
|
|
|
| 569 |
|
| 570 |
-
|
| 571 |
-
|
| 572 |
-
|
| 573 |
|
| 574 |
-
|
| 575 |
-
|
| 576 |
-
|
|
|
|
|
|
|
|
|
|
| 577 |
|
| 578 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 579 |
|
| 580 |
with tab3:
|
| 581 |
st.markdown("### ๐ Detection Analytics")
|
|
|
|
| 14 |
import logging
|
| 15 |
import warnings
|
| 16 |
import requests
|
| 17 |
+
import threading
|
| 18 |
+
import av
|
| 19 |
+
from streamlit_webrtc import webrtc_streamer, VideoProcessorBase
|
| 20 |
|
| 21 |
# Suppress WebRTC/asyncio warnings and errors
|
| 22 |
logging.getLogger('aioice').setLevel(logging.CRITICAL)
|
|
|
|
| 323 |
|
| 324 |
return fig
|
| 325 |
|
| 326 |
+
class RealtimeVideoProcessor(VideoProcessorBase):
|
| 327 |
+
def __init__(self, model, conf_threshold):
|
| 328 |
+
self.model = model
|
| 329 |
+
self.conf_threshold = conf_threshold
|
| 330 |
+
self.last_detections = None
|
| 331 |
+
self.lock = threading.Lock()
|
| 332 |
+
|
| 333 |
+
def recv(self, frame):
|
| 334 |
+
img_bgr = frame.to_ndarray(format="bgr24")
|
| 335 |
+
img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)
|
| 336 |
+
|
| 337 |
+
if self.model is None:
|
| 338 |
+
return frame
|
| 339 |
+
|
| 340 |
+
self.model.conf = self.conf_threshold
|
| 341 |
+
results = self.model(img_rgb)
|
| 342 |
+
|
| 343 |
+
detections = results.pandas().xyxy[0]
|
| 344 |
+
relevant_detections = detections[detections['name'].isin(WHEELCHAIR_CLASSES.values())]
|
| 345 |
+
|
| 346 |
+
with self.lock:
|
| 347 |
+
self.last_detections = relevant_detections
|
| 348 |
+
|
| 349 |
+
rendered_img = results.render()[0]
|
| 350 |
+
return av.VideoFrame.from_ndarray(rendered_img, format="bgr24")
|
| 351 |
+
|
| 352 |
# Main app
|
| 353 |
def main():
|
| 354 |
# Header
|
|
|
|
| 522 |
|
| 523 |
with tab2:
|
| 524 |
st.markdown("### ๐น Realtime Camera Detection")
|
| 525 |
+
st.caption("Start the camera to run live detection on each frame.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 526 |
|
| 527 |
+
if st.session_state.model is None:
|
| 528 |
+
with st.spinner("๐ค Loading AI model..."):
|
| 529 |
+
st.session_state.model = load_model(conf_threshold)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 530 |
|
| 531 |
+
webrtc_ctx = webrtc_streamer(
|
| 532 |
+
key="realtime_camera",
|
| 533 |
+
video_processor_factory=lambda: RealtimeVideoProcessor(st.session_state.model, conf_threshold),
|
| 534 |
+
media_stream_constraints={"video": True, "audio": False},
|
| 535 |
+
async_processing=True
|
| 536 |
+
)
|
| 537 |
|
| 538 |
+
realtime_detections = None
|
| 539 |
+
if webrtc_ctx.video_processor:
|
| 540 |
+
with webrtc_ctx.video_processor.lock:
|
| 541 |
+
realtime_detections = webrtc_ctx.video_processor.last_detections
|
| 542 |
|
| 543 |
+
if realtime_detections is not None:
|
| 544 |
+
st.markdown("### ๐ก๏ธ Safety Status")
|
| 545 |
+
advice, safety_level = get_navigation_advice(realtime_detections, image_width=640)
|
| 546 |
|
| 547 |
+
if "CRITICAL" in safety_level:
|
| 548 |
+
st.markdown(f'<div class="safety-alert"><strong>{safety_level}</strong></div>', unsafe_allow_html=True)
|
| 549 |
+
elif "CAUTION" in safety_level:
|
| 550 |
+
st.markdown(f'<div style="background: #fff3cd; color: #856404; padding: 1rem; border-radius: 8px; border-left: 4px solid #ffc107;"><strong>{safety_level}</strong></div>', unsafe_allow_html=True)
|
| 551 |
+
else:
|
| 552 |
+
st.markdown(f'<div class="success-alert"><strong>{safety_level}</strong></div>', unsafe_allow_html=True)
|
| 553 |
|
| 554 |
+
st.markdown("### ๐งญ Navigation Advice")
|
| 555 |
+
for advice_text in advice:
|
| 556 |
+
st.markdown(f'<div class="detection-box">{advice_text}</div>', unsafe_allow_html=True)
|
| 557 |
+
|
| 558 |
+
if len(realtime_detections) > 0:
|
| 559 |
+
st.markdown("### ๐ Latest Detections")
|
| 560 |
+
display_df = realtime_detections[['name', 'confidence', 'xmin', 'ymin', 'xmax', 'ymax']].copy()
|
| 561 |
+
display_df['confidence'] = display_df['confidence'].apply(lambda x: f"{x:.1%}")
|
| 562 |
+
display_df.columns = ['Object', 'Confidence', 'X Min', 'Y Min', 'X Max', 'Y Max']
|
| 563 |
+
st.dataframe(display_df, use_container_width=True)
|
| 564 |
|
| 565 |
with tab3:
|
| 566 |
st.markdown("### ๐ Detection Analytics")
|