0
0
Lập trình
Harry Tran
Harry Tran106580903228332612117

Hình ảnh hóa dữ liệu đám mây điểm trung tâm dữ liệu với Python và Open3D

Đăng vào 4 tháng trước

• 8 phút đọc

Hình ảnh hóa dữ liệu đám mây điểm trung tâm dữ liệu với Python và Open3D

Trên thực tế, việc hình ảnh hóa dữ liệu đám mây điểm từ các quét LiDAR hoặc TLS trong nội thất trung tâm dữ liệu là rất quan trọng. Bài viết này sẽ hướng dẫn bạn từng bước từ việc kiểm tra, làm sạch cho đến hình ảnh hóa tương tác các đám mây điểm lớn bằng Python và Open3D. Chúng ta sẽ tìm hiểu cách đọc các định dạng phổ biến, xử lý nhanh (giảm mẫu, loại bỏ nhiễu, ước lượng pháp tuyến), tô màu theo cường độ, cắt/định nghĩa hộp bao, hình ảnh hóa nhiều đám mây và các mẹo để xử lý dữ liệu lớn.

Những gì bạn cần (các yêu cầu trước)

  • Python 3.9–3.11 (Open3D hỗ trợ các phiên bản này; hãy kiểm tra tài liệu mới nhất nếu bạn sử dụng phiên bản khác).
  • Open3D (hướng dẫn này sử dụng các khái niệm từ Open3D 0.19.x và các API của nó).
  • Tùy chọn: laspy (cho các tệp LAS/LAZ), numpy, matplotlib (cho các biểu đồ nhỏ), và API tensor của open3d nếu bạn muốn xử lý với GPU.

Cài đặt

Khuyến nghị: tạo một môi trường ảo và cài đặt thông qua pip:

bash Copy
python -m venv o3d-env  
souce o3d-env/bin/activate # Linux/macOS
# o3d-env\Scripts\activate # Windows
bash Copy
pip install --upgrade pip
pip install open3d numpy laspy matplotlib

Lưu ý: Kể từ Open3D v0.15, các gói Conda không còn được duy trì; hãy ưu tiên pip install open3d trong một môi trường ảo (Conda) nếu bạn sử dụng conda.

1 — Tải các đám mây điểm

Open3D có thể đọc các định dạng như PLY, PCD, OBJ trực tiếp với o3d.io.read_point_cloud. Đối với LAS/LAZ (thường dùng cho LiDAR), hãy sử dụng laspy để đọc và sau đó chuyển đổi sang PointCloud của Open3D.

Đọc PLY / PCD với Open3D

python Copy
import open3d as o3d

pcd = o3d.io.read_point_cloud("rack_room.ply") # hỗ trợ .ply, .pcd, .xyz...
print(pcd) # in số lượng điểm và thuộc tính
o3d.visualization.draw_geometries([pcd])

Đọc LAS/LAZ qua laspy → chuyển đổi sang Open3D

python Copy
import laspy
import open3d as o3d
import numpy as np

with laspy.open("site_scan.las") as fh:
    las = fh.read()
    coords = np.vstack((las.x, las.y, las.z)).transpose() # Nx3

pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(coords)

# Nếu LAS có cường độ, ánh xạ nó thành màu (đã chuẩn hóa)
if "intensity" in las.point_format.dimension_names:
    intensity = las.intensity.astype(np.float64)
    intensity = (intensity - intensity.min()) / (intensity.ptp() + 1e-8)
    colors = plt.get_cmap("viridis")(intensity)[:, :3]
    pcd.colors = o3d.utility.Vector3dVector(colors)

o3d.visualization.draw_geometries([pcd])

Nếu bạn thường xuyên xử lý LAS/LAZ, mẫu chuyển đổi này được cộng đồng sử dụng rộng rãi (các ví dụ cộng đồng / StackOverflow).

2 — Xử lý nhanh (các bước phổ biến)

Quét trung tâm dữ liệu có thể rất lớn và nhiễu. Các thao tác này là cần thiết trước khi hình ảnh hóa sâu hoặc đo lường.

2.1 Giảm mẫu voxel (nhanh)

python Copy
voxel_size = 0.02 # mét (điều chỉnh cho tập dữ liệu của bạn)
pcd_down = pcd.voxel_down_sample(voxel_size)

2.2 Loại bỏ nhiễu thống kê

python Copy
cl, ind = pcd_down.remove_statistical_outlier(nb_neighbors=20, std_ratio=2.0)
pcd_clean = pcd_down.select_by_index(ind)

2.3 Ước lượng pháp tuyến (cần thiết cho ánh sáng, tạo lưới, một số đăng ký)

python Copy
pcd_clean.estimate_normals(
    search_param=o3d.geometry.KDTreeSearchParamHybrid(radius=0.1, max_nn=30)
)
pcd_clean.normalize_normals()

2.4 Chuyển đổi thuộc tính cường độ hoặc nhiệt độ thành màu

Nếu đám mây điểm của bạn có các giá trị cường độ (hoặc kênh), hãy chuẩn hóa và ánh xạ qua một bản đồ màu:

python Copy
import numpy as np
import matplotlib.pyplot as plt

intensity = np.asarray(las.intensity) # ví dụ từ laspy

int_norm = (intensity - intensity.min()) / (intensity.ptp() + 1e-8)
colors = plt.get_cmap("plasma")(int_norm)[:, :3]
pcd.colors = o3d.utility.Vector3dVector(colors)

3 — Hình ảnh hóa với Open3D

3.1 Trình xem đơn giản

python Copy
o3d.visualization.draw_geometries([pcd_clean])

Nhấn H trong trình xem để thấy các điều khiển tích hợp (quay, phóng to, dịch chuyển, chụp màn hình, v.v.).

3.2 Hình ảnh hóa nhiều đám mây điểm với màu sắc khác nhau và hộp bao trong suốt

python Copy
pcd1 = pcd_clean # ví dụ, quét từ máy quét A
pcd2 = other_pcd_clean # máy quét B

pcd1.paint_uniform_color([0.9, 0.1, 0.1]) # đỏ
pcd2.paint_uniform_color([0.1, 0.9, 0.1]) # xanh

bbox = pcd_clean.get_axis_aligned_bounding_box()
bbox.color = (0, 0, 1) # xanh dương

o3d.visualization.draw_geometries([pcd1, pcd2, bbox])

3.3 Sử dụng trình xem tương tác (chọn điểm/lưới, callback)

Open3D cung cấp VisualizerWithKeyCallback và các API GUI để kiểm soát và tương tác nhiều hơn, ví dụ, để chọn điểm, ghi lại tham số camera, hoặc phản hồi với các phím. Xem hướng dẫn hình ảnh hóa tương tác để biết thêm ví dụ.

Ví dụ tối thiểu — lưu một ảnh chụp màn hình khi nhấn phím:

python Copy
vis = o3d.visualization.VisualizerWithKeyCallback()
vis.create_window()
vis.add_geometry(pcd_clean)

def capture(vis):
    vis.capture_screen_image("screenshot.png")
    print("Đã lưu ảnh chụp màn hình")
    return False

# gán phím 'S' (83) để chụp
vis.register_key_callback(ord("S"), capture)

vis.run()
vis.destroy_window()

4 — Hình ảnh hóa nâng cao & hiệu suất cho các quét lớn

4.1 Sử dụng voxel_down_sample một cách quyết liệt cho hình ảnh hóa tương tác

Các quét lớn (từ hàng chục đến hàng trăm triệu điểm) nên được giảm mẫu xuống còn vài triệu hoặc ít hơn để có tỷ lệ khung hình tương tác thoải mái.

4.2 Sử dụng API tensor của Open3D (t.geometry) và các backend thiết bị

Open3D có một API dựa trên tensor mới hơn (open3d.t.geometry.PointCloud) được tối ưu hóa cho quy mô lớn và (khi có sẵn) tăng tốc GPU. Nếu bạn thực hiện xử lý nặng (ICP, lọc) trên các quét lớn, hãy thử nghiệm API tensor và lựa chọn thiết bị.

4.3 Sử dụng cắt và quy trình ROI

Chỉ tải vùng bạn cần (ví dụ, một hàng giá đơn) để tăng tốc độ phát triển. Bạn có thể cắt bằng các hộp bao theo trục hoặc theo hướng:

python Copy
aabb = o3d.geometry.AxisAlignedBoundingBox(min_bound, max_bound)
roi = pcd_clean.crop(aabb)
o3d.visualization.draw_geometries([roi])

4.4 Ý tưởng tải tiến (streaming)

Đối với các dự án cực lớn, lưu trữ dữ liệu theo ô (theo phòng hoặc lưới), tải các ô cần thiết cho chế độ xem hiện tại. Đây là một mẫu cấp ứng dụng — Open3D không cung cấp máy chủ streaming ngay lập tức.

5 — Công thức hình ảnh hóa phổ biến & đoạn mã

5.1 Hiện pháp tuyến dưới dạng đường thẳng

python Copy
# tính toán pháp tuyến trước
pcd_clean.estimate_normals(search_param=o3d.geometry.KDTreeSearchParamKNN(knn=30))
python Copy
# tạo các đoạn thẳng cho việc hình ảnh hóa pháp tuyến
import numpy as np
points = np.asarray(pcd_clean.points)
normals = np.asarray(pcd_clean.normals)
lines = []
line_points = []
for i, (p, n) in enumerate(zip(points[:1000], normals[:1000])): # mẫu cho hiệu suất
    line_points.append(p)
    line_points.append(p + 0.05 * n) # mở rộng chiều dài pháp tuyến
    lines.append([2*i, 2*i + 1])

line_set = o3d.geometry.LineSet(
    points=o3d.utility.Vector3dVector(np.array(line_points)),
    lines=o3d.utility.Vector2iVector(np.array(lines))
)
o3d.visualization.draw_geometries([pcd_clean, line_set])

5.2 Tô màu theo chiều cao (Z)

python Copy
import numpy as np
pts = np.asarray(pcd_clean.points)
z = pts[:, 2]
z_n = (z - z.min()) / (z.ptp() + 1e-8)
colors = plt.get_cmap("viridis")(z_n)[:, :3]
pcd_clean.colors = o3d.utility.Vector3dVector(colors)
o3d.visualization.draw_geometries([pcd_clean])

5.3 So sánh hai đám mây (trước/sau) bên cạnh nhau với lớp đăng ký

Sử dụng các màu đồng nhất khác nhau và hiển thị cùng nhau (hoặc sử dụng độ trong suốt nhỏ thông qua chuyển đổi lưới). Để căn chỉnh, áp dụng ICP hoặc ICP màu từ các hướng dẫn Open3D.

6 — Xuất và ảnh chụp màn hình

Lưu PLY/PCD đã xử lý: o3d.io.write_point_cloud("cleaned.ply", pcd_clean)

Sử dụng vis.capture_screen_image("img.png") từ trình xem để có các ảnh chụp màn hình độ phân giải cao. Xem API Visualizer để điều khiển camera, lưu/xem.

7 — Ví dụ kịch bản end-to-end

Một ví dụ hoạt động ngắn gọn mà: đọc LAS → giảm mẫu → loại bỏ nhiễu → ước lượng pháp tuyến → tô màu theo cường độ → hình ảnh hóa.

python Copy
# file: visualize_datacenter.py
import open3d as o3d
import laspy
import numpy as np
import matplotlib.pyplot as plt

def read_las_to_o3d(fname):
    with laspy.open(fname) as fh:
        las = fh.read()
        coords = np.vstack((las.x, las.y, las.z)).transpose()
        pcd = o3d.geometry.PointCloud()
        pcd.points = o3d.utility.Vector3dVector(coords)
        if "intensity" in las.point_format.dimension_names:
            intensity = las.intensity.astype(np.float64)
            intensity = (intensity - intensity.min()) / (intensity.ptp() + 1e-8)
            colors = plt.get_cmap("viridis")(intensity)[:, :3]
            pcd.colors = o3d.utility.Vector3dVector(colors)
        return pcd

if __name__ == "__main__":
    pcd = read_las_to_o3d("datacenter_scan.las")
    print("Số điểm gốc:", len(pcd.points))

    pcd = pcd.voxel_down_sample(0.02)
    print("Sau khi giảm mẫu:", len(pcd.points))

    _, ind = pcd.remove_statistical_outlier(nb_neighbors=20, std_ratio=2.0)
    pcd = pcd.select_by_index(ind)
    print("Sau khi loại bỏ nhiễu:", len(pcd.points))

    pcd.estimate_normals(search_param=o3d.geometry.KDTreeSearchParamHybrid(radius=0.1, max_nn=30))

    o3d.visualization.draw_geometries([pcd])

8 — Mẹo, cạm bẫy & thực hành tốt nhất

  • Luôn giảm mẫu cho hình ảnh hóa tương tác. Các quét LiDAR thô có thể lên đến hàng trăm triệu điểm.
  • Ánh xạ cường độ thành màu để có cái nhìn nhanh (giá kim loại so với cáp có thể cho thấy sự tương phản về cường độ).
  • Sử dụng API tensor cho tính toán nặng và GPU nếu bạn có CUDA và phiên bản Open3D hỗ trợ.

Một số lưu ý:

  • Đọc LAS/LAZ: Open3D không đọc natively LAZ trong nhiều bản dựng; sử dụng laspy (hoặc PDAL) sau đó chuyển đổi.
  • Lưu ý về Conda: Nếu bạn phụ thuộc vào các gói conda cho môi trường của mình, hãy chú ý đến những thay đổi trong trình cài đặt Open3D kể từ v0.15; pip install open3d bên trong môi trường là con đường được khuyến nghị.

9 — Nơi học thêm / tài liệu tham khảo

  • Các hướng dẫn chính thức của Open3D: các khái niệm cơ bản về đám mây điểm, hình ảnh hóa, IO tệp, hình ảnh hóa tương tác, đăng ký. (Nguồn chính xác chính).
  • Open3D PyPI / ghi chú phát hành cho các phiên bản mới nhất và hướng dẫn cài đặt pip.
  • Các ví dụ cộng đồng (Medium, blog) và các chủ đề StackOverflow cho quy trình LAS → Open3D và xử lý LAZ.

Những ghi chú cuối

Hướng dẫn này bao gồm quy trình làm việc điển hình để khám phá và hình ảnh hóa các quét trung tâm dữ liệu với Open3D và Python, với mã hoạt động mà bạn có thể áp dụng. Nếu bạn muốn, tôi có thể:

  • Cung cấp một sổ tay Jupyter sẵn sàng chạy với các ví dụ và hình ảnh hóa trên.
  • Hiện một ví dụ tăng tốc GPU sử dụng open3d.t.geometry (nếu bạn có thể cho tôi biết bạn có CUDA/GPU không).
  • Thêm mã để phân mảnh/tải các quét rất lớn (hữu ích cho các trung tâm dữ liệu quy mô doanh nghiệp).
    Bạn muốn cái nào tiếp theo?

Nội dung bài viết

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào