malavikapradeep2001 commited on
Commit
3f3aedd
·
1 Parent(s): ac76f6e
Files changed (1) hide show
  1. backend/app.py +36 -18
backend/app.py CHANGED
@@ -509,6 +509,8 @@ async def predict(model_name: str = Form(...), file: UploadFile = File(...)):
509
  content={"error": "CIN classifier not available on server."},
510
  status_code=503,
511
  )
 
 
512
  nparr = np.frombuffer(contents, np.uint8)
513
  img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
514
  results = yolo_colposcopy.predict(source=img, conf=0.7, save=False, verbose=False)
@@ -519,36 +521,52 @@ async def predict(model_name: str = Form(...), file: UploadFile = File(...)):
519
  crop = img[y1:y2, x1:x2]
520
  crop = cv2.resize(crop, (224, 224))
521
  img_t = transform(crop).unsqueeze(0).to(device)
 
 
522
  f50 = extract_cbf_features(resnet50_blocks, img_t)
523
  f101 = extract_cbf_features(resnet101_blocks, img_t)
524
  f152 = extract_cbf_features(resnet152_blocks, img_t)
525
  features = np.concatenate([f50, f101, f152]).reshape(1, -1)
 
 
526
  X_scaled = MinMaxScaler().fit_transform(features)
527
- pred = clf.predict(X_scaled)[0]
528
- proba = clf.predict_proba(X_scaled)[0]
529
- # Get actual number of classes from model output
530
- classes = ["Low-grade", "High-grade"] # Binary CIN classification
531
- predicted_label = classes[pred]
532
- confidences = {classes[i]: float(proba[i]) for i in range(len(classes))}
533
-
534
- # Map to more detailed classification based on confidence
535
- if predicted_label == "High-grade" and confidences["High-grade"] > 0.8:
536
- detailed_class = "CIN3"
537
- elif predicted_label == "High-grade":
538
- detailed_class = "CIN2"
539
- else:
540
- detailed_class = "CIN1"
541
 
542
- # Average / primary confidence for display
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
543
  avg_confidence = float(np.max(proba)) * 100
544
 
545
- # Generate a brief AI interpretation using the Mistral client (if available)
546
  ai_interp = generate_cin_summary(predicted_label, confidences, avg_confidence)
547
 
548
  return {
549
  "model_used": "CIN Classifier",
550
- "prediction": detailed_class,
551
- "grade": predicted_label,
552
  "confidence": confidences,
553
  "summary": {
554
  "avg_confidence": round(avg_confidence, 2),
 
509
  content={"error": "CIN classifier not available on server."},
510
  status_code=503,
511
  )
512
+
513
+ # Decode uploaded image and run colposcopy detector
514
  nparr = np.frombuffer(contents, np.uint8)
515
  img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
516
  results = yolo_colposcopy.predict(source=img, conf=0.7, save=False, verbose=False)
 
521
  crop = img[y1:y2, x1:x2]
522
  crop = cv2.resize(crop, (224, 224))
523
  img_t = transform(crop).unsqueeze(0).to(device)
524
+
525
+ # Extract features from multiple ResNet backbones
526
  f50 = extract_cbf_features(resnet50_blocks, img_t)
527
  f101 = extract_cbf_features(resnet101_blocks, img_t)
528
  f152 = extract_cbf_features(resnet152_blocks, img_t)
529
  features = np.concatenate([f50, f101, f152]).reshape(1, -1)
530
+
531
+ # Scale and predict
532
  X_scaled = MinMaxScaler().fit_transform(features)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
533
 
534
+ # Ensure classifier supports probability outputs
535
+ try:
536
+ proba = clf.predict_proba(X_scaled)[0]
537
+ except Exception as e:
538
+ return JSONResponse(
539
+ content={"error": "CIN classifier does not support probability estimates (predict_proba)."},
540
+ status_code=503,
541
+ )
542
+
543
+ num_classes = int(len(proba))
544
+
545
+ # Expecting a 3-class CIN classifier. If not 3, return a clear error so the user can supply a 3-class model.
546
+ if num_classes != 3:
547
+ return JSONResponse(
548
+ content={
549
+ "error": "CIN classifier must output 3-class probabilities (CIN1, CIN2, CIN3).",
550
+ "detected_num_classes": num_classes,
551
+ },
552
+ status_code=503,
553
+ )
554
+
555
+ # Map probabilities to explicit CIN labels (CIN1, CIN2, CIN3)
556
+ classes = ["CIN1", "CIN2", "CIN3"]
557
+ confidences = {classes[i]: float(proba[i]) for i in range(3)}
558
+
559
+ # Primary prediction is the class with the highest probability
560
+ predicted_idx = int(np.argmax(proba))
561
+ predicted_label = classes[predicted_idx]
562
  avg_confidence = float(np.max(proba)) * 100
563
 
564
+ # Generate AI interpretation using Mistral client (if available)
565
  ai_interp = generate_cin_summary(predicted_label, confidences, avg_confidence)
566
 
567
  return {
568
  "model_used": "CIN Classifier",
569
+ "prediction": predicted_label,
 
570
  "confidence": confidences,
571
  "summary": {
572
  "avg_confidence": round(avg_confidence, 2),