sairamv1 commited on
Commit
34dd9a6
Β·
verified Β·
1 Parent(s): 5ed9488

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +78 -12
app.py CHANGED
@@ -180,7 +180,11 @@ async def analyze(file: UploadFile = File(...)):
180
  tmp_path = tmp.name
181
 
182
  result_json = call_roboflow_api(tmp_path)
183
- logger.info(f"πŸ” ROBOFLOW FULL RESPONSE: {result_json}") # ADD THIS
 
 
 
 
184
 
185
  except Exception as e:
186
  logger.error(f"Roboflow workflow error: {e}")
@@ -191,21 +195,73 @@ async def analyze(file: UploadFile = File(...)):
191
  os.remove(tmp_path)
192
 
193
  # ─── Parse detections ────────────────────────────────────────────────────
 
 
194
  try:
195
- if isinstance(result_json, list):
196
- output_data = result_json[0].get("outputs", {})
197
- else:
198
- output_data = result_json.get("outputs", [{}])[0] if isinstance(result_json.get("outputs"), list) else result_json.get("outputs", {})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
199
 
200
- predictions = output_data.get("predictions", [])
201
  if isinstance(predictions, dict):
202
- predictions = predictions.get("predictions", [])
 
 
 
 
 
 
 
 
 
 
203
  except Exception as e:
204
- logger.warning(f"Response parsing issue: {e}")
205
- logger.warning(f"Raw response: {result_json}")
206
  predictions = []
207
 
208
- if not predictions:
 
209
  return {
210
  "status": "success",
211
  "tooth_count": 0,
@@ -213,6 +269,8 @@ async def analyze(file: UploadFile = File(...)):
213
  "message": "No teeth detected in image"
214
  }
215
 
 
 
216
  # ─── Process crops ───────────────────────────────────────────────────────
217
  batch_images = []
218
  metadata = []
@@ -252,8 +310,10 @@ async def analyze(file: UploadFile = File(...)):
252
  batch_images.append(final_img)
253
  metadata.append({"id": i, "box": [x1, y1, x2, y2]})
254
 
 
 
255
  except Exception as e:
256
- logger.warning(f"Skipping detection {i} due to error: {e}")
257
  continue
258
 
259
  if not batch_images:
@@ -264,13 +324,17 @@ async def analyze(file: UploadFile = File(...)):
264
  "message": "No valid tooth crops extracted"
265
  }
266
 
 
 
267
  # ─── Model inference ─────────────────────────────────────────────────────
268
  try:
269
  batch_array = np.array(batch_images)
 
270
  reconstructions = MODEL.predict(batch_array, verbose=0)
271
  errors = np.mean(np.abs(batch_array - reconstructions), axis=(1, 2, 3))
 
272
  except Exception as e:
273
- logger.error(f"Inference error: {e}")
274
  raise HTTPException(status_code=500, detail="Model inference failed")
275
 
276
  # ─── Format results ──────────────────────────────────────────────────────
@@ -285,6 +349,8 @@ async def analyze(file: UploadFile = File(...)):
285
  "confidence": "high" if score_val > THRESHOLD * 1.5 else "medium" if score_val > THRESHOLD else "low"
286
  })
287
 
 
 
288
  return {
289
  "status": "success",
290
  "tooth_count": len(results),
 
180
  tmp_path = tmp.name
181
 
182
  result_json = call_roboflow_api(tmp_path)
183
+
184
+ # ─── DEBUG: Log what Roboflow returns ────────────────────────────────
185
+ logger.info(f"πŸ” Response Type: {type(result_json)}")
186
+ logger.info(f"πŸ” Response Keys: {result_json.keys() if isinstance(result_json, dict) else 'Not a dict'}")
187
+ logger.info(f"πŸ” Full Response: {result_json}")
188
 
189
  except Exception as e:
190
  logger.error(f"Roboflow workflow error: {e}")
 
195
  os.remove(tmp_path)
196
 
197
  # ─── Parse detections ────────────────────────────────────────────────────
198
+ predictions = []
199
+
200
  try:
201
+ # Handle different response structures
202
+ if isinstance(result_json, list) and len(result_json) > 0:
203
+ # Response is a list
204
+ first_item = result_json[0]
205
+ logger.info(f"πŸ” First item keys: {first_item.keys() if isinstance(first_item, dict) else 'Not dict'}")
206
+
207
+ if "outputs" in first_item:
208
+ outputs = first_item["outputs"]
209
+ logger.info(f"πŸ” Outputs type: {type(outputs)}")
210
+ logger.info(f"πŸ” Outputs content: {outputs}")
211
+
212
+ # Try to get predictions from outputs
213
+ if isinstance(outputs, dict):
214
+ predictions = outputs.get("predictions", outputs.get("image", {}).get("predictions", []))
215
+ elif isinstance(outputs, list):
216
+ predictions = outputs
217
+
218
+ elif isinstance(result_json, dict):
219
+ # Response is a dict
220
+ logger.info(f"πŸ” Dict keys: {list(result_json.keys())}")
221
+
222
+ # Try multiple paths
223
+ if "outputs" in result_json:
224
+ outputs = result_json["outputs"]
225
+ logger.info(f"πŸ” Found outputs, type: {type(outputs)}")
226
+
227
+ if isinstance(outputs, list) and len(outputs) > 0:
228
+ output_data = outputs[0]
229
+ elif isinstance(outputs, dict):
230
+ output_data = outputs
231
+ else:
232
+ output_data = {}
233
+
234
+ logger.info(f"πŸ” Output data: {output_data}")
235
+
236
+ # Extract predictions
237
+ if isinstance(output_data, dict):
238
+ predictions = output_data.get("predictions", [])
239
+
240
+ elif "predictions" in result_json:
241
+ predictions = result_json["predictions"]
242
+
243
+ elif "image" in result_json:
244
+ predictions = result_json["image"].get("predictions", [])
245
 
246
+ # Handle nested predictions dict
247
  if isinstance(predictions, dict):
248
+ logger.info(f"πŸ” Predictions is dict with keys: {predictions.keys()}")
249
+ if "predictions" in predictions:
250
+ predictions = predictions["predictions"]
251
+ elif "image" in predictions:
252
+ predictions = predictions["image"].get("predictions", [])
253
+
254
+ logger.info(f"πŸ” Final predictions type: {type(predictions)}")
255
+ logger.info(f"πŸ” Final predictions length: {len(predictions) if isinstance(predictions, list) else 'Not a list'}")
256
+ if isinstance(predictions, list) and len(predictions) > 0:
257
+ logger.info(f"πŸ” First prediction sample: {predictions[0]}")
258
+
259
  except Exception as e:
260
+ logger.error(f"❌ Parsing error: {e}", exc_info=True)
 
261
  predictions = []
262
 
263
+ if not predictions or (isinstance(predictions, list) and len(predictions) == 0):
264
+ logger.warning("⚠️ No predictions found after parsing")
265
  return {
266
  "status": "success",
267
  "tooth_count": 0,
 
269
  "message": "No teeth detected in image"
270
  }
271
 
272
+ logger.info(f"βœ… Found {len(predictions)} teeth detections")
273
+
274
  # ─── Process crops ───────────────────────────────────────────────────────
275
  batch_images = []
276
  metadata = []
 
310
  batch_images.append(final_img)
311
  metadata.append({"id": i, "box": [x1, y1, x2, y2]})
312
 
313
+ logger.info(f"βœ… Processed tooth {i}: bbox=[{x1},{y1},{x2},{y2}]")
314
+
315
  except Exception as e:
316
+ logger.warning(f"⚠️ Skipping detection {i} due to error: {e}")
317
  continue
318
 
319
  if not batch_images:
 
324
  "message": "No valid tooth crops extracted"
325
  }
326
 
327
+ logger.info(f"βœ… Prepared {len(batch_images)} tooth images for inference")
328
+
329
  # ─── Model inference ─────────────────────────────────────────────────────
330
  try:
331
  batch_array = np.array(batch_images)
332
+ logger.info(f"πŸ”„ Running inference on batch shape: {batch_array.shape}")
333
  reconstructions = MODEL.predict(batch_array, verbose=0)
334
  errors = np.mean(np.abs(batch_array - reconstructions), axis=(1, 2, 3))
335
+ logger.info(f"βœ… Inference complete. Scores: {errors}")
336
  except Exception as e:
337
+ logger.error(f"❌ Inference error: {e}")
338
  raise HTTPException(status_code=500, detail="Model inference failed")
339
 
340
  # ─── Format results ──────────────────────────────────────────────────────
 
349
  "confidence": "high" if score_val > THRESHOLD * 1.5 else "medium" if score_val > THRESHOLD else "low"
350
  })
351
 
352
+ logger.info(f"πŸŽ‰ Analysis complete: {len(results)} teeth analyzed")
353
+
354
  return {
355
  "status": "success",
356
  "tooth_count": len(results),