Spaces:
Runtime error
Runtime error
CARLOS VITOR BOTTI CALVI
commited on
Commit
·
c7fa383
1
Parent(s):
682074b
CaneVision first
Browse files- .gitattributes +1 -0
- README.md +5 -7
- app.py +119 -0
- left_beep.wav +3 -0
- requeriments.txt +5 -0
- right_beep.wav +3 -0
- yolov8n.pt +3 -0
.gitattributes
CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
36 |
+
*.wav filter=lfs diff=lfs merge=lfs -text
|
README.md
CHANGED
@@ -1,14 +1,12 @@
|
|
1 |
---
|
2 |
-
title: CaneVision
|
3 |
-
emoji:
|
4 |
colorFrom: blue
|
5 |
-
colorTo:
|
6 |
sdk: gradio
|
7 |
-
sdk_version:
|
8 |
app_file: app.py
|
9 |
pinned: false
|
10 |
-
license: apache-2.0
|
11 |
-
short_description: Cane
|
12 |
---
|
13 |
|
14 |
-
|
|
|
1 |
---
|
2 |
+
title: CaneVision Application
|
3 |
+
emoji: 🦷
|
4 |
colorFrom: blue
|
5 |
+
colorTo: indigo
|
6 |
sdk: gradio
|
7 |
+
sdk_version: '4.19.2'
|
8 |
app_file: app.py
|
9 |
pinned: false
|
|
|
|
|
10 |
---
|
11 |
|
12 |
+
# CaneVision Application
|
app.py
ADDED
@@ -0,0 +1,119 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from datetime import datetime, timedelta
|
2 |
+
|
3 |
+
import cv2
|
4 |
+
import gradio as gr
|
5 |
+
import numpy as np
|
6 |
+
import simpleaudio as sa
|
7 |
+
from ultralytics import YOLO
|
8 |
+
|
9 |
+
# Load pre-trained YOLOv8 model (replace with custom trained model)
|
10 |
+
model = YOLO('yolov8n.pt')
|
11 |
+
obstacle_classes = ['person', 'car', 'traffic light', 'stop sign'] # Customize with your classes
|
12 |
+
|
13 |
+
# Audio alerts
|
14 |
+
left_alert = sa.WaveObject.from_wave_file("left_beep.wav")
|
15 |
+
right_alert = sa.WaveObject.from_wave_file("right_beep.wav")
|
16 |
+
|
17 |
+
class ObstacleDetector:
|
18 |
+
def __init__(self):
|
19 |
+
self.last_alert_time = datetime.now()
|
20 |
+
self.alert_cooldown = 2 # seconds
|
21 |
+
self.recent_obstacles = []
|
22 |
+
|
23 |
+
def detect_obstacles(self, frame):
|
24 |
+
results = model(frame)
|
25 |
+
detected_obstacles = []
|
26 |
+
|
27 |
+
for box in results[0].boxes:
|
28 |
+
class_id = int(box.cls)
|
29 |
+
if results[0].names[class_id] in obstacle_classes:
|
30 |
+
x_center = (box.xyxy[0][0] + box.xyxy[0][2]) / 2
|
31 |
+
position = "left" if x_center < frame.shape[1]/2 else "right"
|
32 |
+
detected_obstacles.append({
|
33 |
+
"class": results[0].names[class_id],
|
34 |
+
"position": position,
|
35 |
+
"confidence": float(box.conf)
|
36 |
+
})
|
37 |
+
|
38 |
+
return detected_obstacles, results[0].plot()
|
39 |
+
|
40 |
+
def generate_audio_feedback(self, obstacles):
|
41 |
+
if datetime.now() - self.last_alert_time < timedelta(seconds=self.alert_cooldown):
|
42 |
+
return
|
43 |
+
|
44 |
+
for obstacle in obstacles:
|
45 |
+
if obstacle['position'] == 'left':
|
46 |
+
left_alert.play()
|
47 |
+
self.last_alert_time = datetime.now()
|
48 |
+
break
|
49 |
+
elif obstacle['position'] == 'right':
|
50 |
+
right_alert.play()
|
51 |
+
self.last_alert_time = datetime.now()
|
52 |
+
break
|
53 |
+
|
54 |
+
detector = ObstacleDetector()
|
55 |
+
|
56 |
+
def process_frame(frame, enable_audio):
|
57 |
+
if frame is None:
|
58 |
+
return None, [], "No vibration"
|
59 |
+
|
60 |
+
# Process the frame
|
61 |
+
frame_np = np.array(frame)
|
62 |
+
# Convert to BGR for YOLOv8
|
63 |
+
frame_bgr = cv2.cvtColor(frame_np, cv2.COLOR_RGB2BGR)
|
64 |
+
|
65 |
+
obstacles, annotated_frame = detector.detect_obstacles(frame_bgr)
|
66 |
+
|
67 |
+
if enable_audio and obstacles:
|
68 |
+
detector.generate_audio_feedback(obstacles)
|
69 |
+
|
70 |
+
# Simulate vibration feedback
|
71 |
+
vibration = "■" * min(len(obstacles), 5) if obstacles else "No vibration"
|
72 |
+
|
73 |
+
# Convert back to RGB for display
|
74 |
+
output_frame = cv2.cvtColor(annotated_frame, cv2.COLOR_BGR2RGB)
|
75 |
+
|
76 |
+
return output_frame, obstacles, vibration
|
77 |
+
|
78 |
+
def create_demo():
|
79 |
+
with gr.Blocks(title="CaneVision Demo") as demo:
|
80 |
+
gr.Markdown("# 🦯 CaneVision - Intelligent Navigation Assistant")
|
81 |
+
|
82 |
+
with gr.Row():
|
83 |
+
with gr.Column():
|
84 |
+
# Use gr.Image with webcam source instead of gr.Video
|
85 |
+
camera_input = gr.Image(label="Live Camera Input", sources=["webcam"], type="numpy")
|
86 |
+
audio_toggle = gr.Checkbox(label="Enable Audio Alerts", value=True)
|
87 |
+
process_btn = gr.Button("Process Frame")
|
88 |
+
|
89 |
+
with gr.Column():
|
90 |
+
output_image = gr.Image(label="Detected Obstacles")
|
91 |
+
vibration_output = gr.Textbox(label="Vibration Feedback Simulation")
|
92 |
+
obstacles_output = gr.JSON(label="Detected Objects")
|
93 |
+
|
94 |
+
# Process webcam frame when button is clicked
|
95 |
+
process_btn.click(
|
96 |
+
process_frame,
|
97 |
+
inputs=[camera_input, audio_toggle],
|
98 |
+
outputs=[output_image, obstacles_output, vibration_output]
|
99 |
+
)
|
100 |
+
|
101 |
+
# Add a live processing option with a fixed interval (if needed)
|
102 |
+
# Not implemented here as it's better to use button for explicit processing
|
103 |
+
|
104 |
+
gr.Markdown("## How it works:")
|
105 |
+
gr.Markdown("""
|
106 |
+
1. Capture an image from your webcam
|
107 |
+
2. Click 'Process Frame' to analyze
|
108 |
+
3. The AI detects obstacles (people, vehicles, traffic signs)
|
109 |
+
4. System provides:
|
110 |
+
- Spatial audio alerts (left/right)
|
111 |
+
- Simulated vibration feedback
|
112 |
+
- Visual detection overlay
|
113 |
+
""")
|
114 |
+
|
115 |
+
return demo
|
116 |
+
|
117 |
+
if __name__ == "__main__":
|
118 |
+
demo = create_demo()
|
119 |
+
demo.launch(share=True, debug=True)
|
left_beep.wav
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:3a9d799ac9018def1a0bee7071423c3df3f01e4477da720b66a59826738d19a5
|
3 |
+
size 176478
|
requeriments.txt
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
gradio
|
2 |
+
opencv-python
|
3 |
+
numpy
|
4 |
+
simpleaudio
|
5 |
+
ultralytics
|
right_beep.wav
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:bc3e15dcdc78d008c36dd5857ae9566e427ee968e7f2566eb6e1a813adba38a8
|
3 |
+
size 176478
|
yolov8n.pt
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:31e20dde3def09e2cf938c7be6fe23d9150bbbe503982af13345706515f2ef95
|
3 |
+
size 6534387
|