Spaces:
Sleeping
Sleeping
| 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) | |