malavikapradeep2001 commited on
Commit
8bf4cb9
·
1 Parent(s): bda7ce7
Files changed (1) hide show
  1. backend/app.py +32 -40
backend/app.py CHANGED
@@ -488,27 +488,12 @@ async def predict(model_name: str = Form(...), file: UploadFile = File(...)):
488
  # Generate a brief AI interpretation using the Mistral client (if available)
489
  ai_interp = generate_mwt_summary(predicted_label, confidences, avg_confidence)
490
 
491
- # Save the input image to outputs/images so reports can embed it when no
492
- # annotated image is produced by the model (MWT is a classifier only).
493
- try:
494
- os.makedirs(IMAGES_DIR, exist_ok=True)
495
- input_filename = f"input_{uuid.uuid4().hex[:8]}.jpg"
496
- input_path = os.path.join(IMAGES_DIR, input_filename)
497
- # 'contents' was read earlier from the uploaded file
498
- with open(input_path, 'wb') as out_f:
499
- out_f.write(contents)
500
- input_image_url = f"/outputs/images/{input_filename}"
501
- except Exception as e:
502
- print(f"⚠️ Failed to save input image for MWT report embedding: {e}")
503
- input_image_url = ""
504
-
505
  return {
506
  "model_used": "MWT Classifier",
507
  "prediction": predicted_label,
508
  "confidence": confidences,
509
  "summary": {
510
  "ai_interpretation": ai_interp,
511
- "annotated_image_url": input_image_url,
512
  },
513
  }
514
 
@@ -848,7 +833,6 @@ async def generate_report(
848
  annotated_img = ai_summary.get('annotated_image_url') or report_data.get("analysis", {}).get("annotated_image_url") or ""
849
  annotated_img_full = ""
850
  annotated_img_local = None
851
- annotated_img_display_width = None
852
 
853
  if annotated_img:
854
  # If it's an outputs path served by StaticFiles, map to local file
@@ -873,30 +857,33 @@ async def generate_report(
873
  except Exception as e:
874
  print(f"⚠️ Failed to save uploaded input image for report: {e}")
875
 
876
- # If we have a local image file, compute a reasonable display width (px)
877
- try:
878
- if annotated_img_local and os.path.isfile(annotated_img_local):
879
- from PIL import Image as PILImageLocal
880
- with PILImageLocal.open(annotated_img_local) as im:
881
- img_w, img_h = im.size
882
- # Choose display width: cap at 800px, don't go below 300px for visibility
883
- annotated_img_display_width = max(300, min(img_w, 800))
884
- elif annotated_img_full and annotated_img_full.startswith('/outputs/'):
885
- # Map to local and attempt to open
886
- rel = annotated_img_full[len('/outputs/'):].lstrip('/')
887
- candidate = os.path.join(OUTPUT_DIR, rel)
888
- if os.path.isfile(candidate):
889
- from PIL import Image as PILImageLocal
890
- with PILImageLocal.open(candidate) as im:
891
- img_w, img_h = im.size
892
- annotated_img_display_width = max(300, min(img_w, 800))
893
- except Exception:
894
- annotated_img_display_width = None
895
-
896
  # Ensure annotated_img_full has a leading slash if it's a relative path
897
  if annotated_img_full and not annotated_img_full.startswith(('http://', 'https://')):
898
  annotated_img_full = annotated_img_full if annotated_img_full.startswith('/') else '/' + annotated_img_full
899
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
900
  # Now attempt to create the PDF (passing the local annotated image path
901
  # so the PDF writer can embed it). If annotation is remote or not
902
  # available, PDF creation will still proceed without the image.
@@ -984,9 +971,6 @@ async def generate_report(
984
  annotated_img_full = ''
985
  annotated_img = annotated_img_full
986
 
987
- # Prepare width attribute for the HTML img tag if available
988
- annotated_img_width_attr = f' width="{annotated_img_display_width}"' if annotated_img_display_width else ''
989
-
990
  download_pdf_btn = f'<a href="{pdf_url}" download style="text-decoration:none"><button class="btn-secondary">Download PDF</button></a>' if pdf_url else ''
991
 
992
  # Format generated time
@@ -1084,7 +1068,7 @@ async def generate_report(
1084
  </div>
1085
  </div>
1086
 
1087
- {'<div class="full"><div class="section-title">Annotated Analysis Image</div><img src="' + annotated_img_full + '" class="annotated-image" alt="Annotated Analysis Result"' + annotated_img_width_attr + ' /></div>' if annotated_img else ''}
1088
 
1089
  <div class="full">
1090
  <div class="section-title">Doctor\'s Notes</div>
@@ -1124,6 +1108,14 @@ async def generate_report(
1124
  with open(report_html, "w", encoding="utf-8") as f:
1125
  f.write(html_content)
1126
 
 
 
 
 
 
 
 
 
1127
  return {
1128
  "report_id": report_id,
1129
  "json_url": json_url,
 
488
  # Generate a brief AI interpretation using the Mistral client (if available)
489
  ai_interp = generate_mwt_summary(predicted_label, confidences, avg_confidence)
490
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
491
  return {
492
  "model_used": "MWT Classifier",
493
  "prediction": predicted_label,
494
  "confidence": confidences,
495
  "summary": {
496
  "ai_interpretation": ai_interp,
 
497
  },
498
  }
499
 
 
833
  annotated_img = ai_summary.get('annotated_image_url') or report_data.get("analysis", {}).get("annotated_image_url") or ""
834
  annotated_img_full = ""
835
  annotated_img_local = None
 
836
 
837
  if annotated_img:
838
  # If it's an outputs path served by StaticFiles, map to local file
 
857
  except Exception as e:
858
  print(f"⚠️ Failed to save uploaded input image for report: {e}")
859
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
860
  # Ensure annotated_img_full has a leading slash if it's a relative path
861
  if annotated_img_full and not annotated_img_full.startswith(('http://', 'https://')):
862
  annotated_img_full = annotated_img_full if annotated_img_full.startswith('/') else '/' + annotated_img_full
863
 
864
+ # If we have a local annotated image but it's stored in the shared images folder
865
+ # (e.g. /outputs/images/...), copy it into this report's folder so the HTML/PDF
866
+ # can reference the image relative to the report directory. This also makes the
867
+ # image visible when opening report.html directly from disk (file://).
868
+ try:
869
+ if annotated_img_local:
870
+ annotated_img_local_abs = os.path.abspath(annotated_img_local)
871
+ report_dir_abs = os.path.abspath(report_dir)
872
+ # If the image is not already in the report directory, copy it there
873
+ if not os.path.commonpath([annotated_img_local_abs, report_dir_abs]) == report_dir_abs:
874
+ src_basename = os.path.basename(annotated_img_local_abs)
875
+ dest_name = f"annotated_{src_basename}"
876
+ dest_path = os.path.join(report_dir, dest_name)
877
+ try:
878
+ shutil.copy2(annotated_img_local_abs, dest_path)
879
+ annotated_img_local = dest_path
880
+ annotated_img_full = f"/outputs/reports/{report_id}/{dest_name}"
881
+ except Exception as e:
882
+ # If copy fails, keep using the original annotated_img_full (may be served by StaticFiles)
883
+ print(f"⚠️ Failed to copy annotated image into report folder: {e}")
884
+ except Exception:
885
+ pass
886
+
887
  # Now attempt to create the PDF (passing the local annotated image path
888
  # so the PDF writer can embed it). If annotation is remote or not
889
  # available, PDF creation will still proceed without the image.
 
971
  annotated_img_full = ''
972
  annotated_img = annotated_img_full
973
 
 
 
 
974
  download_pdf_btn = f'<a href="{pdf_url}" download style="text-decoration:none"><button class="btn-secondary">Download PDF</button></a>' if pdf_url else ''
975
 
976
  # Format generated time
 
1068
  </div>
1069
  </div>
1070
 
1071
+ {'<div class="full"><div class="section-title">Annotated Analysis Image</div><img src="' + annotated_img_full + '" class="annotated-image" alt="Annotated Analysis Result" /></div>' if annotated_img else ''}
1072
 
1073
  <div class="full">
1074
  <div class="section-title">Doctor\'s Notes</div>
 
1108
  with open(report_html, "w", encoding="utf-8") as f:
1109
  f.write(html_content)
1110
 
1111
+ # Update report.json to include the resolved annotated image url so callers can find it
1112
+ try:
1113
+ report_data['analysis']['annotated_image_url'] = annotated_img_full or ''
1114
+ with open(report_json, 'w', encoding='utf-8') as f:
1115
+ json.dump(report_data, f, indent=2, ensure_ascii=False)
1116
+ except Exception as e:
1117
+ print(f"⚠️ Failed to update report.json with annotated image url: {e}")
1118
+
1119
  return {
1120
  "report_id": report_id,
1121
  "json_url": json_url,