Update app.py
Browse files
app.py
CHANGED
@@ -7,7 +7,7 @@ import numpy as np
|
|
7 |
import streamlit as st
|
8 |
from streamlit_webrtc import WebRtcMode, webrtc_streamer
|
9 |
from sample_utils.turn import get_ice_servers
|
10 |
-
|
11 |
import os
|
12 |
import time
|
13 |
|
@@ -20,8 +20,10 @@ st.title("Interactive Virtual Keyboard")
|
|
20 |
st.subheader('''Turn on the webcam and use hand gestures to interact with the virtual keyboard.
|
21 |
Use 'a' and 'd' from the keyboard to change the background.''')
|
22 |
|
23 |
-
# Initialize
|
24 |
-
|
|
|
|
|
25 |
|
26 |
# Define virtual keyboard layout
|
27 |
keys = [["Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P"],
|
@@ -35,7 +37,7 @@ class Detection(NamedTuple):
|
|
35 |
|
36 |
result_queue: "queue.Queue[List[Detection]]" = queue.Queue()
|
37 |
|
38 |
-
#
|
39 |
listImg = os.listdir('model/street') if os.path.exists('model/street') else []
|
40 |
if not listImg:
|
41 |
st.error("Error: 'street' directory is missing or empty. Please add background images.")
|
@@ -54,21 +56,34 @@ if "output_text" not in st.session_state:
|
|
54 |
def video_frame_callback(frame: av.VideoFrame) -> av.VideoFrame:
|
55 |
global indexImg, output_text
|
56 |
|
57 |
-
# Convert the frame to BGR
|
58 |
img = frame.to_ndarray(format="bgr24")
|
|
|
59 |
|
60 |
-
# Process the frame with
|
61 |
-
|
62 |
|
63 |
detections = []
|
64 |
-
if
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
72 |
else:
|
73 |
logger.info("No hands detected.")
|
74 |
|
|
|
7 |
import streamlit as st
|
8 |
from streamlit_webrtc import WebRtcMode, webrtc_streamer
|
9 |
from sample_utils.turn import get_ice_servers
|
10 |
+
import mediapipe as mp
|
11 |
import os
|
12 |
import time
|
13 |
|
|
|
20 |
st.subheader('''Turn on the webcam and use hand gestures to interact with the virtual keyboard.
|
21 |
Use 'a' and 'd' from the keyboard to change the background.''')
|
22 |
|
23 |
+
# Initialize MediaPipe Hand Detector
|
24 |
+
mp_hands = mp.solutions.hands
|
25 |
+
hands = mp_hands.Hands(static_image_mode=False, max_num_hands=2, min_detection_confidence=0.7)
|
26 |
+
mp_drawing = mp.solutions.drawing_utils
|
27 |
|
28 |
# Define virtual keyboard layout
|
29 |
keys = [["Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P"],
|
|
|
37 |
|
38 |
result_queue: "queue.Queue[List[Detection]]" = queue.Queue()
|
39 |
|
40 |
+
# Load background images
|
41 |
listImg = os.listdir('model/street') if os.path.exists('model/street') else []
|
42 |
if not listImg:
|
43 |
st.error("Error: 'street' directory is missing or empty. Please add background images.")
|
|
|
56 |
def video_frame_callback(frame: av.VideoFrame) -> av.VideoFrame:
|
57 |
global indexImg, output_text
|
58 |
|
|
|
59 |
img = frame.to_ndarray(format="bgr24")
|
60 |
+
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
|
61 |
|
62 |
+
# Process the frame with MediaPipe
|
63 |
+
result = hands.process(img_rgb)
|
64 |
|
65 |
detections = []
|
66 |
+
if result.multi_hand_landmarks:
|
67 |
+
for hand_landmarks in result.multi_hand_landmarks:
|
68 |
+
mp_drawing.draw_landmarks(
|
69 |
+
img, hand_landmarks, mp_hands.HAND_CONNECTIONS,
|
70 |
+
mp_drawing.DrawingSpec(color=(0, 255, 0), thickness=2, circle_radius=4),
|
71 |
+
mp_drawing.DrawingSpec(color=(0, 0, 255), thickness=2)
|
72 |
+
)
|
73 |
+
# Extract bounding box for detection info
|
74 |
+
x_min, y_min = 1.0, 1.0
|
75 |
+
x_max, y_max = 0.0, 0.0
|
76 |
+
for lm in hand_landmarks.landmark:
|
77 |
+
x_min = min(x_min, lm.x)
|
78 |
+
y_min = min(y_min, lm.y)
|
79 |
+
x_max = max(x_max, lm.x)
|
80 |
+
y_max = max(y_max, lm.y)
|
81 |
+
|
82 |
+
h, w, _ = img.shape
|
83 |
+
bbox = np.array([int(x_min * w), int(y_min * h), int((x_max - x_min) * w), int((y_max - y_min) * h)])
|
84 |
+
detections.append(Detection(label="Hand", score=1.0, box=bbox))
|
85 |
+
|
86 |
+
logger.info(f"Detected {len(detections)} hand(s).")
|
87 |
else:
|
88 |
logger.info("No hands detected.")
|
89 |
|