RomRam1 commited on
Commit
787312f
·
verified ·
1 Parent(s): e8754de

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +49 -35
app.py CHANGED
@@ -1,85 +1,100 @@
1
- import cv2
2
- import numpy as np
3
- import math
4
  import os
5
- from flask import Flask, request, jsonify
6
- # 🔥 FORCE CPU MODE FOR MEDIAPIPE (REQUIRED IN CLOUD)
7
- os.environ["MEDIAPIPE_DISABLE_GPU"] = "1"
8
  os.environ["CUDA_VISIBLE_DEVICES"] = "-1"
9
  os.environ["TF_CPP_MIN_LOG_LEVEL"] = "3"
10
 
11
- from cvzone.HandTrackingModule import HandDetector
 
 
 
 
12
  from cvzone.ClassificationModule import Classifier
13
 
14
- os.environ["TF_CPP_MIN_LOG_LEVEL"] = "3"
15
 
16
  MODEL_PATH = "Model_old/keras_model.h5"
17
  LABELS_PATH = "Model_old/labels.txt"
18
-
19
- CONFIDENCE_THRESHOLD = 0.5
20
  IMG_SIZE = 300
21
  OFFSET = 20
 
22
  STABILITY_THRESHOLD = 3
23
 
 
 
24
  app = Flask(__name__)
25
 
26
- print("Loading hand detector...")
27
- detector = HandDetector(maxHands=1)
 
 
 
 
 
 
 
 
 
 
28
 
29
- print("Loading classifier...")
30
  classifier = Classifier(MODEL_PATH, LABELS_PATH)
31
 
32
  with open(LABELS_PATH) as f:
33
  labels = [l.strip() for l in f.readlines()]
34
 
35
- last_gesture = None
36
  stable_gesture = None
37
  stable_count = 0
38
 
 
39
 
40
  @app.route("/predict", methods=["POST"])
41
  def predict():
42
- global last_gesture, stable_gesture, stable_count
43
 
44
  if "frame" not in request.files:
45
  return jsonify({"gesture": None, "confidence": 0})
46
 
47
  file = request.files["frame"]
48
- img_bytes = np.frombuffer(file.read(), np.uint8)
49
- frame = cv2.imdecode(img_bytes, cv2.IMREAD_COLOR)
50
-
51
  frame = cv2.flip(frame, 1)
52
- hands, _ = detector.findHands(frame)
53
 
54
- if not hands:
55
- stable_count = 0
 
 
56
  stable_gesture = None
 
57
  return jsonify({"gesture": None, "confidence": 0})
58
 
59
- hand = hands[0]
60
- x, y, w, h = hand["bbox"]
 
 
 
 
 
 
61
 
62
  imgWhite = np.ones((IMG_SIZE, IMG_SIZE, 3), np.uint8) * 255
63
- imgCrop = frame[max(0, y - OFFSET):y + h + OFFSET,
64
- max(0, x - OFFSET):x + w + OFFSET]
65
 
66
  if imgCrop.size == 0:
67
  return jsonify({"gesture": None, "confidence": 0})
68
 
69
- aspectRatio = h / w
70
 
71
  if aspectRatio > 1:
72
- k = IMG_SIZE / h
73
- wCal = math.ceil(k * w)
74
  imgResize = cv2.resize(imgCrop, (wCal, IMG_SIZE))
75
- wGap = math.ceil((IMG_SIZE - wCal) / 2)
76
- imgWhite[:, wGap:wCal + wGap] = imgResize
77
  else:
78
- k = IMG_SIZE / w
79
- hCal = math.ceil(k * h)
80
  imgResize = cv2.resize(imgCrop, (IMG_SIZE, hCal))
81
- hGap = math.ceil((IMG_SIZE - hCal) / 2)
82
- imgWhite[hGap:hCal + hGap, :] = imgResize
83
 
84
  prediction, index = classifier.getPrediction(imgWhite, draw=False)
85
  confidence = float(prediction[index])
@@ -92,7 +107,6 @@ def predict():
92
  stable_count = 1
93
 
94
  if stable_count >= STABILITY_THRESHOLD and confidence >= CONFIDENCE_THRESHOLD:
95
- last_gesture = gesture
96
  return jsonify({
97
  "gesture": gesture,
98
  "confidence": confidence
 
 
 
 
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
7
+ import math
8
+ from flask import Flask, request, jsonify
9
+ import mediapipe as mp
10
  from cvzone.ClassificationModule import Classifier
11
 
12
+ # ---------------- CONFIG ----------------
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
19
  STABILITY_THRESHOLD = 3
20
 
21
+ # ---------------- APP ----------------
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
+ )
35
+
36
+ # ---------------- CLASSIFIER ----------------
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
45
 
46
+ # ---------------- API ----------------
47
 
48
  @app.route("/predict", methods=["POST"])
49
  def predict():
50
+ global stable_gesture, stable_count
51
 
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
+
71
+ x_vals = [int(p.x * w) for p in lm]
72
+ y_vals = [int(p.y * h) for p in lm]
73
+
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])
 
107
  stable_count = 1
108
 
109
  if stable_count >= STABILITY_THRESHOLD and confidence >= CONFIDENCE_THRESHOLD:
 
110
  return jsonify({
111
  "gesture": gesture,
112
  "confidence": confidence