Skip to content

Sreeyukth/Geometry-Based-RobotPerception

Repository files navigation

3D Room Scene Semantic Segmentation

A geometry-only pipeline that segments indoor 3D point clouds into semantic components — floor, ceiling, walls, and furniture — using RANSAC plane fitting and DBSCAN clustering. No deep learning, no pretrained models.


Overview

Given a .ply or .pcd scan of an indoor room, this pipeline:

  1. Preprocesses the point cloud (denoise + voxel downsample)
  2. Iteratively fits planes via RANSAC, labelling each as floor, ceiling, or wall
  3. Clusters remaining points with DBSCAN to identify furniture
  4. Generates outputs — colour-coded point cloud, bounding box report, and a 2D floor-plan PNG

All labelling is purely rule-based (height, orientation, size) — no training data required.


Demo Output

Floor (Blue) Ceiling (White) Walls (Red) Furniture (Green)

Sample run on Area_1_office_14_sample35:

After preprocessing : 4,295 points
Clusters found      : 6

  Cluster 0 (724 pts) → CEILING   — 1.44m × 0.78m × 0.09m
  Cluster 1 (669 pts) → FLOOR     — 0.39m × 0.83m × 0.07m
  Cluster 2 (669 pts) → WALL      — 0.92m × 0.67m × 0.97m
  Cluster 3 (497 pts) → CEILING   — 1.47m × 1.15m × 0.05m
  Cluster 4 (316 pts) → WALL      — 1.55m × 1.40m × 0.41m
  Cluster 5 ( 82 pts) → FURNITURE — 0.24m × 0.14m × 0.07m

Runtime: 0.09s

Project Structure

3d-room-segmentation/
├── main.py              # CLI entry point
├── preprocessing.py     # Load, denoise, voxel-downsample
├── plane_fitting.py     # Iterative RANSAC plane extraction
├── clustering.py        # DBSCAN clustering on residual points
├── semantic_labeling.py # Rule-based label assignment
├── bounding_box.py      # AABB computation & report generation
├── cluster_merging.py   # Post-processing: merge adjacent same-label clusters
├── visualization.py     # Colour coding, PLY export, viewer, PNG floor-plan
├── utils.py             # Label constants, colour map, helpers
├── merge_fragments.py   # Utility: merge Open3D demo scan fragments
└── requirements.txt

Installation

Requires Python 3.11 — Open3D does not yet support 3.12/3.13.

python3.11 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

Dependencies: numpy, scikit-learn, open3d, plyfile, Pillow


Dataset

This pipeline is built for the VX-S3DIS dataset (Stanford 3D Indoor Spaces).

Download:

  1. Create a free account at huggingface.co
  2. Request access at the dataset page linked above
  3. Download global_view.zip and extract:
mkdir -p data/s3dis_raw/s3dis
7z x global_view.zip -o./data/s3dis_raw/s3dis

Any .ply file from an indoor 3D scan will also work.


Quick Start

source .venv/bin/activate

python main.py ./data/s3dis_raw/s3dis/Area_1_office_14_sample35_simCtr_385.ply \
  --eps 0.05 --min_samples 10 --voxel_size 0.02 --output_dir ./output

View the 3D result interactively:

python -c "
import open3d as o3d
pcd = o3d.io.read_point_cloud('./output/Area_1_office_14_sample35_simCtr_385_segmented.ply')
o3d.visualization.draw_geometries([pcd], window_name='Segmented Room', width=1280, height=800)
"

Or pass --visualize to open the viewer automatically after processing.


Pipeline

Input PLY/PCD
     │
     ▼
1. Preprocessing
   ├── Statistical outlier removal
   └── Voxel downsampling (default 0.02 m)
     │
     ▼
2. Iterative RANSAC Plane Segmentation
   ├── Extract dominant planes one by one
   └── Classify each: FLOOR / CEILING / WALL
       (planes with z_range > 0.3 m → reclassified as WALL)
     │
     ▼
3. DBSCAN on Remaining Points
   └── Non-planar residual → FURNITURE clusters
     │
     ▼
4. Degenerate Cluster Filtering
   ├── Drop clusters with any dimension < 1.5 cm
   └── Drop clusters with negative Z centroid
     │
     ▼
5. Output Generation
   ├── Colour-coded segmented .ply
   ├── Bounding box report (.txt + .json)
   └── 2D top-down floor-plan (.png)

Semantic Labelling Rules

Label Rule
FLOOR Horizontal plane (nz ≥ 0.7), thin (z_range < 0.3 m), mean Z near ground
CEILING Horizontal plane (nz ≥ 0.7), thin (z_range < 0.3 m), mean Z near room top
WALL Vertical plane (nz < 0.7) or thick horizontal plane (z_range ≥ 0.3 m)
FURNITURE Non-planar DBSCAN clusters (tables, chairs, shelves, monitors, …)

CLI Reference

python main.py <input_file> [options]
Argument Default Description
input_file Path to .ply or .pcd file
--output_dir ./output Output directory
--voxel_size 0.05 Downsampling voxel size (metres)
--eps 0.1 DBSCAN neighbourhood radius
--min_samples 5 DBSCAN min points per core point
--min_cluster_size 75 Drop clusters smaller than this
--visualize off Open interactive 3D viewer after run
--merge_clusters off Merge adjacent same-label clusters
--merge_distance 0.5 Max centroid distance for merging (metres)
--no_json off Skip JSON report
--no_png off Skip floor-plan PNG

Output Files

File Description
*_segmented.ply Colour-coded point cloud — open in CloudCompare or MeshLab
*_bbox_report.txt Human-readable bounding box report with dimensions and centroids
*_bbox_report.json Machine-readable JSON version of the same report
*_floorplan.png 2D top-down projection of the segmented scene

License

MIT

About

Learning robotics — built a geometry-only pipeline to segment 3D indoor point clouds into floor, ceiling, walls & furniture using RANSAC plane fitting + DBSCAN clustering. No deep learning, just spatial reasoning. Built with Open3D and the S3DIS dataset.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages