Mathematicaljuice commited on
Commit
0ee8971
·
verified ·
1 Parent(s): 084fd49

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +100 -32
app.py CHANGED
@@ -1,8 +1,5 @@
1
  import cv2
2
- import mediapipe as mp
3
-
4
- from mediapipe.tasks.python import vision
5
- from mediapipe.tasks.python import BaseOptions
6
  import numpy as np
7
  import torch
8
  import torch.nn as nn
@@ -12,12 +9,31 @@ import gradio as gr
12
  # Labels
13
  # ----------------------------
14
  GESTURE_LABELS = {
15
- 0: "A", 1: "B", 2: "L", 3: "U", 4: "V", 5: "W",
16
- 6: "Z", 7: "F", 8: "five", 9: "one", 10: "three",
17
- 11: "two", 12: "six", 13: "seven", 14: "eight",
18
- 15: "nine", 16: "ten", 17: "E", 18: "four",
19
- 19: "i", 20: "k", 21: "r", 22: "zero",
20
- 23: "m", 24: "s"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  }
22
 
23
  CONF_THRESHOLD = 0.6
@@ -28,76 +44,128 @@ CONF_THRESHOLD = 0.6
28
  class GestureNet(nn.Module):
29
  def __init__(self, input_size=126, num_classes=len(GESTURE_LABELS)):
30
  super().__init__()
 
31
  self.fc1 = nn.Linear(input_size, 256)
32
  self.fc2 = nn.Linear(256, 128)
33
  self.fc3 = nn.Linear(128, num_classes)
 
34
  self.relu = nn.ReLU()
35
  self.dropout = nn.Dropout(0.3)
36
 
37
  def forward(self, x):
38
  x = self.relu(self.fc1(x))
39
  x = self.dropout(x)
 
40
  x = self.relu(self.fc2(x))
41
  x = self.dropout(x)
42
- return self.fc3(x)
43
 
 
 
 
 
 
 
 
44
  model = GestureNet()
45
- model.load_state_dict(torch.load("gesture_model1.pth", map_location="cpu"))
 
 
 
 
 
 
 
46
  model.eval()
47
 
48
  # ----------------------------
49
- # MediaPipe
50
  # ----------------------------
51
- mp_hands = mp.solutions.hands
52
-
53
  def predict(image):
54
- image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
55
 
56
- with mp_hands.Hands(static_image_mode=True, max_num_hands=2) as hands:
57
- results = hands.process(image)
 
 
 
 
 
 
 
 
 
 
 
 
58
 
59
  coords = []
60
 
 
61
  if results.multi_hand_landmarks:
 
62
  for hand_landmarks in results.multi_hand_landmarks:
63
- hand_coords = np.array([[lm.x, lm.y, lm.z] for lm in hand_landmarks.landmark])
64
 
 
 
 
 
 
 
65
  hand_coords -= hand_coords[0]
66
- max_val = np.max(np.linalg.norm(hand_coords, axis=1))
 
 
 
 
67
  if max_val > 0:
68
  hand_coords /= max_val
69
 
70
  coords.extend(hand_coords.flatten())
71
 
 
72
  if len(coords) < 126:
73
  coords.extend([0.0] * (126 - len(coords)))
 
74
  elif len(coords) > 126:
75
  coords = coords[:126]
76
 
77
- if len(coords) == 126:
78
- input_tensor = torch.tensor(coords, dtype=torch.float32).unsqueeze(0)
 
 
 
 
 
79
 
80
- with torch.no_grad():
81
- outputs = model(input_tensor)
82
- probs = torch.softmax(outputs, dim=1).numpy()[0]
83
 
84
- pred_class = np.argmax(probs)
85
- confidence = probs[pred_class]
86
 
87
- if confidence >= CONF_THRESHOLD:
88
- return f"{GESTURE_LABELS[pred_class]} ({confidence*100:.2f}%)"
 
 
 
 
 
 
 
 
 
89
 
90
  return "Unknown"
91
 
92
  # ----------------------------
93
- # Gradio UI
94
  # ----------------------------
95
  app = gr.Interface(
96
  fn=predict,
97
  inputs=gr.Image(type="numpy"),
98
  outputs="text",
99
  title="Hand Gesture Recognition",
100
- description="Upload an image of a hand gesture"
101
  )
102
 
103
- app.launch()
 
 
 
 
1
  import cv2
2
+ import mediapipe.python.solutions.hands as mp_hands
 
 
 
3
  import numpy as np
4
  import torch
5
  import torch.nn as nn
 
9
  # Labels
10
  # ----------------------------
11
  GESTURE_LABELS = {
12
+ 0: "A",
13
+ 1: "B",
14
+ 2: "L",
15
+ 3: "U",
16
+ 4: "V",
17
+ 5: "W",
18
+ 6: "Z",
19
+ 7: "F",
20
+ 8: "five",
21
+ 9: "one",
22
+ 10: "three",
23
+ 11: "two",
24
+ 12: "six",
25
+ 13: "seven",
26
+ 14: "eight",
27
+ 15: "nine",
28
+ 16: "ten",
29
+ 17: "E",
30
+ 18: "four",
31
+ 19: "i",
32
+ 20: "k",
33
+ 21: "r",
34
+ 22: "zero",
35
+ 23: "m",
36
+ 24: "s"
37
  }
38
 
39
  CONF_THRESHOLD = 0.6
 
44
  class GestureNet(nn.Module):
45
  def __init__(self, input_size=126, num_classes=len(GESTURE_LABELS)):
46
  super().__init__()
47
+
48
  self.fc1 = nn.Linear(input_size, 256)
49
  self.fc2 = nn.Linear(256, 128)
50
  self.fc3 = nn.Linear(128, num_classes)
51
+
52
  self.relu = nn.ReLU()
53
  self.dropout = nn.Dropout(0.3)
54
 
55
  def forward(self, x):
56
  x = self.relu(self.fc1(x))
57
  x = self.dropout(x)
58
+
59
  x = self.relu(self.fc2(x))
60
  x = self.dropout(x)
 
61
 
62
+ x = self.fc3(x)
63
+
64
+ return x
65
+
66
+ # ----------------------------
67
+ # Load Model
68
+ # ----------------------------
69
  model = GestureNet()
70
+
71
+ model.load_state_dict(
72
+ torch.load(
73
+ "gesture_model1.pth",
74
+ map_location=torch.device("cpu")
75
+ )
76
+ )
77
+
78
  model.eval()
79
 
80
  # ----------------------------
81
+ # Prediction Function
82
  # ----------------------------
 
 
83
  def predict(image):
 
84
 
85
+ if image is None:
86
+ return "No image uploaded"
87
+
88
+ # Convert RGB
89
+ image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
90
+
91
+ # MediaPipe Hands
92
+ with mp_hands.Hands(
93
+ static_image_mode=True,
94
+ max_num_hands=2,
95
+ min_detection_confidence=0.5
96
+ ) as hands:
97
+
98
+ results = hands.process(image_rgb)
99
 
100
  coords = []
101
 
102
+ # Extract landmarks
103
  if results.multi_hand_landmarks:
104
+
105
  for hand_landmarks in results.multi_hand_landmarks:
 
106
 
107
+ hand_coords = np.array([
108
+ [lm.x, lm.y, lm.z]
109
+ for lm in hand_landmarks.landmark
110
+ ])
111
+
112
+ # Normalize
113
  hand_coords -= hand_coords[0]
114
+
115
+ max_val = np.max(
116
+ np.linalg.norm(hand_coords, axis=1)
117
+ )
118
+
119
  if max_val > 0:
120
  hand_coords /= max_val
121
 
122
  coords.extend(hand_coords.flatten())
123
 
124
+ # Pad / truncate
125
  if len(coords) < 126:
126
  coords.extend([0.0] * (126 - len(coords)))
127
+
128
  elif len(coords) > 126:
129
  coords = coords[:126]
130
 
131
+ # Predict
132
+ input_tensor = torch.tensor(
133
+ coords,
134
+ dtype=torch.float32
135
+ ).unsqueeze(0)
136
+
137
+ with torch.no_grad():
138
 
139
+ outputs = model(input_tensor)
 
 
140
 
141
+ probs = torch.softmax(outputs, dim=1)
 
142
 
143
+ probs = probs.numpy()[0]
144
+
145
+ pred_class = np.argmax(probs)
146
+
147
+ confidence = probs[pred_class]
148
+
149
+ if confidence >= CONF_THRESHOLD:
150
+
151
+ label = GESTURE_LABELS[pred_class]
152
+
153
+ return f"{label} ({confidence * 100:.2f}%)"
154
 
155
  return "Unknown"
156
 
157
  # ----------------------------
158
+ # Gradio Interface
159
  # ----------------------------
160
  app = gr.Interface(
161
  fn=predict,
162
  inputs=gr.Image(type="numpy"),
163
  outputs="text",
164
  title="Hand Gesture Recognition",
165
+ description="Upload a hand gesture image"
166
  )
167
 
168
+ # ----------------------------
169
+ # Launch
170
+ # ----------------------------
171
+ app.launch(server_name="0.0.0.0", server_port=7860)