shuishen
10 hours ago fbb068ec702338d609c1ca6eddbdb9f182d8f211
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
from __future__ import annotations
 
import tempfile
import unittest
from pathlib import Path
 
import numpy as np
import open3d as o3d
 
import sys
 
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
from run_pointcloud_understanding import classify_semantic_points, process_point_cloud  # noqa: E402
 
 
def write_cloud(path: Path, points: np.ndarray) -> None:
    cloud = o3d.geometry.PointCloud()
    cloud.points = o3d.utility.Vector3dVector(points)
    assert o3d.io.write_point_cloud(str(path), cloud)
 
 
class PointCloudUnderstandingTests(unittest.TestCase):
    def test_raster_vector_and_mesh_are_created(self) -> None:
        with tempfile.TemporaryDirectory() as directory:
            root = Path(directory)
            rng = np.random.default_rng(2)
            ground = np.column_stack((rng.uniform(-4, 4, (600, 2)), rng.normal(0, 0.01, 600)))
            roof = np.column_stack((rng.uniform(-1, 1, (350, 2)), rng.normal(2, 0.02, 350)))
            source = root / "site.ply"
            write_cloud(source, np.vstack((ground, roof)))
            result = process_point_cloud(source, root / "output", voxel_size=0.2, ground_distance=0.1, elevated_threshold=0.6)
            self.assertGreater(result["elevated_points"], 0)
            self.assertGreater(result["elevated_footprint_count"], 0)
            self.assertEqual(result["coordinate_basis"], "local_point_cloud_coordinates")
            for field in ("dsm_file", "label_raster_file", "preview_file", "vector_file", "summary_file", "classified_point_cloud"):
                self.assertTrue((root / "output" / result[field]).is_file())
 
    def test_small_cloud_fails(self) -> None:
        with tempfile.TemporaryDirectory() as directory:
            root = Path(directory)
            source = root / "small.ply"
            write_cloud(source, np.zeros((4, 3)))
            with self.assertRaises(ValueError):
                process_point_cloud(source, root / "output")
 
    def test_semantic_rules_keep_unknown_and_identify_strong_candidates(self) -> None:
        ground = np.column_stack((np.linspace(0, 4, 20), np.zeros(20), np.zeros(20)))
        structure = np.column_stack((10 + np.linspace(0, 0.8, 20), np.zeros(20), np.full(20, 3.0)))
        vegetation = np.column_stack((20 + np.linspace(0, 0.8, 20), np.zeros(20), np.linspace(2.0, 3.5, 20)))
        wire = np.column_stack((30 + np.arange(20), np.zeros(20), np.linspace(6.0, 6.1, 20)))
        pole = np.column_stack((40 + np.zeros(20), np.zeros(20), np.linspace(1.0, 10.0, 20)))
        points = np.vstack((ground, structure, vegetation, wire, pole))
        heights = points[:, 2].copy()
        colors = np.full((len(points), 3), 0.5)
        colors[len(ground) + len(structure):len(ground) + len(structure) + len(vegetation)] = [0.15, 0.7, 0.15]
        labels = classify_semantic_points(points, colors, heights, voxel_size=0.2)
        self.assertIn(2, labels)
        self.assertIn(5, labels)
        self.assertIn(6, labels)
        self.assertIn(15, labels)
        self.assertIn(16, labels)
 
 
if __name__ == "__main__":
    unittest.main()