Paradise151 commited on
Commit
7be74ed
·
verified ·
1 Parent(s): 6e55f94

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +109 -14
app.py CHANGED
@@ -1,3 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  from fastapi import FastAPI, UploadFile, File, Form
2
  from fastapi.responses import JSONResponse, Response, FileResponse
3
  from fastapi.middleware.cors import CORSMiddleware
@@ -8,7 +108,7 @@ import numpy as np
8
 
9
  app = FastAPI()
10
 
11
- # Разрешаем вызовы из фронта того же Space
12
  app.add_middleware(
13
  CORSMiddleware,
14
  allow_origins=["*"],
@@ -26,24 +126,21 @@ 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()
@@ -60,26 +157,24 @@ 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")
 
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
+
100
+
101
  from fastapi import FastAPI, UploadFile, File, Form
102
  from fastapi.responses import JSONResponse, Response, FileResponse
103
  from fastapi.middleware.cors import CORSMiddleware
 
108
 
109
  app = FastAPI()
110
 
111
+ # Разрешаем фронту обращаться к API
112
  app.add_middleware(
113
  CORSMiddleware,
114
  allow_origins=["*"],
 
126
  return FileResponse("index.html")
127
 
128
  def read_image_to_bgr(file_bytes: bytes) -> np.ndarray:
 
129
  img_array = np.frombuffer(file_bytes, dtype=np.uint8)
130
+ img = cv2.imdecode(img_array, cv2.IMREAD_COLOR)
131
  return img
132
 
133
  def annotate_bgr(results) -> np.ndarray:
 
134
  return results[0].plot()
135
 
136
  def results_to_json(results):
 
137
  r = results[0]
138
  boxes = r.boxes
139
  out = []
140
  if boxes is not None and len(boxes) > 0:
141
+ xyxy = boxes.xyxy.cpu().numpy()
142
+ conf = boxes.conf.cpu().numpy()
143
+ cls = boxes.cls.cpu().numpy().astype(int)
144
  names = r.names
145
  for i in range(len(xyxy)):
146
  x1, y1, x2, y2 = xyxy[i].tolist()
 
157
  file: UploadFile = File(...),
158
  conf: float = Form(0.25),
159
  iou: float = Form(0.45),
160
+ return_image: int = Form(1)
161
  ):
162
  data = await file.read()
163
  bgr = read_image_to_bgr(data)
164
  if bgr is None:
165
  return JSONResponse({"error": "Invalid image"}, status_code=400)
166
 
 
167
  results = model.predict(
168
  source=bgr,
169
  conf=conf,
170
  iou=iou,
171
+ imgsz=480, # меньше размер для скорости
172
  verbose=False
173
  )
174
 
175
  if return_image == 1:
176
+ annotated = annotate_bgr(results)
177
+ ok, buf = cv2.imencode(".jpg", annotated, [int(cv2.IMWRITE_JPEG_QUALITY), 95])
 
178
  if not ok:
179
  return JSONResponse({"error": "Encode failed"}, status_code=500)
180
  return Response(content=buf.tobytes(), media_type="image/jpeg")