Paradise151 commited on
Commit
4e2d441
·
verified ·
1 Parent(s): 2bfe44b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +24 -107
app.py CHANGED
@@ -1,101 +1,3 @@
1
- # from fastapi import FastAPI, UploadFile, File, Form
2
- # from fastapi.responses import JSONResponse, Response, FileResponse
3
- # from fastapi.middleware.cors import CORSMiddleware
4
- # from ultralytics import YOLO
5
- # import torch
6
- # import cv2
7
- # import numpy as np
8
-
9
- # app = FastAPI()
10
-
11
- # # Разрешаем вызовы из фронта того же Space
12
- # app.add_middleware(
13
- # CORSMiddleware,
14
- # allow_origins=["*"],
15
- # allow_methods=["*"],
16
- # allow_headers=["*"],
17
- # )
18
-
19
- # # Загружаем модель
20
- # model = YOLO("best.pt")
21
- # device = "cuda" if torch.cuda.is_available() else "cpu"
22
- # model.to(device)
23
-
24
- # @app.get("/")
25
- # def root():
26
- # return FileResponse("index.html")
27
-
28
- # def read_image_to_bgr(file_bytes: bytes) -> np.ndarray:
29
- # # Декод JPEG/PNG в BGR
30
- # img_array = np.frombuffer(file_bytes, dtype=np.uint8)
31
- # img = cv2.imdecode(img_array, cv2.IMREAD_COLOR) # BGR
32
- # return img
33
-
34
- # def annotate_bgr(results) -> np.ndarray:
35
- # # results[0].plot() возвращает BGR с нарисованными боксами
36
- # return results[0].plot()
37
-
38
- # def results_to_json(results):
39
- # # Конвертация результатов в чистые боксы/классы/скор
40
- # r = results[0]
41
- # boxes = r.boxes
42
- # out = []
43
- # if boxes is not None and len(boxes) > 0:
44
- # xyxy = boxes.xyxy.cpu().numpy() # (N,4)
45
- # conf = boxes.conf.cpu().numpy() # (N,)
46
- # cls = boxes.cls.cpu().numpy().astype(int) # (N,)
47
- # names = r.names
48
- # for i in range(len(xyxy)):
49
- # x1, y1, x2, y2 = xyxy[i].tolist()
50
- # out.append({
51
- # "bbox": [x1, y1, x2, y2],
52
- # "conf": float(conf[i]),
53
- # "class_id": int(cls[i]),
54
- # "class_name": names[int(cls[i])] if names else str(cls[i])
55
- # })
56
- # return {"detections": out}
57
-
58
- # @app.post("/predict")
59
- # async def predict(
60
- # file: UploadFile = File(...),
61
- # conf: float = Form(0.25),
62
- # iou: float = Form(0.45),
63
- # return_image: int = Form(1) # 1 = вернуть аннотированное изображение, 0 = вернуть JSON боксов
64
- # ):
65
- # data = await file.read()
66
- # bgr = read_image_to_bgr(data)
67
- # if bgr is None:
68
- # return JSONResponse({"error": "Invalid image"}, status_code=400)
69
-
70
- # # Инференс (без трекинга — кадры независимы; для трекинга можно persist и tracker)
71
- # results = model.predict(
72
- # source=bgr,
73
- # conf=conf,
74
- # iou=iou,
75
- # imgsz=640,
76
- # verbose=False
77
- # )
78
-
79
- # if return_image == 1:
80
- # annotated = annotate_bgr(results) # BGR
81
- # # Кодируем в JPEG для отправки
82
- # ok, buf = cv2.imencode(".jpg", annotated)
83
- # if not ok:
84
- # return JSONResponse({"error": "Encode failed"}, status_code=500)
85
- # return Response(content=buf.tobytes(), media_type="image/jpeg")
86
- # else:
87
- # return JSONResponse(results_to_json(results))
88
-
89
-
90
-
91
-
92
-
93
-
94
-
95
-
96
-
97
-
98
-
99
  from fastapi import FastAPI, UploadFile, File, Form
100
  from fastapi.responses import JSONResponse, Response, FileResponse
101
  from fastapi.middleware.cors import CORSMiddleware
@@ -106,7 +8,7 @@ import numpy as np
106
 
107
  app = FastAPI()
108
 
109
- # Разрешаем фронту обращаться к API
110
  app.add_middleware(
111
  CORSMiddleware,
112
  allow_origins=["*"],
@@ -124,21 +26,24 @@ def root():
124
  return FileResponse("index.html")
125
 
126
  def read_image_to_bgr(file_bytes: bytes) -> np.ndarray:
 
127
  img_array = np.frombuffer(file_bytes, dtype=np.uint8)
128
- img = cv2.imdecode(img_array, cv2.IMREAD_COLOR)
129
  return img
130
 
131
  def annotate_bgr(results) -> np.ndarray:
 
132
  return results[0].plot()
133
 
134
  def results_to_json(results):
 
135
  r = results[0]
136
  boxes = r.boxes
137
  out = []
138
  if boxes is not None and len(boxes) > 0:
139
- xyxy = boxes.xyxy.cpu().numpy()
140
- conf = boxes.conf.cpu().numpy()
141
- cls = boxes.cls.cpu().numpy().astype(int)
142
  names = r.names
143
  for i in range(len(xyxy)):
144
  x1, y1, x2, y2 = xyxy[i].tolist()
@@ -155,26 +60,38 @@ async def predict(
155
  file: UploadFile = File(...),
156
  conf: float = Form(0.25),
157
  iou: float = Form(0.45),
158
- return_image: int = Form(1)
159
  ):
160
  data = await file.read()
161
  bgr = read_image_to_bgr(data)
162
  if bgr is None:
163
  return JSONResponse({"error": "Invalid image"}, status_code=400)
164
 
 
165
  results = model.predict(
166
  source=bgr,
167
  conf=conf,
168
  iou=iou,
169
- imgsz=480, # меньше размер для скорости
170
  verbose=False
171
  )
172
 
173
  if return_image == 1:
174
- annotated = annotate_bgr(results)
175
- ok, buf = cv2.imencode(".jpg", annotated, [int(cv2.IMWRITE_JPEG_QUALITY), 95])
 
176
  if not ok:
177
  return JSONResponse({"error": "Encode failed"}, status_code=500)
178
  return Response(content=buf.tobytes(), media_type="image/jpeg")
179
  else:
180
  return JSONResponse(results_to_json(results))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  from fastapi import FastAPI, UploadFile, File, Form
2
  from fastapi.responses import JSONResponse, Response, FileResponse
3
  from fastapi.middleware.cors import CORSMiddleware
 
8
 
9
  app = FastAPI()
10
 
11
+ # Разрешаем вызовы из фронта того же Space
12
  app.add_middleware(
13
  CORSMiddleware,
14
  allow_origins=["*"],
 
26
  return FileResponse("index.html")
27
 
28
  def read_image_to_bgr(file_bytes: bytes) -> np.ndarray:
29
+ # Декод JPEG/PNG в BGR
30
  img_array = np.frombuffer(file_bytes, dtype=np.uint8)
31
+ img = cv2.imdecode(img_array, cv2.IMREAD_COLOR) # BGR
32
  return img
33
 
34
  def annotate_bgr(results) -> np.ndarray:
35
+ # results[0].plot() возвращает BGR с нарисованными боксами
36
  return results[0].plot()
37
 
38
  def results_to_json(results):
39
+ # Конвертация результатов в чистые боксы/классы/скор
40
  r = results[0]
41
  boxes = r.boxes
42
  out = []
43
  if boxes is not None and len(boxes) > 0:
44
+ xyxy = boxes.xyxy.cpu().numpy() # (N,4)
45
+ conf = boxes.conf.cpu().numpy() # (N,)
46
+ cls = boxes.cls.cpu().numpy().astype(int) # (N,)
47
  names = r.names
48
  for i in range(len(xyxy)):
49
  x1, y1, x2, y2 = xyxy[i].tolist()
 
60
  file: UploadFile = File(...),
61
  conf: float = Form(0.25),
62
  iou: float = Form(0.45),
63
+ return_image: int = Form(1) # 1 = вернуть аннотированное изображение, 0 = вернуть JSON боксов
64
  ):
65
  data = await file.read()
66
  bgr = read_image_to_bgr(data)
67
  if bgr is None:
68
  return JSONResponse({"error": "Invalid image"}, status_code=400)
69
 
70
+ # Инференс (без трекинга — кадры независимы; для трекинга можно persist и tracker)
71
  results = model.predict(
72
  source=bgr,
73
  conf=conf,
74
  iou=iou,
75
+ imgsz=640,
76
  verbose=False
77
  )
78
 
79
  if return_image == 1:
80
+ annotated = annotate_bgr(results) # BGR
81
+ # Кодируем в JPEG для отправки
82
+ ok, buf = cv2.imencode(".jpg", annotated)
83
  if not ok:
84
  return JSONResponse({"error": "Encode failed"}, status_code=500)
85
  return Response(content=buf.tobytes(), media_type="image/jpeg")
86
  else:
87
  return JSONResponse(results_to_json(results))
88
+
89
+
90
+
91
+
92
+
93
+
94
+
95
+
96
+
97
+