RomRam1 commited on
Commit
4fa21dc
·
verified ·
1 Parent(s): 052c593

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +76 -29
app.py CHANGED
@@ -1,6 +1,9 @@
1
  import os
 
 
2
  os.environ["CUDA_VISIBLE_DEVICES"] = "-1"
3
  os.environ["TF_CPP_MIN_LOG_LEVEL"] = "3"
 
4
 
5
  import cv2
6
  import numpy as np
@@ -13,6 +16,7 @@ from cvzone.ClassificationModule import Classifier
13
 
14
  MODEL_PATH = "Model_old/keras_model.h5"
15
  LABELS_PATH = "Model_old/labels.txt"
 
16
  IMG_SIZE = 300
17
  OFFSET = 20
18
  CONFIDENCE_THRESHOLD = 0.5
@@ -22,13 +26,14 @@ STABILITY_THRESHOLD = 3
22
 
23
  app = Flask(__name__)
24
 
25
- # ---------------- MEDIAPIPE (CPU ONLY) ----------------
26
 
27
  mp_hands = mp.solutions.hands
 
28
  hands = mp_hands.Hands(
29
- static_image_mode=True, # 🔥 REQUIRED for cloud
30
  max_num_hands=1,
31
- model_complexity=0, # 🔥 CPU-only
32
  min_detection_confidence=0.6,
33
  min_tracking_confidence=0.6
34
  )
@@ -37,8 +42,8 @@ hands = mp_hands.Hands(
37
 
38
  classifier = Classifier(MODEL_PATH, LABELS_PATH)
39
 
40
- with open(LABELS_PATH) as f:
41
- labels = [l.strip() for l in f.readlines()]
42
 
43
  stable_gesture = None
44
  stable_count = 0
@@ -52,19 +57,34 @@ def predict():
52
  if "frame" not in request.files:
53
  return jsonify({"gesture": None, "confidence": 0})
54
 
55
- file = request.files["frame"]
56
- img = np.frombuffer(file.read(), np.uint8)
57
- frame = cv2.imdecode(img, cv2.IMREAD_COLOR)
58
- frame = cv2.flip(frame, 1)
 
 
 
 
 
 
 
 
59
 
60
- rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
61
- result = hands.process(rgb)
 
 
 
 
 
 
62
 
63
  if not result.multi_hand_landmarks:
64
  stable_gesture = None
65
  stable_count = 0
66
  return jsonify({"gesture": None, "confidence": 0})
67
 
 
68
  h, w, _ = frame.shape
69
  lm = result.multi_hand_landmarks[0].landmark
70
 
@@ -74,32 +94,53 @@ def predict():
74
  x, y = min(x_vals), min(y_vals)
75
  bw, bh = max(x_vals) - x, max(y_vals) - y
76
 
 
 
 
 
77
  imgWhite = np.ones((IMG_SIZE, IMG_SIZE, 3), np.uint8) * 255
78
- imgCrop = frame[max(0, y - OFFSET):y + bh + OFFSET,
79
- max(0, x - OFFSET):x + bw + OFFSET]
 
 
 
80
 
81
  if imgCrop.size == 0:
82
  return jsonify({"gesture": None, "confidence": 0})
83
 
84
  aspectRatio = bh / bw
85
 
86
- if aspectRatio > 1:
87
- k = IMG_SIZE / bh
88
- wCal = math.ceil(k * bw)
89
- imgResize = cv2.resize(imgCrop, (wCal, IMG_SIZE))
90
- wGap = (IMG_SIZE - wCal) // 2
91
- imgWhite[:, wGap:wGap + wCal] = imgResize
92
- else:
93
- k = IMG_SIZE / bw
94
- hCal = math.ceil(k * bh)
95
- imgResize = cv2.resize(imgCrop, (IMG_SIZE, hCal))
96
- hGap = (IMG_SIZE - hCal) // 2
97
- imgWhite[hGap:hGap + hCal, :] = imgResize
 
 
 
 
 
 
 
 
98
 
99
- prediction, index = classifier.getPrediction(imgWhite, draw=False)
100
- confidence = float(prediction[index])
101
- gesture = labels[index]
102
 
 
 
 
 
 
 
 
103
  if gesture == stable_gesture:
104
  stable_count += 1
105
  else:
@@ -112,4 +153,10 @@ def predict():
112
  "confidence": confidence
113
  })
114
 
115
- return jsonify({"gesture": None, "confidence": 0})
 
 
 
 
 
 
 
1
  import os
2
+
3
+ # 🔥 HARD CPU ENFORCEMENT (BEFORE ANY IMPORTS)
4
  os.environ["CUDA_VISIBLE_DEVICES"] = "-1"
5
  os.environ["TF_CPP_MIN_LOG_LEVEL"] = "3"
6
+ os.environ["MEDIAPIPE_DISABLE_GPU"] = "1"
7
 
8
  import cv2
9
  import numpy as np
 
16
 
17
  MODEL_PATH = "Model_old/keras_model.h5"
18
  LABELS_PATH = "Model_old/labels.txt"
19
+
20
  IMG_SIZE = 300
21
  OFFSET = 20
22
  CONFIDENCE_THRESHOLD = 0.5
 
26
 
27
  app = Flask(__name__)
28
 
29
+ # ---------------- MEDIAPIPE (CPU-ONLY, CLOUD SAFE) ----------------
30
 
31
  mp_hands = mp.solutions.hands
32
+
33
  hands = mp_hands.Hands(
34
+ static_image_mode=True, # REQUIRED for server inference
35
  max_num_hands=1,
36
+ model_complexity=0, # CPU graph only
37
  min_detection_confidence=0.6,
38
  min_tracking_confidence=0.6
39
  )
 
42
 
43
  classifier = Classifier(MODEL_PATH, LABELS_PATH)
44
 
45
+ with open(LABELS_PATH, "r") as f:
46
+ labels = [line.strip() for line in f.readlines()]
47
 
48
  stable_gesture = None
49
  stable_count = 0
 
57
  if "frame" not in request.files:
58
  return jsonify({"gesture": None, "confidence": 0})
59
 
60
+ # ---- Decode image safely ----
61
+ try:
62
+ file = request.files["frame"]
63
+ img_bytes = np.frombuffer(file.read(), np.uint8)
64
+ frame = cv2.imdecode(img_bytes, cv2.IMREAD_COLOR)
65
+
66
+ if frame is None:
67
+ return jsonify({"gesture": None, "confidence": 0})
68
+
69
+ frame = cv2.flip(frame, 1)
70
+ except Exception:
71
+ return jsonify({"gesture": None, "confidence": 0})
72
 
73
+ # ---- MediaPipe inference ----
74
+ try:
75
+ rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
76
+ result = hands.process(rgb)
77
+ except Exception:
78
+ stable_gesture = None
79
+ stable_count = 0
80
+ return jsonify({"gesture": None, "confidence": 0})
81
 
82
  if not result.multi_hand_landmarks:
83
  stable_gesture = None
84
  stable_count = 0
85
  return jsonify({"gesture": None, "confidence": 0})
86
 
87
+ # ---- Bounding box from landmarks ----
88
  h, w, _ = frame.shape
89
  lm = result.multi_hand_landmarks[0].landmark
90
 
 
94
  x, y = min(x_vals), min(y_vals)
95
  bw, bh = max(x_vals) - x, max(y_vals) - y
96
 
97
+ if bw <= 0 or bh <= 0:
98
+ return jsonify({"gesture": None, "confidence": 0})
99
+
100
+ # ---- Image preprocessing ----
101
  imgWhite = np.ones((IMG_SIZE, IMG_SIZE, 3), np.uint8) * 255
102
+
103
+ imgCrop = frame[
104
+ max(0, y - OFFSET): y + bh + OFFSET,
105
+ max(0, x - OFFSET): x + bw + OFFSET
106
+ ]
107
 
108
  if imgCrop.size == 0:
109
  return jsonify({"gesture": None, "confidence": 0})
110
 
111
  aspectRatio = bh / bw
112
 
113
+ try:
114
+ if aspectRatio > 1:
115
+ k = IMG_SIZE / bh
116
+ wCal = max(1, math.ceil(k * bw))
117
+ imgResize = cv2.resize(imgCrop, (wCal, IMG_SIZE))
118
+ wGap = (IMG_SIZE - wCal) // 2
119
+ imgWhite[:, wGap:wGap + wCal] = imgResize
120
+ else:
121
+ k = IMG_SIZE / bw
122
+ hCal = max(1, math.ceil(k * bh))
123
+ imgResize = cv2.resize(imgCrop, (IMG_SIZE, hCal))
124
+ hGap = (IMG_SIZE - hCal) // 2
125
+ imgWhite[hGap:hGap + hCal, :] = imgResize
126
+ except Exception:
127
+ return jsonify({"gesture": None, "confidence": 0})
128
+
129
+ # ---- Classification ----
130
+ try:
131
+ prediction, index = classifier.getPrediction(imgWhite, draw=False)
132
+ index = int(index)
133
 
134
+ if index < 0 or index >= len(labels):
135
+ return jsonify({"gesture": None, "confidence": 0})
 
136
 
137
+ confidence = float(prediction[index])
138
+ confidence = max(0.0, min(confidence, 1.0))
139
+ gesture = labels[index]
140
+ except Exception:
141
+ return jsonify({"gesture": None, "confidence": 0})
142
+
143
+ # ---- Stability logic ----
144
  if gesture == stable_gesture:
145
  stable_count += 1
146
  else:
 
153
  "confidence": confidence
154
  })
155
 
156
+ return jsonify({"gesture": None, "confidence": 0})
157
+
158
+
159
+ # ---------------- ENTRY ----------------
160
+
161
+ if __name__ == "__main__":
162
+ app.run(host="0.0.0.0", port=7860)