| | |
| | | # 3D and Point Cloud |
| | | # Three-dimensional reconstruction and point-cloud understanding |
| | | |
| | | - 输入:重叠照片、LAS/LAZ/PLY 点云或现有三维成果。 |
| | | - 输出:点云、网格、DSM、分类或构件结果。 |
| | | - 首个 Demo:先分析已有 ODM/点云成果,不在本机从零训练重型模型。 |
| | | ## Boundary |
| | | |
| | | Classification: **B - ecosystem combination**. |
| | | |
| | | `geoai-py 0.42.0` has no installed API for SfM/MVS reconstruction or point-cloud |
| | | classification. This Demo uses pycolmap/COLMAP for CPU sparse SfM and OpenMVS for |
| | | CPU dense MVS, meshing and texturing from a coherent photo sequence, plus Open3D |
| | | for existing point-cloud geometry. `geoai.masks_to_vector` |
| | | turns an elevated-surface label raster into the GeoJSON footprint output. Open3D, |
| | | Rasterio, GeoPandas, Laspy, and pycolmap supply the remaining work. This is not a |
| | | built-in `geoai-py` 3D reconstruction function. |
| | | |
| | | ## Runnable Demo |
| | | |
| | | Input: one existing `PLY`, `PCD`, `XYZ`, `LAS`, or `LAZ` point cloud. The first |
| | | geometry branch consumes a reconstruction output and creates inspectable raster |
| | | and vector outputs. The photo branch accepts a coherent JPG/JPEG sequence and |
| | | creates a CPU sparse SfM point cloud. A user-supplied survey, reconstruction |
| | | export, or image sequence is copied unchanged into a raw run directory before a |
| | | console run is processed. |
| | | |
| | | ```powershell |
| | | $py = .\.venvs\05-3d-pointcloud\Scripts\python.exe |
| | | & $py .\capabilities\05-3d-pointcloud\run_pointcloud_understanding.py ` |
| | | --input .\shared\data\raw\05-3d-pointcloud\validation-20260821\normal_site.ply ` |
| | | --output .\shared\outputs\05-3d-pointcloud\validation-normal-20260821 |
| | | ``` |
| | | |
| | | Photo sparse reconstruction: |
| | | |
| | | ```powershell |
| | | $py = .\.venvs\05-3d-pointcloud\Scripts\python.exe |
| | | & $py .\capabilities\05-3d-pointcloud\run_photo_reconstruction.py ` |
| | | --input .\shared\data\raw\05-3d-pointcloud\h30t-sideview-20260820-v2 ` |
| | | --output .\shared\outputs\05-3d-pointcloud\real-h30t-sideview-20260821-v2 |
| | | ``` |
| | | |
| | | CPU dense MVS after a verified sparse model (the original source images remain |
| | | unchanged; the output directory must be new): |
| | | |
| | | ```powershell |
| | | $py = .\.venvs\05-3d-pointcloud\Scripts\python.exe |
| | | & $py .\capabilities\05-3d-pointcloud\run_cpu_dense_reconstruction.py ` |
| | | --input .\shared\data\raw\05-3d-pointcloud\h30t-sideview-20260820-v2 ` |
| | | --sparse-model .\shared\outputs\05-3d-pointcloud\real-h30t-sideview-20260821-v2\sparse_model\0 ` |
| | | --output .\shared\outputs\05-3d-pointcloud\cpu-mvs-full-<new-run-id> ` |
| | | --openmvs-bin .\shared\tools\openmvs-2.4.0\vc17\x64\Release ` |
| | | --threads 12 --max-resolution 2400 --dense-resolution-level 0 ` |
| | | --dense-number-views 8 --dense-number-views-fuse 2 --target-faces 800000 |
| | | ``` |
| | | |
| | | WebODM/ODX-compatible RTK input preparation (metadata only; it neither starts |
| | | WebODM nor reconstructs a model): |
| | | |
| | | ```powershell |
| | | $py = .\.venvs\05-3d-pointcloud\Scripts\python.exe |
| | | & $py .\capabilities\05-3d-pointcloud\prepare_odx_reconstruction_inputs.py ` |
| | | --input .\shared\data\raw\05-3d-pointcloud\h30t-sideview-20260820-v2 ` |
| | | --output .\shared\outputs\05-3d-pointcloud\odx-input-h30t-sideview-<new-run-id> ` |
| | | --webodm-reference .\reference_project\WebODM-master |
| | | ``` |
| | | |
| | | The generated package contains `geo.txt` in ODX's `EPSG:4326` format, a |
| | | camera-position GeoJSON, a source-hash manifest, recommended ODX parameters, |
| | | and an explicit compatibility report. It reproduces the referenced ODX DJI |
| | | conversion: `FlightYawDegree`, `90 + GimbalPitchDegree`, and |
| | | `GimbalRollDegree`, with the reported RTK deviations doubled as ODX does. |
| | | Leave ODX's global `--gps-accuracy` unset for this package because it would |
| | | overwrite the per-photo horizontal/vertical deviations in `geo.txt`. |
| | | |
| | | The CPU pipeline performs voxel downsampling, RANSAC dominant-ground fitting, |
| | | height-above-ground labelling, alpha-shape mesh reconstruction, rasterization, |
| | | and GeoAI footprint vectorization. The output directory must be new or empty. |
| | | |
| | | Use `--ground-up-axis auto` only when the source-local Z axis is not vertical; |
| | | it rotates a processing copy from the dominant RANSAC plane and records that |
| | | rotation. The raw point cloud is never changed. |
| | | |
| | | ## Input and output contract |
| | | |
| | | Existing-point-cloud input yields `*.classified.ply`, an alpha-shape |
| | | `*.reconstruction.ply` when the geometry permits it, DSM and height GeoTIFFs, |
| | | an elevated-surface GeoTIFF, a PNG raster preview, elevated-footprint GeoJSON, |
| | | summary CSV, and fixed `run_metadata.json`. |
| | | |
| | | Photo input first yields a COLMAP sparse model, coloured `sparse_points.ply`, a |
| | | principal-axis PNG preview, `camera_poses_local.csv`, an EXIF GPS input manifest, |
| | | and fixed `run_metadata.json`. The verified CPU dense branch additionally yields |
| | | `dense.ply`, a triangle `mesh.ply`, OpenMVS texture atlas PNGs, an original |
| | | `textured.glb`, a self-contained `textured_preview_filtered.glb` for reliable |
| | | texture inspection, and `geometry_preview.glb` for complete-surface inspection. |
| | | The reliable-texture preview flips atlas pixels vertically to match browser sampling |
| | | while preserving OpenMVS UV coordinates, then removes any triangle whose four |
| | | interior samples reach black atlas background or OpenMVS's orange |
| | | `RGB(255,127,39)` no-coverage colour. `textured_preview_filter_report.json` |
| | | records retained and rejected faces. `geometry_preview.glb` keeps every mesh face |
| | | with a neutral material: it does not invent colour or texture and separates |
| | | geometric coverage from texture coverage. It records the registered |
| | | images, sparse/dense point counts, mesh counts, source hashes and CPU parameters. |
| | | When an OpenMVS dense PLY contains fused RGB, `point_color_preview.glb` also |
| | | assigns each complete-mesh vertex the RGB of its nearest fused point. This keeps |
| | | all mesh faces and uses observed point colours, but it is a nearest-point colour |
| | | projection rather than a per-face photo texture. |
| | | |
| | | Default local-coordinate thresholds: voxel size `0.20`, RANSAC plane distance |
| | | `0.15`, elevated height `0.75`. Review them against the source units and density. |
| | | |
| | | ## Coordinates and limitations |
| | | |
| | | PLY/PCD/XYZ input normally has no declared CRS. Its output is explicitly |
| | | `local_point_cloud_coordinates`; GeoTIFF/GeoJSON coordinates are not geographic |
| | | coordinates, metres, or survey-grade locations. LAS/LAZ source CRS is not |
| | | promoted in this first Demo, so it is also treated as local. |
| | | |
| | | The generated `validation-*` PLYs are known-geometry test fixtures, not field |
| | | data or an accuracy dataset. `normal_site.ply` checks a dense flat site; |
| | | `difficult_sparse_site.ply` checks sparse tilted terrain and isolated high |
| | | noise. The difficult case is expected to show false elevated cells around noise: |
| | | it validates handling and output, not semantic accuracy. |
| | | |
| | | Photo SfM uses `SIMPLE_RADIAL` camera parameters. Position priors can preserve |
| | | the RTK-scale camera trajectory, but neither camera calibration nor exterior |
| | | orientation is survey-grade. pycolmap's dense PatchMatch requires CUDA and |
| | | remains unavailable, but the separate OpenMVS 2.4.0 Windows CPU binary has been |
| | | verified for dense depth fusion, meshing and texturing. This does not create a |
| | | DSM, orthomosaic, semantic class, GIS coordinate or survey-grade measurement |
| | | claim. |
| | | |
| | | Real DJI H30T validation: 18 side-view photos from `2026-08-20` completed CPU |
| | | sparse SfM in 140.832 seconds. All 18 photos registered into one camera group; |
| | | the result has 11,975 coloured sparse points and 1.1992 px mean reprojection |
| | | error. A six-photo representative CPU MVS check completed depth fusion, meshing |
| | | and texturing in 112 seconds (232,060 dense points, 199,970 faces). The full |
| | | 18-photo CPU MVS run then completed in 461 seconds: 681,788 dense points and a |
| | | 399,932-face textured mesh. It uses a 1,600 px dense-image cap and 12 CPU |
| | | threads, so it is a verified CPU baseline rather than a maximum-quality GPU run. |
| | | A two-photo low-baseline check failed cleanly, documenting the need for sufficient |
| | | baseline. Reliable-texture reprocessing of the full 18-photo output reuses the |
| | | completed dense point cloud, disables mesh hole closing/smoothing, requests no |
| | | texture outlier removal, and filters the browser preview as above. The new raw |
| | | mesh has 346,878 faces; 128,772 faces (37.12%) pass the four-sample atlas check. |
| | | The remaining faces are deliberately absent from the preview because the photos |
| | | do not provide consistent texture there. This avoids orange/black placeholders, |
| | | but does not create a watertight model or improve the original coverage. |
| | | |
| | | High-resolution CPU verification of the same 18 photos completed in 2,341.305 |
| | | seconds at 2,400 x 1,774 depth maps, level 0, eight neighbouring views, and a |
| | | two-view fusion threshold. It produced 3,379,097 dense points and a 799,632-face |
| | | mesh, but only 293,229 faces (36.67%) passed the reliable-texture check. The mesh |
| | | itself has one 799,646-face main connected component, so the dominant visible |
| | | holes in reliable-texture display are coverage rejections, not deletion of the |
| | | geometric surface. The console exposes both modes; this does not prove that the |
| | | complete geometry is accurate in vegetation or occluded areas. |
| | | The same high-resolution result also has a 799,632-face point-colour preview; |
| | | it is useful for inspecting coloured complete geometry, but must not be treated |
| | | as an image-texture accuracy claim. |
| | | |
| | | Metric diagnostic for the RTK/fixed-focal high-resolution result rejects it for |
| | | height or measurement use. The read-only |
| | | `diagnose_photo_pose_alignment.py` script compares source DJI RTK/LRF XMP with |
| | | a sparse model and optional OpenMVS `dense.ply`. For all 18 LRF target points, |
| | | the latest dense cloud has a 13.3814 m median nearest-point distance, 11.9794 m |
| | | median horizontal error, and -4.8131 m median signed vertical error. The RTK |
| | | camera trajectory itself is materially better (0.5978 m median fit error), so |
| | | the dense failure is not a viewer/texture issue. A fixed-pose sparse trial using |
| | | RTK camera centres plus LRF target directions kept camera centres at 0 m error |
| | | but reached 12.0193 px mean reprojection error, compared with 1.2105 px for the |
| | | RTK-constrained SfM baseline. It therefore rejects the uncalibrated assumptions |
| | | that the GNSS receiver is the optical centre and the LRF target is the RGB |
| | | principal point; it must not be used as an MVS input. |
| | | |
| | | ## ODX-aligned CPU result |
| | | |
| | | The original result above remains a preserved baseline. A new local sparse |
| | | model uses an ODX-style configuration: `OPENCV` intrinsics (the local analogue |
| | | of ODX brown calibration), RTK/GPS spatial matching with four neighbours, |
| | | 2,000 px feature extraction, 18,000 features, and a 0.05 m position-prior |
| | | loss scale. Both a normal six-photo set and a difficult six-photo set registered |
| | | 6/6 images, with 0.7581 px and 0.7596 px mean reprojection error respectively. |
| | | The complete 18-photo model registered 18/18 images with 23,084 sparse points |
| | | and 0.8410 px mean reprojection error. |
| | | |
| | | Its CPU OpenMVS run at 2,400 px, eight views and two-view fusion completed in |
| | | 2,390.086 seconds. It has 3,756,551 dense points and a 799,645-face mesh. The |
| | | reliable-texture browser GLB retains 293,614 faces (36.72%) after rejecting |
| | | black/orange atlas placeholders; the point-colour and neutral complete-geometry |
| | | GLBs both retain all 799,645 faces. It is available in the case library as |
| | | `ODX 对齐 CPU 高分重建(H30T 18 图)`. |
| | | |
| | | The read-only DJI RTK/LRF diagnostic reports a 0.4038 m median nearest dense |
| | | point distance for all 18 targets, with 0.3073 m horizontal and 0.0709 m signed |
| | | vertical median error. This is a material improvement over the preserved old |
| | | baseline, but the LRF observations are used here as a diagnostic rather than |
| | | independent surveyed check points. The result is suitable for visual comparison |
| | | with WebODM and continuing reconstruction evaluation; it is not a survey-grade |
| | | DSM, orthomosaic, GIS-coordinate, semantic-class, or engineering measurement |
| | | claim. |
| | | |
| | | ## WebODM/ODX reference and acceptance gate |
| | | |
| | | The local `reference_project/WebODM-master` was inspected to understand the |
| | | comparison output. WebODM is the task/UI service; the current reference's |
| | | default processing node is `webodm/nodeodx` (NodeODX), which runs the actual |
| | | OpenSfM/OpenDroneMap pipeline. It accepts `geo.txt`, GCPs, and a verified |
| | | `cameras.json`; it can also lock verified camera parameters during bundle |
| | | adjustment. These are substantive inputs, not display settings that can be |
| | | copied into the current COLMAP/OpenMVS code. |
| | | |
| | | The new `prepare_odx_reconstruction_inputs.py` produces a checked input package |
| | | from DJI metadata. For the supplied H30T sequence, the verified package at |
| | | `shared/outputs/05-3d-pointcloud/odx-input-h30t-sideview-20260822-v2/` contains |
| | | 18 camera records. Its median per-photo ODX horizontal/vertical observations |
| | | are 0.00472 m and 0.01162 m respectively. It does not create a guessed |
| | | `cameras.json`, and it excludes LRF target observations from GCP input. |
| | | |
| | | This workstation has neither Docker nor NodeODX/NodeODM available, so no claim |
| | | is made that WebODM or ODX was executed locally. Before sending this photo set |
| | | to an ODX worker or cloud service, provide one of: a camera-specific H30T RGB |
| | | calibration plus antenna/camera lever-arm and boresight; or at least three |
| | | surveyed stable GCPs, each marked in two or more images, with separate check |
| | | points. Accept a resulting model only after it reports independent checkpoint |
| | | residuals and they meet the intended measurement tolerance. |
| | | |
| | | Further accuracy improvement requires camera-specific H30T calibration and |
| | | antenna-to-camera lever-arm/boresight data, or at least three stable surveyed |
| | | 3D control points marked in two or more images with separate check points. A |
| | | uniform height translation is not a valid replacement for those inputs. |
| | | |
| | | The sparse PLY contains only `element vertex 11975`; it has no faces or normals. |
| | | A viewer that triangulates it as a surface creates false sheets or spikes. The |
| | | console renders sparse data strictly as coloured `THREE.Points`; dense MVS cases |
| | | offer reliable-texture and complete-geometry modes with orbit, zoom, reset and |
| | | optional wireframe. A point-colour mode can additionally project fused point RGB |
| | | onto every mesh vertex. Complete geometry uses a neutral material and retains |
| | | all mesh faces, while reliable texture retains only faces with image evidence. |
| | | The original mesh and atlas files remain downloadable for review. |
| | | The CPU mesh still has holes or potentially incorrect surfaces in occluded, |
| | | vegetated, low-texture or reflective regions and cannot be assumed equivalent to |
| | | a higher-resolution GPU/cloud output without visual review. |
| | | |
| | | The separate real input `shared/data/raw/05-3d-pointcloud/pcl-table-scene-20260821/table_scene_lms400.pcd` |
| | | is the PCL tutorial's `table_scene_lms400` scan, downloaded unchanged from the |
| | | PCL data repository (SHA-256 `E285D415641E0D9DE695B611DB874CC8FE995E8089B77A50D6056D24D8CBCC58`). |
| | | Its 460,400 source points validate reading a real PCD and the `--ground-up-axis |
| | | auto` processing-copy branch. It is a tabletop scan, not an aerial reconstruction |
| | | or semantic truth set. |
| | | |
| | | Ground/elevated is a geometric split, not building, tree, equipment, or hazard |
| | | recognition. Slopes, water, vertical dominant surfaces, dense vegetation, or a |
| | | weak/no ground return can invalidate the RANSAC assumption. The mesh is an |
| | | inspectable alpha-shape approximation and is not guaranteed watertight or |
| | | metric-accurate. Obtain registered source data and manually reviewed truth before |
| | | operational or commercial use. |
| | | |
| | | ## Semantic point-cloud classification baseline |
| | | |
| | | The existing-point-cloud route now writes a separate CPU semantic-classification |
| | | baseline. It uses RGB plus locally estimated ground/height, density, vertical |
| | | span, and horizontal line continuity. It is still **B** work: `geoai-py` is used |
| | | only for the existing elevated-surface raster-to-vector branch, not for a native |
| | | point-cloud classifier. |
| | | |
| | | Classes are `ground`, `vegetation`, `building_structure`, `power_line`, |
| | | `pole_tower`, and `other_unknown`. The last three names describe review outputs: |
| | | the first version is deliberately a transparent rule baseline rather than a |
| | | trained semantic model. It exports a colour-coded preview PLY (capped at 400,000 |
| | | points for the browser), semantic LAS class codes, class GeoTIFF/PNG, candidate |
| | | GeoJSON, class-count CSV, and `run_metadata.json`. |
| | | |
| | | Real LAS check: the unchanged user input `baseData/las/part_01.las` contains |
| | | 10,473,127 points, RGB and return attributes, but every source LAS |
| | | `classification` value is `0`; it is not semantic truth. Run |
| | | `validation-las-part01-semantic-20260822-v11-original-rgb` used 0.20 local-unit voxel sampling |
| | | and local-neighbourhood shape features (horizontal linearity for conductors and |
| | | vertical linearity for pole/tower members). It completed in 73.586 seconds CPU |
| | | with 1,370,984 output points: 356,170 ground, 714,122 vegetation, 1,031 |
| | | structure, 3,183 pole/tower candidates, 8,162 power-line candidates, and 288,316 |
| | | unknown. The preview retains every line/pole candidate before sampling the other |
| | | classes, because uniform preview sampling hid sparse conductors. Candidate |
| | | precision and recall remain unvalidated. Do not use these candidates as asset |
| | | inventory, clearance, or inspection conclusions until a user reviews the browser |
| | | preview and supplies labelled ground truth. |
| | | |
| | | The generated H30T dense cloud was also checked as |
| | | `validation-h30t-dense-semantic-20260822-v2`: 3,756,551 input points became |
| | | 1,205,115 sampled points in 38.673 CPU seconds. Its dominant plane was too |
| | | steep to be accepted as ground, so the output uses only the local low-point |
| | | fallback and records `ground_plane_available: false`. It produced 181,436 ground, |
| | | 663,962 vegetation, 988 structure, 641 pole/tower candidates, zero power-line |
| | | candidates and 358,088 unknown. This proves the technical route accepts the |
| | | reconstructed PLY; it does not validate class accuracy for this side-view model. |
| | | |
| | | ## Console |
| | | |
| | | The independent local experiment console exposes `GET/POST |
| | | /api/3d-pointcloud/runs`. It accepts at most two PLY/PCD/XYZ/LAS/LAZ files for |
| | | new geometry runs, generates a server-side run ID, preserves raw source bytes and |
| | | SHA-256, and stores raw, processed, and output artifacts separately. Its case |
| | | library also discovers sparse photo-SfM and dense CPU-MVS result directories. |
| | | Sparse results display an interactive Three.js point viewer, registration |
| | | statistics, poses, input manifest and downloads. Dense results display reliable |
| | | texture, point-colour and complete-geometry modes, plus dense PLY, mesh PLY and |
| | | texture downloads. The point-colour mode projects fused RGB point values to the |
| | | complete mesh; the complete geometry mode retains all mesh faces with a neutral |
| | | material. Neither fabricates a photo texture. The |
| | | sparse viewer supports orbit, zoom, point-size adjustment and reset, and never triangulates PLY vertices. It |
| | | has no connection to a drone product, product account, product API, or product |
| | | database. |
| | | |
| | | The console keeps incompatible inputs in two workflow tabs. `照片三维重建` |
| | | accepts 3-30 JPG/JPEG files from one coherent flight/camera sequence through |
| | | bounded binary uploads, preserves source bytes and SHA-256 values in a new run |
| | | directory, and starts a background CPU sparse-SfM then OpenMVS dense-MVS job. |
| | | The page polls `queued`, `sparse_sfm`, `dense_mvs`, `complete`, or `failed` and |
| | | automatically adds a completed result to the case library. Enable `GPS/RTK |
| | | 先验` only when all input photos have valid position metadata; it selects the |
| | | verified spatial matching configuration. Disable it for ordinary cameras, which |
| | | use exhaustive matching. `既有点云理解` remains the PLY/PCD/XYZ/LAS/LAZ-to- |
| | | raster/vector route. Creating a new run or discovering its result does not |
| | | rebuild the console; `npm run build` is only needed after changing Vue/TypeScript |
| | | frontend source. |
| | | |
| | | The console separates this capability into four workspaces: photo 3D |
| | | reconstruction; point-cloud geometry processing; point-cloud semantic |
| | | classification; and annotation, training, and model application. Photo cases |
| | | are isolated from point-cloud cases. Geometry and semantic workspaces each have |
| | | their own filtered case library; a source run can appear in both only when it |
| | | has both output families. The model workspace contains the linked annotation, |
| | | training, and portable-model workflow without placing it below every semantic |
| | | result. |
| | | |
| | | ```powershell |
| | | py -3.12 .\scripts\serve_workbench_console.py --port 6188 |
| | | ``` |
| | | |
| | | ## Licenses |
| | | |
| | | - `geoai-py`: MIT. This does not grant rights for data or other dependencies. |
| | | - Open3D: MIT; check release and bundled dependency notices before redistribution. |
| | | - Laspy: BSD-3-Clause; Rasterio, GeoPandas, and Shapely retain their own licenses. |
| | | - No model weights or third-party point-cloud dataset are bundled. Record the |
| | | licence of each survey/reconstruction source before commercial use. |
| | | - The PCL tutorial scan remains subject to the upstream PCL data repository's |
| | | licensing and attribution terms; it is validation input only and is not |
| | | cleared here for commercial redistribution. |
| | | - WebODM is AGPL-3.0. NodeODX/ODX, OpenSfM/OpenDroneMap, their images, and any |
| | | cloud processing service require separate license and data-handling review. |
| | | |
| | | ## Human annotation and supervised CPU training |
| | | |
| | | The workbench now provides a separate human annotation and supervised training |
| | | area. A semantic run writes a 400,000-point `*.semantic-annotation-source.ply` |
| | | that preserves observed RGB and coordinates. Rule-coloured previews are never |
| | | used as model inputs or ground truth. Brush and rectangle selections are saved |
| | | as separate revisions under `shared/outputs/05-3d-pointcloud/annotations/<annotation-id>/`. |
| | | The annotation viewer renders observed RGB through an sRGB-correct, anti-aliased |
| | | circular point sprite. It separates navigation from annotation: browse mode |
| | | uses left-drag rotation, while brush/rectangle mode reserves left-drag for |
| | | labels and retains right-drag rotation, middle-drag panning and wheel zoom. |
| | | Middle-button auto-scroll is suppressed within the viewer. The rotate-centre |
| | | tool sets the camera target to a clicked visible point without creating a label. |
| | | The model-orientation control independently rotates the displayed model about |
| | | its centre on local X/Y/Z axes from 0 through 360 degrees. It is a viewer-only |
| | | transform: source coordinates, semantic outputs and saved point indices remain |
| | | unchanged, while point picking and rectangle selection use the transformed view. |
| | | A saved revision is never edited in place. If it contains an error, the console |
| | | can remove that selected revision after confirmation; it cannot delete source |
| | | LAS/PLY data, semantic results, or training outputs. Each revision records |
| | | source run/checksum, point indices, class codes and time. |
| | | |
| | | `train_pointcloud_semantic_model.py` trains a compact PointNet-style shared MLP |
| | | from user-confirmed labels only. It runs locally with `--device cpu` and later |
| | | uses the same code/data with `--device cuda`. Training requires two or more |
| | | classes and at least 500 confirmed points per class, partitions XY blocks into |
| | | train/validation/test, and writes `model.pt`, `metrics.json`, a predicted PLY, |
| | | per-class precision/recall/F1 and a confusion matrix. Metrics apply only to the |
| | | labelled source blocks and are not field-wide accuracy claims. |
| | | |
| | | CPU validation `validation-las-part01-semantic-20260822-v11-original-rgb` processed unchanged |
| | | `baseData/las/part_01.las` in 73.586 seconds and created its 400,000-point RGB |
| | | annotation source. Its 3,183 pole/tower and 8,162 power-line results remain rule |
| | | candidates until users supply labels and supervised evaluation is completed. |
| | | |
| | | ## Applying a trained model |
| | | |
| | | The supervised model can be applied to a new coloured PLY, PCD, LAS, or LAZ |
| | | point cloud without retraining. This is still B work: PyTorch, Open3D, NumPy, |
| | | and Laspy perform inference; `geoai-py` is not a built-in point-cloud semantic |
| | | classifier. |
| | | |
| | | The input must contain readable observed RGB values. XYZ-only inputs fail rather |
| | | than inventing colour features. Coordinates remain unchanged. XYZ features are |
| | | normalised using the new input's own centre and extent, matching the feature |
| | | definition used during training without forcing the old scene coordinates onto a |
| | | new site. |
| | | |
| | | ```powershell |
| | | .\.venvs\05-3d-pointcloud\Scripts\python.exe ` |
| | | .\capabilities\05-3d-pointcloud\apply_pointcloud_semantic_model.py ` |
| | | --model .\shared\outputs\05-3d-pointcloud\training-runs\<model-id>\model.pt ` |
| | | --input .\path\to\new-rgb-cloud.las ` |
| | | --output .\shared\outputs\05-3d-pointcloud\model-inference-runs\<new-run-id> ` |
| | | --device cpu |
| | | ``` |
| | | |
| | | Each new output directory contains `predicted-semantic-preview.ply` (a |
| | | class-aware deterministic browser preview capped at 400,000 points), |
| | | `predicted-semantic-classified.las` (LAS classification codes), |
| | | `class-counts.csv`, `prediction-summary.json`, and `run_metadata.json` with |
| | | model/input SHA-256 values, versions, normalisation, class counts, runtime, and |
| | | limitations. No vector asset layer is fabricated from semantic predictions. |
| | | |
| | | Verified CPU check on 2026-08-24: model |
| | | `semantic-model-20260824-023343-571983` applied to the 400,000-point RGB |
| | | annotation source in 1.608 seconds through the CLI. The local-console upload and |
| | | background-job route was also verified, including PLY and classified-LAS artifact |
| | | download. This verifies the workflow, not field accuracy. Its labelled spatial |
| | | test F1 is vegetation 0.979, power line 0.815, and pole/tower 0.348; the latter |
| | | has substantial false-positive risk and all output remains review candidates. |