FLOOR2MODEL / endToEnd2.py
Harisri
Full rebuild based on cvlab source (removed all GAN/extra changes)
95ccdf6
import cv2
import os
import sys
import shutil
from pathlib import Path
PROJECT_ROOT = Path(__file__).resolve().parent
os.chdir(PROJECT_ROOT)
sys.path.insert(0, str(PROJECT_ROOT))
from src.segmentation.predictor import FloorPlanPredictor
from src.segmentation.visualizer import SegmentationVisualizer
from src.geometry.pipeline import GeometryPipeline
from src.reconstruction.pipeline import ReconstructionPipeline
# GAN/Phase 5 fully removed as requested
GAN_AVAILABLE = False
MODEL_PATH = PROJECT_ROOT / "models" / "best.pt"
OUTPUTS_DIR = PROJECT_ROOT / "outputs"
GENERATED_DIR = PROJECT_ROOT / "generated_models"
print(f"Project root: {PROJECT_ROOT}")
print(f"Model exists: {MODEL_PATH.exists()}")
def run_pipeline(sample_image: Path):
stem = sample_image.stem
print(f"\n{'='*60}")
print(f"Processing: {sample_image.name}")
print(f"{'='*60}")
# ── Phase 2: Segmentation (raw image, CPU) ────────────────────────
print("\n[Phase 2] Segmentation...")
best_conf = None
best_result = None
# Use CPU by default to match cvlab behavior
for conf in [0.35, 0.25, 0.15, 0.10, 0.05]:
predictor = FloorPlanPredictor(str(MODEL_PATH), confidence=conf, device="cpu")
seg_result = predictor.predict(str(sample_image))
total = seg_result.summary["total_elements"]
print(f" conf={conf}: {total} elements detected")
if total > 0 and best_result is None:
best_conf = conf
best_result = seg_result
# Load original color image for drawing
base_img = cv2.imread(str(sample_image), cv2.IMREAD_COLOR)
if base_img is not None and len(base_img.shape) == 2:
base_img = cv2.cvtColor(base_img, cv2.COLOR_GRAY2BGR)
out_dir = GENERATED_DIR / stem
if out_dir.exists():
shutil.rmtree(out_dir)
out_dir.mkdir(parents=True)
ann_path = out_dir / f"{stem}_detections.png"
if best_result is None:
print(" ⚠ No elements detected.")
if base_img is not None:
cv2.imwrite(str(ann_path), base_img)
return
print(f" βœ“ conf={best_conf} β†’ {best_result.summary['total_elements']} elements")
print(f" {best_result.summary['by_class']}")
# Save detection overlay into output folder
viz = SegmentationVisualizer()
annotated = viz.draw(base_img, best_result)
cv2.imwrite(str(ann_path), annotated)
print(f" βœ“ Detection overlay β†’ {ann_path.name}")
# ── Phase 3: Geometry ─────────────────────────────────────────────
print("\n[Phase 3] Geometry reconstruction...")
img = cv2.imread(str(sample_image))
geo_result, _, _ = GeometryPipeline().run_and_visualize(
best_result, img,
image_path=str(sample_image),
output_dir=str(OUTPUTS_DIR / "geometry"),
)
# ── Phase 4: 3D Reconstruction ────────────────────────────────────
print("\n[Phase 4] 3D reconstruction...")
seg_has_elements = best_result is not None and len(best_result.elements) > 0
has_polygons = len(geo_result.vectorization.all_polygons) > 0
if not has_polygons and not seg_has_elements:
print(" ⚠ No geometry to extrude β€” skipping 3D.")
return
model_3d = ReconstructionPipeline().reconstruct(
geo_result,
output_dir=str(out_dir),
stem=stem,
floorplan_image_path=str(sample_image),
render_image_path=None, # Explicitly no GAN render
)
print(f" βœ“ {model_3d.summary}")
print(f"\n Output β†’ {out_dir}/")
print(f" β”œβ”€β”€ {stem}_detections.png")
print(f" β”œβ”€β”€ {stem}.gltf")
print(f" β”œβ”€β”€ {stem}.obj")
if __name__ == "__main__":
if len(sys.argv) > 1:
run_pipeline(Path(sys.argv[1]))
else:
exts = ("*.png", "*.jpg", "*.jpeg", "*.bmp", "*.tiff", "*.tif")
samples = sorted(p for ext in exts for p in (PROJECT_ROOT / "samples").glob(ext))
for sample in samples:
run_pipeline(sample)