zulfaaulia commited on
Commit
4e7056e
Β·
verified Β·
1 Parent(s): b1d936d

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +114 -0
app.py ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, render_template, request, jsonify
2
+ import os
3
+ import base64
4
+ import numpy as np
5
+ import cv2
6
+ from ultralytics import YOLO
7
+
8
+ app = Flask(__name__)
9
+
10
+ # =======================================================
11
+ # πŸ”₯ LAZY LOAD β€” Model hanya diload saat pertama dipakai
12
+ # =======================================================
13
+ YOLO_MODEL = None
14
+
15
+ def load_yolo():
16
+ global YOLO_MODEL
17
+
18
+ if YOLO_MODEL is not None:
19
+ return YOLO_MODEL
20
+
21
+ try:
22
+ # Prefer load dari file lokal (HuggingFace tidak download ulang)
23
+ if os.path.exists("yolov8n.pt"):
24
+ print("πŸš€ Loading YOLO locally...")
25
+ YOLO_MODEL = YOLO("yolov8n.pt")
26
+ else:
27
+ print("⬇️ Downloading YOLO from Ultralytics...")
28
+ YOLO_MODEL = YOLO("yolov8n.pt") # auto-download 6MB
29
+ print("βœ… YOLO Ready!")
30
+ except Exception as e:
31
+ print("❌ YOLO gagal load:", e)
32
+ YOLO_MODEL = None
33
+
34
+ return YOLO_MODEL
35
+
36
+
37
+ # =======================================================
38
+ # πŸ”₯ HOME PAGE
39
+ # =======================================================
40
+ @app.route("/")
41
+ def home():
42
+ return render_template("object_detection.html")
43
+
44
+
45
+ # =======================================================
46
+ # πŸ”₯ YOLO DETECTION API
47
+ # =======================================================
48
+ @app.route("/api/object_detect", methods=["POST"])
49
+ def object_detect_api():
50
+ model = load_yolo()
51
+
52
+ if model is None:
53
+ return jsonify({"ok": False, "msg": "Model YOLO gagal load!"}), 500
54
+
55
+ if "image" not in request.files:
56
+ return jsonify({"ok": False, "msg": "Tidak ada file gambar"}), 400
57
+
58
+ file = request.files["image"]
59
+ img_bytes = file.read()
60
+
61
+ # Convert image
62
+ nparr = np.frombuffer(img_bytes, np.uint8)
63
+ img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
64
+
65
+ if img is None:
66
+ return jsonify({"ok": False, "msg": "Gambar tidak bisa dibaca"}), 400
67
+
68
+ # YOLO inference
69
+ results = model(img)
70
+
71
+ objects = []
72
+ found = False
73
+
74
+ for result in results:
75
+ for box in result.boxes:
76
+ found = True
77
+ x1, y1, x2, y2 = [int(v) for v in box.xyxy[0]]
78
+ conf = float(box.conf[0])
79
+ cls = int(box.cls.item())
80
+ label = model.names.get(cls, str(cls))
81
+
82
+ objects.append({
83
+ "label": label,
84
+ "confidence": round(conf * 100, 2)
85
+ })
86
+
87
+ # Draw box
88
+ cv2.rectangle(img, (x1, y1), (x2, y2), (30, 200, 255), 3)
89
+ cv2.putText(
90
+ img,
91
+ f"{label} {conf:.2f}",
92
+ (x1, y1 - 5),
93
+ cv2.FONT_HERSHEY_SIMPLEX,
94
+ 0.6,
95
+ (30, 200, 255),
96
+ 2
97
+ )
98
+
99
+ _, buffer = cv2.imencode(".jpg", img)
100
+ img_base64 = base64.b64encode(buffer).decode()
101
+
102
+ return jsonify({
103
+ "ok": True,
104
+ "found": found,
105
+ "objects": objects,
106
+ "image": img_base64
107
+ })
108
+
109
+
110
+ # =======================================================
111
+ # LOCAL RUN
112
+ # =======================================================
113
+ if __name__ == "__main__":
114
+ app.run(host="0.0.0.0", port=7860)