Đọc một phần file point cloud khổng lồ: classification, octree và COPC cho dữ liệu LAS/LAZ/PTS
Một file LiDAR LAS/LAZ quét một nhà máy hay một tuyến đường có thể nặng vài chục GB và chứa hàng tỷ điểm. Phần lớn tác vụ thực tế — chỉ lấy điểm mặt đất, chỉ lấy một công trình trong một khu vực, hoặc chỉ tải bản xem trước độ phân giải thấp — không cần đọc toàn bộ file. Cách LAS/LAZ/PTS tổ chức classification, bounding box và octree, và cách PDAL, Entwine, COPC khai thác chúng để chỉ tải đúng phần điểm cần — giảm tải hệ thống và tăng tốc xử lý dữ liệu 3D quy mô lớn.
Một file LiDAR LAS/LAZ quét một khu nhà máy hoặc một tuyến đường có thể nặng vài chục GB và chứa hàng tỷ điểm — mỗi điểm là một tọa độ X, Y, Z cùng các thuộc tính như cường độ phản xạ, số lần phản hồi (return number) và mã phân loại (classification). Phần lớn tác vụ thực tế — "chỉ lấy các điểm thuộc mặt đất để dựng mô hình địa hình", "chỉ lấy các điểm trong bán kính 50m quanh một cột điện", "chỉ tải bản xem trước độ phân giải thấp" — không cần đọc toàn bộ file. Bài viết này phân tích cách các định dạng LAS, LAZ, PTS tổ chức dữ liệu theo classification, bounding box và cấu trúc không gian (octree), và cách các công cụ như PDAL, Entwine và COPC khai thác chúng để chỉ tải đúng phần điểm cần — giảm tải hệ thống và tăng tốc xử lý dữ liệu 3D quy mô lớn.
Bên trong file LAS/LAZ/PTS: header, point record và classification
Khác với ảnh raster hay bảng dữ liệu, một file point cloud là một danh sách điểm rời rạc trong không gian 3D — nhưng vẫn có cấu trúc rõ ràng mà engine có thể khai thác:
- Header — chứa bounding box toàn cục (min/max X, Y, Z), hệ quy chiếu (CRS) lưu trong Variable Length Record (VLR), point data record format và tổng số điểm. Đọc vài trăm byte đầu file là đủ biết toàn bộ phạm vi không gian của dữ liệu
- Point record — mỗi điểm mang tọa độ, intensity (cường độ phản xạ laser), return number (số lần tia laser phản hồi qua tán cây hoặc mái nhà), GPS time
- Classification — mã phân loại theo chuẩn ASPRS gán cho từng điểm: 2 = mặt đất, 3-5 = thực vật thấp/trung/cao, 6 = công trình xây dựng, 9 = nước, 7 = nhiễu... Đây chính là "class" mà mỗi điểm tự mang theo nhãn phân loại của nó
- PTS — định dạng đơn giản hơn, dạng text, mỗi dòng là X Y Z intensity [R G B]. Không có trường classification chuẩn hóa trong file, thường dùng làm input/output cho các bước phân loại bên ngoài trước khi nạp vào LAS
Lọc theo classification — chỉ đọc đúng "loại" điểm cần
PDAL (Point Data Abstraction Library) cho phép xây pipeline với filters.range, ví dụ Classification[2:2] để chỉ giữ điểm mặt đất khi dựng mô hình địa hình, hoặc Classification[6:6] để chỉ giữ điểm công trình khi tái tạo mô hình 3D nhà xưởng. Vấn đề là: nếu file chỉ được lưu tuần tự, việc lọc theo classification vẫn buộc engine đọc qua toàn bộ point record để kiểm tra từng điểm — giảm khối lượng xử lý ở tầng sau, nhưng không giảm I/O đọc file. Để giảm I/O thực sự, cần thêm một lớp index không gian.
Octree và Entwine Point Tile (EPT) — index không gian cho point cloud
Entwine xây một octree từ point cloud gốc: không gian 3D được chia đệ quy thành 8 ô (octant), mỗi node octree chứa một tập điểm con cùng bounding box và mức độ chi tiết (LOD) riêng. Cấu trúc Entwine Point Tile (EPT) lưu các node này thành các file riêng theo (level, x, y, z) — một truy vấn theo bounding box hoặc theo độ phân giải chỉ cần tải các node giao với vùng quan tâm, bỏ qua hoàn toàn các nhánh octree còn lại. Đây chính là "layout" phân cấp mà point cloud sử dụng thay cho row group của dữ liệu dạng bảng. Potree dùng chính cấu trúc octree này để stream point cloud hàng tỷ điểm lên trình duyệt, chỉ tải các node nằm trong viewport và ở mức LOD phù hợp với khoảng cách camera.
COPC — nhúng octree vào một file LAZ duy nhất, đọc qua HTTP range request
Cloud Optimized Point Cloud (COPC) đi xa hơn một bước: thay vì tách ra hàng nghìn file EPT riêng, COPC nhúng toàn bộ cấu trúc octree vào bên trong một file .laz duy nhất, dưới dạng VLR/EVLR mô tả offset và kích thước của từng node. Mỗi node octree là một chunk LAZ nén độc lập, giải mã được riêng biệt. Khi file COPC nằm trên S3 hay R2, PDAL hoặc lidR đọc phần header và hierarchy VLR trước — chỉ vài chục KB — rồi phát các HTTP Range request tương ứng đúng các chunk của những node cần, mà không cần convert sang EPT hay tải toàn bộ file về máy.
Nguyên tắc: chi phí thực của một truy vấn point cloud không phải là kích thước file .laz, mà là số node octree (chunk) thực sự cần tải và giải mã để trả lời câu hỏi không gian — phần còn lại của file không bao giờ được đọc từ disk hoặc tải qua network.
Trích xuất "object" — bounding volume cho một thực thể cụ thể
Một file point cloud quét toàn bộ nhà máy có thể chứa hàng tỷ điểm, nhưng một kỹ sư kết cấu chỉ cần dữ liệu của một bồn chứa hoặc một khung giàn cụ thể để so sánh hình dạng theo thời gian (deformation monitoring). Kết hợp ba lớp — classification để chỉ lấy điểm thuộc nhóm công trình, bounding box của riêng đối tượng đó, và octree để xác định node nào giao với bounding box — pipeline chỉ cần tải và giải mã một phần rất nhỏ của file gốc, thường dưới 1% tổng dữ liệu, để dựng lại đúng đối tượng cần theo dõi.
Ứng dụng tại KonexForge
Trong các pilot thuộc lớp IoT & Sensors, dữ liệu LiDAR từ drone hoặc máy quét mặt đất là một trong những nguồn dữ liệu vật lý có khối lượng lớn nhất mà chúng tôi xử lý — một lần quét định kỳ một nhà máy có thể tạo ra vài chục GB mỗi lượt. Với hệ thống giám sát kết cấu cho 4 nhà máy thép, chỉ tải đúng các node octree giao với khung kết cấu cần theo dõi — thay vì tải lại toàn bộ point cloud mỗi kỳ quét — giúp pipeline so sánh biến dạng chạy trong vài phút thay vì hàng giờ, và cho phép lưu trữ lịch sử quét trên object storage giá rẻ mà vẫn truy vấn trực tiếp được. Dữ liệu điểm sau khi lọc theo classification và bounding box thường được đẩy tiếp vào lớp Data Analytics để tính độ lệch và sinh cảnh báo.
Giới hạn — khi nào cần xử lý trước (preprocessing)
Octree và COPC chỉ phát huy hiệu quả khi cấu trúc index đã được xây từ trước — một file LAS thô mới quét xong chưa có hierarchy, nên lần đầu vẫn cần một bước build index (entwine build hoặc untwine cho COPC), tốn thời gian và compute một lần. Tương tự, nếu classification chưa được gán (file PTS thô, hoặc LAS chưa qua bước classify), việc lọc theo class sẽ không khả dụng cho đến khi chạy một bước phân loại — thường bằng thuật toán ground filtering (CSF, PMF) hoặc model học máy. Chi phí preprocessing này là một lần, nhưng cần được tính vào pipeline ngay từ đầu, không phải là bước "tùy chọn" thêm sau.
Kết luận
Giống như với dữ liệu dạng bảng, phần lớn chi phí xử lý point cloud không nằm ở việc "cần máy mạnh hơn", mà ở việc đọc nhiều hơn mức cần thiết. Classification cho biết "loại" điểm nào cần, bounding box cho biết "vùng" nào cần, và octree/COPC cho biết chính xác những byte nào trong file chứa đúng các điểm đó. Thiết kế pipeline để khai thác ba lớp này — ngay từ bước lưu trữ — là cách hiệu quả nhất để giữ hệ thống xử lý dữ liệu 3D quy mô lớn chạy nhanh và rẻ theo thời gian.