90 lines
2.7 KiB
Python
90 lines
2.7 KiB
Python
import time
|
|
import os
|
|
import cv2
|
|
import numpy as np
|
|
import mediapipe as mp
|
|
import tensorflow as tf
|
|
from flask import Flask, request, jsonify
|
|
from flask_cors import CORS
|
|
|
|
app = Flask(__name__)
|
|
CORS(app)
|
|
|
|
# Load model dari folder yang sama
|
|
MODEL_PATH = "best_sibi_landmark.keras"
|
|
print("[INFO] Memuat model Keras...")
|
|
model = tf.keras.models.load_model(MODEL_PATH)
|
|
classes = list("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
|
|
|
mp_hands = mp.solutions.hands
|
|
hands = mp_hands.Hands(static_image_mode=True, max_num_hands=2, min_detection_confidence=0.5)
|
|
|
|
def normalize(points):
|
|
points = np.array(points)
|
|
wrist = points[0]
|
|
points[:, 0] -= wrist[0]
|
|
points[:, 1] -= wrist[1]
|
|
points[:, 2] -= wrist[2]
|
|
return points.flatten()
|
|
|
|
@app.route('/predict', methods=['POST'])
|
|
def predict():
|
|
# Catat waktu mulai dari awal request masuk
|
|
start_time = time.time()
|
|
try:
|
|
file = request.files['image']
|
|
npimg = np.frombuffer(file.read(), np.uint8)
|
|
img = cv2.imdecode(npimg, cv2.IMREAD_COLOR)
|
|
|
|
rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
|
|
result = hands.process(rgb)
|
|
|
|
# Hitung durasi sementara jika tangan tidak terdeteksi
|
|
end_time = time.time()
|
|
processing_time = round((end_time - start_time) * 1000)
|
|
|
|
if not result.multi_hand_landmarks:
|
|
return jsonify({
|
|
"status": "error",
|
|
"message": "Tangan tidak terdeteksi!",
|
|
"latency": f"{processing_time} ms"
|
|
})
|
|
|
|
left = [0] * 63
|
|
right = [0] * 63
|
|
|
|
for idx, hand in enumerate(result.multi_hand_landmarks):
|
|
pts = [[lm.x, lm.y, lm.z] for lm in hand.landmark]
|
|
pts = normalize(pts)
|
|
hand_type = result.multi_handedness[idx].classification[0].label
|
|
if hand_type == "Left":
|
|
left = pts.tolist()
|
|
else:
|
|
right = pts.tolist()
|
|
|
|
feature = np.array(right + left, dtype=np.float32).reshape(1, 126, 1)
|
|
pred = model.predict(feature, verbose=0)[0]
|
|
best_idx = np.argmax(pred)
|
|
|
|
# Hitung total waktu proses sampai prediksi selesai
|
|
end_time = time.time()
|
|
processing_time = round((end_time - start_time) * 1000)
|
|
|
|
return jsonify({
|
|
"status": "success",
|
|
"letter": classes[best_idx],
|
|
"confidence": f"{pred[best_idx] * 100:.2f}%",
|
|
"latency": f"{processing_time} ms"
|
|
})
|
|
|
|
except Exception as e:
|
|
end_time = time.time()
|
|
processing_time = round((end_time - start_time) * 1000)
|
|
return jsonify({
|
|
"status": "error",
|
|
"message": str(e),
|
|
"latency": f"{processing_time} ms"
|
|
})
|
|
|
|
if __name__ == '__main__':
|
|
app.run(port=5000, debug=True) |