abbhy123ghh commited on
Commit
61a263b
·
verified ·
1 Parent(s): a91e541

Update app_fullbody_pretrained.py

Browse files
Files changed (1) hide show
  1. app_fullbody_pretrained.py +29 -48
app_fullbody_pretrained.py CHANGED
@@ -663,15 +663,16 @@ async def generate_3d_local(file: UploadFile = File(...)):
663
  # ============================================================
664
  # ✅ MONAI + PyVista 3D Full-Body Visualization (Final HF Safe)
665
  # ============================================================
 
666
  from fastapi import UploadFile, File
667
  from fastapi.responses import JSONResponse
668
- import io, os, numpy as np, torch, imageio
669
  from PIL import Image
670
  from monai.networks.nets import UNet
671
  import torch.nn.functional as F
672
- import pyvista
673
- from pyvista import Plotter, start_xvfb
674
- import vtk
675
 
676
  HF_SPACE_URL = os.getenv("HF_SPACE_URL", "https://abbhy123ghh-x-ray-analysis.hf.space").rstrip("/")
677
 
@@ -695,9 +696,7 @@ async def generate_3d_monai(file: UploadFile = File(...)):
695
  volume = np.expand_dims(volume, axis=0) # [1, D, H, W]
696
 
697
  # --- Step 3: MONAI lightweight 3D UNet (shallow for CPU) ---
698
- x = torch.tensor(volume, dtype=torch.float32).unsqueeze(0) # [1,1,D,H,W]
699
-
700
- # pad to multiples of 16 for shape-safe inference
701
  pad_d = (16 - x.shape[2] % 16) % 16
702
  pad_h = (16 - x.shape[3] % 16) % 16
703
  pad_w = (16 - x.shape[4] % 16) % 16
@@ -719,54 +718,39 @@ async def generate_3d_monai(file: UploadFile = File(...)):
719
  seg = (seg - seg.min()) / (seg.max() - seg.min() + 1e-8)
720
  seg = np.clip(seg * 255, 0, 255).astype(np.uint8)
721
 
722
- # --- Step 4: Create volumetric grid safely (ImageData, no UniformGrid) ---
723
- try:
724
- grid = pyvista.ImageData()
725
- except Exception:
726
- grid = vtk.vtkImageData()
727
-
728
- dims = np.array(seg.shape) + 1
729
- try:
730
- grid.dimensions = dims
731
- except Exception:
732
- grid.SetDimensions(int(dims[2]), int(dims[1]), int(dims[0]))
733
-
734
  grid.spacing = (1, 1, 1)
735
  grid.origin = (0, 0, 0)
 
736
 
737
- try:
738
- grid.cell_data["values"] = seg.flatten(order="F")
739
- except Exception:
740
- # fallback for vtk.vtkImageData
741
- arr_flat = seg.flatten(order="F")
742
- for i, val in enumerate(arr_flat):
743
- grid.GetPointData().GetScalars().SetTuple1(i, int(val))
744
-
745
- pv_grid = pyvista.wrap(grid)
746
-
747
- # --- Step 5: Render rotating 3D volume (headless safe mode) ---
748
- try:
749
- start_xvfb() # enable virtual framebuffer if available
750
- except OSError:
751
- print("⚠️ Xvfb not available — running headless fallback mode.")
752
-
753
- os.environ["PYVISTA_OFF_SCREEN"] = "true"
754
-
755
- plotter = Plotter(off_screen=True)
756
  plotter.add_volume(
757
- pv_grid,
758
  cmap="bone",
759
  opacity="sigmoid_5",
760
  shade=True,
 
 
 
761
  )
762
  plotter.set_background("black")
763
- plotter.enable_eye_dome_lighting()
 
 
 
 
 
 
 
764
 
765
  frames = []
766
  for angle in range(0, 360, 5):
767
  plotter.camera_position = [
768
- (seg.shape[2] * 2, 0, seg.shape[0] / 2),
769
- (seg.shape[2] / 2, seg.shape[1] / 2, seg.shape[0] / 2),
770
  (0, 0, 1),
771
  ]
772
  plotter.camera.azimuth = angle
@@ -774,14 +758,10 @@ async def generate_3d_monai(file: UploadFile = File(...)):
774
  frames.append(img_frame)
775
  plotter.close()
776
 
777
- # --- Step 6: Save rotating video ---
778
  os.makedirs("static", exist_ok=True)
779
  out_path = "static/xray_monai_3d_fullbody.mp4"
780
-
781
- writer = imageio.get_writer(out_path, fps=12, codec="libx264", quality=8)
782
- for f in frames:
783
- writer.append_data(f)
784
- writer.close()
785
 
786
  return JSONResponse({
787
  "ok": True,
@@ -793,6 +773,7 @@ async def generate_3d_monai(file: UploadFile = File(...)):
793
  import traceback; traceback.print_exc()
794
  return JSONResponse({"error": str(e)}, status_code=500)
795
 
 
796
 
797
 
798
 
 
663
  # ============================================================
664
  # ✅ MONAI + PyVista 3D Full-Body Visualization (Final HF Safe)
665
  # ============================================================
666
+
667
  from fastapi import UploadFile, File
668
  from fastapi.responses import JSONResponse
669
+ import io, os, numpy as np, torch
670
  from PIL import Image
671
  from monai.networks.nets import UNet
672
  import torch.nn.functional as F
673
+ import pyvista as pv
674
+ from pyvista import start_xvfb
675
+ import imageio.v3 as iio
676
 
677
  HF_SPACE_URL = os.getenv("HF_SPACE_URL", "https://abbhy123ghh-x-ray-analysis.hf.space").rstrip("/")
678
 
 
696
  volume = np.expand_dims(volume, axis=0) # [1, D, H, W]
697
 
698
  # --- Step 3: MONAI lightweight 3D UNet (shallow for CPU) ---
699
+ x = torch.tensor(volume, dtype=torch.float32).unsqueeze(0) # [1, 1, D, H, W]
 
 
700
  pad_d = (16 - x.shape[2] % 16) % 16
701
  pad_h = (16 - x.shape[3] % 16) % 16
702
  pad_w = (16 - x.shape[4] % 16) % 16
 
718
  seg = (seg - seg.min()) / (seg.max() - seg.min() + 1e-8)
719
  seg = np.clip(seg * 255, 0, 255).astype(np.uint8)
720
 
721
+ # --- Step 4: Create PyVista grid (Hugging Face compatible) ---
722
+ start_xvfb()
723
+ grid = pv.ImageData(dimensions=seg.shape)
 
 
 
 
 
 
 
 
 
724
  grid.spacing = (1, 1, 1)
725
  grid.origin = (0, 0, 0)
726
+ grid.point_data["values"] = seg.flatten(order="F")
727
 
728
+ # --- Step 5: Enhanced 3D visualization with lighting ---
729
+ plotter = pv.Plotter(off_screen=True, window_size=[512, 512])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
730
  plotter.add_volume(
731
+ grid,
732
  cmap="bone",
733
  opacity="sigmoid_5",
734
  shade=True,
735
+ diffuse=1.0,
736
+ specular=0.3,
737
+ specular_power=15,
738
  )
739
  plotter.set_background("black")
740
+
741
+ # Add realistic light
742
+ light = pv.Light(
743
+ position=(seg.shape[2]*2, seg.shape[1]*2, seg.shape[0]),
744
+ color='white',
745
+ intensity=1.5,
746
+ )
747
+ plotter.add_light(light)
748
 
749
  frames = []
750
  for angle in range(0, 360, 5):
751
  plotter.camera_position = [
752
+ (seg.shape[2]*2, 0, seg.shape[0]/2),
753
+ (seg.shape[2]/2, seg.shape[1]/2, seg.shape[0]/2),
754
  (0, 0, 1),
755
  ]
756
  plotter.camera.azimuth = angle
 
758
  frames.append(img_frame)
759
  plotter.close()
760
 
761
+ # --- Step 6: Save rotating MP4 video ---
762
  os.makedirs("static", exist_ok=True)
763
  out_path = "static/xray_monai_3d_fullbody.mp4"
764
+ iio.imwrite(out_path, frames, fps=12, codec="libx264")
 
 
 
 
765
 
766
  return JSONResponse({
767
  "ok": True,
 
773
  import traceback; traceback.print_exc()
774
  return JSONResponse({"error": str(e)}, status_code=500)
775
 
776
+
777
 
778
 
779