joao-dutra commited on
Commit
4cf18e7
·
verified ·
1 Parent(s): db9e655
Files changed (1) hide show
  1. app.py +1 -184
app.py CHANGED
@@ -22,13 +22,6 @@ def process_image_bytes(img_bytes: bytes):
22
  # lê bytes em numpy + OpenCV
23
  nparr = np.frombuffer(img_bytes, np.uint8)
24
  img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
25
- lab = cv.cvtColor(img, cv.COLOR_BGR2LAB)
26
- l, a, b = cv.split(lab)
27
- clahe = cv.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
28
- l_clahe = clahe.apply(l)
29
- lab_clahe = cv.merge([l_clahe, a, b])
30
- img = cv.cvtColor(lab_clahe, cv.COLOR_LAB2BGR)
31
-
32
  if img is None:
33
  raise ValueError("Não foi possível decodificar a imagem.")
34
 
@@ -108,180 +101,4 @@ async def analyze(file: UploadFile = File(...)):
108
 
109
  @app.get("/")
110
  def read_root():
111
- return {"status": "ok"}
112
-
113
- # app.py
114
- # from fastapi import FastAPI, File, UploadFile, HTTPException, Query
115
- # from fastapi.middleware.cors import CORSMiddleware
116
- # from fastapi.responses import JSONResponse
117
- # import numpy as np
118
- # import cv2
119
- # import base64
120
- # from typing import List, Dict
121
-
122
- # app = FastAPI(title="Detector de Corrosão Branca (multi-objetos)")
123
-
124
- # # CORS (ajuste allow_origins em produção)
125
- # app.add_middleware(
126
- # CORSMiddleware,
127
- # allow_origins=["*"],
128
- # allow_credentials=True,
129
- # allow_methods=["*"],
130
- # allow_headers=["*"],
131
- # )
132
-
133
- # def to_data_uri_from_rgb(img_rgb: np.ndarray) -> str | None:
134
- # """Recebe imagem RGB uint8 e retorna data URI PNG."""
135
- # if img_rgb is None:
136
- # return None
137
- # bgr = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2BGR)
138
- # ok, buf = cv2.imencode(".png", bgr)
139
- # if not ok:
140
- # return None
141
- # b64 = base64.b64encode(buf.tobytes()).decode("ascii")
142
- # return f"data:image/png;base64,{b64}"
143
-
144
- # def process_one_object(img_bgr: np.ndarray, obj_mask: np.ndarray) -> Dict:
145
- # """
146
- # Calcula métricas e imagens para um único objeto (parafuso).
147
- # - img_bgr: imagem original BGR
148
- # - obj_mask: máscara binária 0/255 do objeto (mesmo tamanho da imagem)
149
- # """
150
- # # isolar objeto em BGR e converter para RGB p/ visualização
151
- # isolated = cv2.bitwise_and(img_bgr, img_bgr, mask=obj_mask)
152
- # isolated_rgb = cv2.cvtColor(isolated, cv2.COLOR_BGR2RGB)
153
-
154
- # # corrosão branca: S baixo, V alto (em HSV)
155
- # hsv_iso = cv2.cvtColor(isolated, cv2.COLOR_BGR2HSV)
156
- # lower_white = np.array([0, 0, 180], dtype=np.uint8)
157
- # upper_white = np.array([180, 60, 255], dtype=np.uint8)
158
- # mask_white = cv2.inRange(hsv_iso, lower_white, upper_white)
159
- # mask_white = cv2.bitwise_and(mask_white, mask_white, mask=obj_mask)
160
-
161
- # total_pixels = int(np.count_nonzero(obj_mask))
162
- # corrosion_pixels = int(np.count_nonzero(mask_white))
163
- # percent = (corrosion_pixels / max(1, total_pixels)) * 100.0
164
-
165
- # # visual da corrosão em cima do isolado
166
- # corrosion_vis = cv2.bitwise_and(isolated_rgb, isolated_rgb, mask=mask_white)
167
-
168
- # return {
169
- # "total_pixels": total_pixels,
170
- # "corrosion_pixels": corrosion_pixels,
171
- # "percent": round(percent, 4),
172
- # "isolated_image": to_data_uri_from_rgb(isolated_rgb),
173
- # "corrosion_image": to_data_uri_from_rgb(corrosion_vis),
174
- # }
175
-
176
- # def process_image_bytes_multi(img_bytes: bytes, min_area: int, max_items: int, sort: str):
177
- # # decodifica
178
- # nparr = np.frombuffer(img_bytes, np.uint8)
179
- # img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
180
- # if img is None:
181
- # raise ValueError("Não foi possível decodificar a imagem.")
182
-
183
- # h, w = img.shape[:2]
184
-
185
- # # HSV + fundo preto
186
- # hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
187
- # lower_bg = np.array([0, 0, 0], dtype=np.uint8)
188
- # upper_bg = np.array([180, 255, 50], dtype=np.uint8)
189
- # mask_bg = cv2.inRange(hsv, lower_bg, upper_bg)
190
- # mask_obj = cv2.bitwise_not(mask_bg)
191
-
192
- # # limpeza morfológica
193
- # kernel = np.ones((5, 5), np.uint8)
194
- # mask_obj = cv2.morphologyEx(mask_obj, cv2.MORPH_OPEN, kernel)
195
- # mask_obj = cv2.morphologyEx(mask_obj, cv2.MORPH_CLOSE, kernel)
196
-
197
- # # contornos externos
198
- # contours, _ = cv2.findContours(mask_obj, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
199
- # if not contours:
200
- # return {"error": "Nenhum objeto detectado", "items": []}
201
-
202
- # # filtra por área
203
- # candidates = []
204
- # for c in contours:
205
- # area = cv2.contourArea(c)
206
- # if area >= max(1, min_area):
207
- # x, y, ww, hh = cv2.boundingRect(c)
208
- # candidates.append({"contour": c, "area": area, "bbox": (x, y, ww, hh)})
209
-
210
- # if not candidates:
211
- # return {"error": "Somente ruído encontrado abaixo do min_area", "items": []}
212
-
213
- # # ordenação
214
- # if sort == "area":
215
- # candidates.sort(key=lambda d: d["area"], reverse=True)
216
- # else: # "x" (esquerda -> direita)
217
- # candidates.sort(key=lambda d: d["bbox"][0])
218
-
219
- # candidates = candidates[:max_items]
220
-
221
- # # imagem de overview (RGB) p/ desenhar anotações
222
- # overview = cv2.cvtColor(img.copy(), cv2.COLOR_BGR2RGB)
223
-
224
- # items: List[Dict] = []
225
- # total_pixels_sum = 0
226
- # corrosion_pixels_sum = 0
227
-
228
- # for idx, obj in enumerate(candidates, 1):
229
- # c = obj["contour"]
230
- # x, y, ww, hh = obj["bbox"]
231
-
232
- # # máscara do objeto atual
233
- # obj_mask = np.zeros((h, w), dtype=np.uint8)
234
- # cv2.drawContours(obj_mask, [c], -1, 255, cv2.FILLED)
235
-
236
- # # métricas e imagens do objeto
237
- # r = process_one_object(img, obj_mask)
238
-
239
- # # acumula totais
240
- # total_pixels_sum += r["total_pixels"]
241
- # corrosion_pixels_sum += r["corrosion_pixels"]
242
-
243
- # # desenha no overview
244
- # cv2.rectangle(overview, (x, y), (x + ww, y + hh), (0, 255, 0), 2)
245
- # label = f"#{idx} {r['percent']:.2f}%"
246
- # cv2.putText(overview, label, (x, max(0, y - 6)),
247
- # cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 50, 50), 2, cv2.LINE_AA)
248
-
249
- # items.append({
250
- # "id": idx,
251
- # "bbox": {"x": x, "y": y, "w": ww, "h": hh},
252
- # "area_pixels": int(obj["area"]),
253
- # **r, # total_pixels, corrosion_pixels, percent, images...
254
- # })
255
-
256
- # overall_percent = (corrosion_pixels_sum / max(1, total_pixels_sum)) * 100.0
257
-
258
- # # adiciona overview
259
- # overview_data_uri = to_data_uri_from_rgb(overview)
260
-
261
- # return {
262
- # "total_objects": len(items),
263
- # "items": items,
264
- # "total_pixels": int(total_pixels_sum),
265
- # "total_corrosion_pixels": int(corrosion_pixels_sum),
266
- # "overall_percent": round(overall_percent, 4),
267
- # "overview_image": overview_data_uri,
268
- # }
269
-
270
- # @app.post("/analyze")
271
- # async def analyze(
272
- # file: UploadFile = File(...),
273
- # min_area: int = Query(1500, ge=1, description="Área mínima do objeto (px)"),
274
- # max_items: int = Query(20, ge=1, le=200, description="Limite de objetos"),
275
- # sort: str = Query("x", pattern="^(x|area)$", description="Ordenação: x|area"),
276
- # ):
277
- # content = await file.read()
278
- # try:
279
- # result = process_image_bytes_multi(content, min_area=min_area, max_items=max_items, sort=sort)
280
- # except ValueError as e:
281
- # raise HTTPException(status_code=400, detail=str(e))
282
- # return JSONResponse(result)
283
-
284
- # @app.get("/")
285
- # def read_root():
286
- # return {"status": "ok"}
287
-
 
22
  # lê bytes em numpy + OpenCV
23
  nparr = np.frombuffer(img_bytes, np.uint8)
24
  img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
 
 
 
 
 
 
 
25
  if img is None:
26
  raise ValueError("Não foi possível decodificar a imagem.")
27
 
 
101
 
102
  @app.get("/")
103
  def read_root():
104
+ return {"status": "ok"}