morefaat69 commited on
Commit
4ef45aa
·
verified ·
1 Parent(s): b204dd0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +16 -60
app.py CHANGED
@@ -5,48 +5,37 @@ import os
5
  import cv2
6
  import base64
7
  from ultralytics import YOLO
8
-
9
- # ─── Load Models ──────────────────────────────────────────────────────────────
10
- person_model = YOLO("yolov8n.pt")
11
-
12
- # ─── App Setup ────────────────────────────────────────────────────────────────
13
  app = FastAPI()
14
-
15
  UPLOAD_FOLDER = "/tmp/uploads"
16
  os.makedirs(UPLOAD_FOLDER, exist_ok=True)
17
-
18
  app.mount("/uploads", StaticFiles(directory=UPLOAD_FOLDER), name="uploads")
19
-
20
- PERSON_CONF = 0.30 # threshold
21
- STATUE_CONF = 0.20 # threshold
22
-
23
  router = APIRouter()
24
-
25
-
26
  def draw_label(image, label, x1, y1, x2, y2, box_color, text_color):
 
27
  font = cv2.FONT_HERSHEY_SIMPLEX
28
  font_scale = 0.6
29
  thickness = 2
30
  (tw, th), _ = cv2.getTextSize(label, font, font_scale, thickness)
31
-
32
  if y1 - th - 8 >= 0:
33
  label_y1 = y1 - th - 8
34
  label_y2 = y1
35
  text_y = y1 - 5
36
  else:
 
37
  label_y1 = y1
38
  label_y2 = y1 + th + 8
39
  text_y = y1 + th + 3
40
-
41
  cv2.rectangle(image, (x1, label_y1), (x1 + tw + 4, label_y2), box_color, -1)
42
  cv2.putText(image, label, (x1 + 2, text_y), font, font_scale, text_color, thickness)
43
-
44
-
45
  @app.get("/")
46
  def root():
47
  return {"message": "AI API is running 🚀"}
48
-
49
-
50
  @router.post("/predict-image")
51
  async def predict_image(
52
  request: Request,
@@ -54,45 +43,27 @@ async def predict_image(
54
  ):
55
  safe_filename = file.filename.replace(" ", "_")
56
  file_path = os.path.join(UPLOAD_FOLDER, safe_filename)
57
-
58
  with open(file_path, "wb") as buffer:
59
  shutil.copyfileobj(file.file, buffer)
60
-
61
  image = cv2.imread(file_path)
62
-
63
  if image is None:
64
  return {"error": "Invalid image"}
65
-
66
  detections = []
67
  person_count = 0
68
  statue_count = 0
69
-
70
- # ── Person Detection ──────────────────────────────────────────────────────
71
- # imgsz=1280 يخلي الموديل يشوف الصورة بدقة أعلى داخلياً
72
- # فبيلاقط أشخاص صغار/بعيدين كانوا بيضيعوا على الدقة الافتراضية (640)
73
- person_results = person_model(
74
- file_path,
75
- imgsz=1280,
76
- conf=PERSON_CONF,
77
- iou=0.5, # نسبة أعلى شوية من 0.45 تمنع لغي أشخاص متقاربين بالغلط
78
- max_det=300
79
- )
80
-
81
  for box in person_results[0].boxes:
82
  cls_id = int(box.cls)
83
  if cls_id != 0:
84
  continue
85
-
86
  conf = float(box.conf)
87
- if conf < PERSON_CONF:
88
  continue
89
-
90
  x1, y1, x2, y2 = map(int, box.xyxy[0])
91
-
92
  cv2.rectangle(image, (x1, y1), (x2, y2), (0, 255, 0), 2)
93
  draw_label(image, f"Person {conf:.2f}", x1, y1, x2, y2,
94
  box_color=(0, 255, 0), text_color=(0, 0, 0))
95
-
96
  detections.append({
97
  "type": "person",
98
  "name": "Person",
@@ -100,28 +71,18 @@ async def predict_image(
100
  "bbox": [x1, y1, x2, y2]
101
  })
102
  person_count += 1
103
-
104
- # ── Statue Detection ──────────────────────────────────────────────────────
105
- # سيبناها كما كانت بالضبط (imgsz عادي + conf منخفض) عشان تفضل تكشف التماثيل صح
106
- statue_results = statue_model(
107
- file_path,
108
- conf=STATUE_CONF
109
- )
110
-
111
  for box in statue_results[0].boxes:
112
  conf = float(box.conf)
113
- if conf < STATUE_CONF:
114
  continue
115
-
116
  cls_id = int(box.cls)
117
  statue_name = statue_results[0].names[cls_id]
118
-
119
  x1, y1, x2, y2 = map(int, box.xyxy[0])
120
-
121
  cv2.rectangle(image, (x1, y1), (x2, y2), (0, 0, 255), 2)
122
  draw_label(image, f"{statue_name} {conf:.2f}", x1, y1, x2, y2,
123
  box_color=(0, 0, 255), text_color=(255, 255, 255))
124
-
125
  detections.append({
126
  "type": "statue",
127
  "name": statue_name,
@@ -129,17 +90,13 @@ async def predict_image(
129
  "bbox": [x1, y1, x2, y2]
130
  })
131
  statue_count += 1
132
-
133
- # ── Save Output Image ─────────────────────────────────────────────────────
134
  output_filename = f"output_{safe_filename}"
135
  output_path = os.path.join(UPLOAD_FOLDER, output_filename)
136
  cv2.imwrite(output_path, image)
137
-
138
  with open(output_path, "rb") as img_file:
139
  image_base64 = base64.b64encode(img_file.read()).decode("utf-8")
140
-
141
  image_url = f"{request.base_url}uploads/{output_filename}"
142
-
143
  return {
144
  "total_count": len(detections),
145
  "persons": person_count,
@@ -148,6 +105,5 @@ async def predict_image(
148
  "output_image_base64": f"data:image/jpeg;base64,{image_base64}",
149
  "detections": detections
150
  }
 
151
 
152
-
153
- app.include_router(router)
 
5
  import cv2
6
  import base64
7
  from ultralytics import YOLO
8
+ # ─── Load Models
9
+ person_model = YOLO("yolov8n.pt")
10
+ statue_model = YOLO("best.pt")
11
+ # ─── App Setup
 
12
  app = FastAPI()
 
13
  UPLOAD_FOLDER = "/tmp/uploads"
14
  os.makedirs(UPLOAD_FOLDER, exist_ok=True)
 
15
  app.mount("/uploads", StaticFiles(directory=UPLOAD_FOLDER), name="uploads")
16
+ CONF_THRESHOLD = 0.30
 
 
 
17
  router = APIRouter()
 
 
18
  def draw_label(image, label, x1, y1, x2, y2, box_color, text_color):
19
+
20
  font = cv2.FONT_HERSHEY_SIMPLEX
21
  font_scale = 0.6
22
  thickness = 2
23
  (tw, th), _ = cv2.getTextSize(label, font, font_scale, thickness)
24
+
25
  if y1 - th - 8 >= 0:
26
  label_y1 = y1 - th - 8
27
  label_y2 = y1
28
  text_y = y1 - 5
29
  else:
30
+
31
  label_y1 = y1
32
  label_y2 = y1 + th + 8
33
  text_y = y1 + th + 3
 
34
  cv2.rectangle(image, (x1, label_y1), (x1 + tw + 4, label_y2), box_color, -1)
35
  cv2.putText(image, label, (x1 + 2, text_y), font, font_scale, text_color, thickness)
 
 
36
  @app.get("/")
37
  def root():
38
  return {"message": "AI API is running 🚀"}
 
 
39
  @router.post("/predict-image")
40
  async def predict_image(
41
  request: Request,
 
43
  ):
44
  safe_filename = file.filename.replace(" ", "_")
45
  file_path = os.path.join(UPLOAD_FOLDER, safe_filename)
 
46
  with open(file_path, "wb") as buffer:
47
  shutil.copyfileobj(file.file, buffer)
 
48
  image = cv2.imread(file_path)
 
49
  if image is None:
50
  return {"error": "Invalid image"}
 
51
  detections = []
52
  person_count = 0
53
  statue_count = 0
54
+ # ── Person Detection
55
+ person_results = person_model(file_path)
 
 
 
 
 
 
 
 
 
 
56
  for box in person_results[0].boxes:
57
  cls_id = int(box.cls)
58
  if cls_id != 0:
59
  continue
 
60
  conf = float(box.conf)
61
+ if conf < CONF_THRESHOLD:
62
  continue
 
63
  x1, y1, x2, y2 = map(int, box.xyxy[0])
 
64
  cv2.rectangle(image, (x1, y1), (x2, y2), (0, 255, 0), 2)
65
  draw_label(image, f"Person {conf:.2f}", x1, y1, x2, y2,
66
  box_color=(0, 255, 0), text_color=(0, 0, 0))
 
67
  detections.append({
68
  "type": "person",
69
  "name": "Person",
 
71
  "bbox": [x1, y1, x2, y2]
72
  })
73
  person_count += 1
74
+ # ── Statue Detection
75
+ statue_results = statue_model(file_path)
 
 
 
 
 
 
76
  for box in statue_results[0].boxes:
77
  conf = float(box.conf)
78
+ if conf < CONF_THRESHOLD:
79
  continue
 
80
  cls_id = int(box.cls)
81
  statue_name = statue_results[0].names[cls_id]
 
82
  x1, y1, x2, y2 = map(int, box.xyxy[0])
 
83
  cv2.rectangle(image, (x1, y1), (x2, y2), (0, 0, 255), 2)
84
  draw_label(image, f"{statue_name} {conf:.2f}", x1, y1, x2, y2,
85
  box_color=(0, 0, 255), text_color=(255, 255, 255))
 
86
  detections.append({
87
  "type": "statue",
88
  "name": statue_name,
 
90
  "bbox": [x1, y1, x2, y2]
91
  })
92
  statue_count += 1
93
+ # ── Save Output Image
 
94
  output_filename = f"output_{safe_filename}"
95
  output_path = os.path.join(UPLOAD_FOLDER, output_filename)
96
  cv2.imwrite(output_path, image)
 
97
  with open(output_path, "rb") as img_file:
98
  image_base64 = base64.b64encode(img_file.read()).decode("utf-8")
 
99
  image_url = f"{request.base_url}uploads/{output_filename}"
 
100
  return {
101
  "total_count": len(detections),
102
  "persons": person_count,
 
105
  "output_image_base64": f"data:image/jpeg;base64,{image_base64}",
106
  "detections": detections
107
  }
108
+ app.include_router(router)
109