Hidden spaces module
This module visualizes which areas of a buildings interior are not scanned in a volumetric fashion using voxels to represent 3D space.
The identification of the volumes (voxels) that are not visited by the explorers is done gradually by processing one Keyframe at a time and updating the status of the voxels. The voxels can have 6 different states (statuses):
- Mesh -> Voxels occupied by the buildings hull
- Exterior -> Voxels outside of the building
- Scanned -> Voxels that contain points from the point cloud
- Seen -> Voxels that represent the void space between the camera's position and the Scanned voxels
- Unknown -> Initially they represent the interior of the building. At the end of the process they represent the voxels that remain unknown (i.e., are not Scanned or Seen)
- Temporary -> Used for some extreme cases where the camera lies outside of the voxel grid, for isntance in the beginning of the scan.
This process is explained in steps.
- Building's hull as triangular mesh
- Point cloud
The building hull is manually transformed so that it aligns with X, Y, and Z axes using CloudCompare and is stored as a new file.
The point cloud is manually transformed so that it fits in the building's hull using CloudCompare and the transformation matrix is stored for further use.
- The building's hull is voxelized using
open3d.geometry.VoxelGrid.create_from_triangle_mesh(). - The voxels are transferred in a custom
VoxelGrid, and are marked as occupied. - The voxel grid is the densified, which means that all the voxels in the domain are created and are marked as unknown.
- The exterior voxels (i.e., the voxels outside of the building) are marked using 6 neighbours region growing.
- Mark scanned and void voxels
- For each Keyframe (pair of RGB + Depth images) that is retrieved from the database a point cloud is generated and transformed using the transformation matrix retrieved in the preprocessing.
- This point cloud is then voxelized using
open3d.geometry.VoxelGrid.create_from_point_cloud_within_bounds(). - This voxel grid has the same origin as the one in step 2, and its voxels are copied to the latter and marked as scanned.
- The voxels between the camera's position and the voxels generated by the point-cloud of the latest keyframe are marked as seen using fast voxel traversal.
- Repeat step 5 until all keyframes are processed.
The module's main focus is to visualize the voxels based on their status. The status have 8 different states:
This module uses both Open3D library and two custom classes Voxel and VoxelGrid:
- This class represents a single voxel.
Explanation of Voxel's attributes:
x,y, andzstore the voxel's position as indices- the
sizeis the voxel's size i.e., height, width, depth - the
colorstores the voxels color that is used for visualization purposes - the
statusstores the category in which the voxel belongs to - the
queuedstore if the voxel has already been processed in the neighbours search while marking the exterior voxels
- This class represents a voxel grid.
Explanation of VoxelGrid's attributes:
cell_sizestores the size of the voxels' i.e., height, width, depthoriginstores the voxel grid's origin in real world coordinateswidth,height, anddepthstore the voxel grid's real-life sizewidth_voxels,height_voxels, anddepth_voxelsstore the voxel grid's dimensions in voxelsvoxelsstores the voxels as a dictionary of voxelsself.voxels: Dict[Voxel]interior_voxels,exterior_voxels,mesh_voxels,scanned_voxels,seen_voxels, andunknown_voxelsstore the indices of the voxels as they're being marked
The point cloud reconstruction is implemented in map_database_point_cloud_reconstruction.py.
This module works with iPhone RGB-D images