Normals

Getting your point cloud ready for your application 웨비나에서는 부분적으로 노멀을 다룹니다.

Introduction

이번 자료는 표면 법선(노멀)과, 노멀값을 Zivid SDK의 포인트 클라우드에서 계산하는 방법, 노멀이 중요한 기능인 이유에 대해 설명합니다. 마지막으로 코드 예제가 포함된 튜토리얼을 제공합니다.

표면 법선(Normal)은 기하학적 표면의 중요한 속성입니다. 포인트 클라우드의 특정 지점에서 표면의 접평면에 수직인 단위 벡터를 나타냅니다. 벡터이기 때문에 표면 법선은 각 요소의 범위가 -1에서 1인 3D 좌표를 설명하는 3개의 벡터 요소(x, y, z)로 구성됩니다. 평면의 모든 표면 법선은 평행하지만 구의 표면 법선은 가능한 모든 방향을 가리키고 있습니다.

법선은 표면 방향을 설명하고 법선의 변화율은 표면의 곡률을 설명합니다.

Normals in Zivid Studio

Normals 맵은 장면의 표면 Normals을 2D로 표현하며, RGB 색상 구성 요소는 Normals 벡터를 나타냅니다. Normals 벡터와 색상 구성 요소 간의 관계는 아래 이미지의 Normals 맵에서 빈 벽과 바닥을 통해 잘 표현됩니다. 이는 각 표면의 모든 점들이 거의 같은 방향을 가리키는 Normals 벡터를 가지고 있기 때문입니다.

Normals 맵의 색상 규칙은 camera coordinate system 와 음의 방향으로 정렬됩니다. 따라서 파란색 픽셀로 표현된 Normals 벡터는 카메라를 향해 수직을 향합니다. Normals 맵을 보면 파란색 픽셀이 상자 바닥에 있는 것을 볼 수 있습니다. 이 Normals 벡터는 카메라 좌표계 Z축의 음의 방향을 향합니다. 따라서 왼쪽 하단 모서리의 상태 표시줄은 [0, 0, -1]에 가까워집니다.

또한, 오른쪽 빈 벽은 빨간색 픽셀이 지배적입니다. 이 Normals은 카메라 좌표계의 X축과 음의 방향으로 정렬되어 있습니다. 이는 표면의 Normals 벡터가 장면에서 왼쪽을 향함을 의미합니다. 마찬가지로, 아래쪽 빈 벽은 법선이 장면에서 위쪽을 향하고 있으므로 녹색으로 표시됩니다. 따라서 상태 표시줄은 빨간색 픽셀의 경우 [-1, 0, 0]에 가깝고, 녹색 픽셀의 경우 [0, -1, 0]에 가깝습니다.

../../_images/normal-map.png

결과적으로, Normals 맵은 포인트 클라우드에서 평면을 확인하는 데 유용합니다. 또한 Normals 맵은 표면 곡률, 표면 질감, 그리고 객체 간 전환을 검사하는 데에도 유용합니다. 색상 그라디언트가 이러한 요소들을 잘 표현하기 때문입니다.

Normals API

소스로 이동

source

std::cout << "Computing normals and copying them to CPU memory" << std::endl;
const auto normals = pointCloud.copyData<Zivid::NormalXYZ>();
소스로 이동

source

Console.WriteLine("Computing normals and copying them to CPU memory");
var normals = pointCloud.CopyNormalsXYZ();
소스로 이동

source

print("Computing normals and copying them to CPU memory")
normals = point_cloud.copy_data("normals")

Normals API는 포인트 클라우드의 각 지점에서 노멀을 계산하고 GPU 메모리에서 CPU 메모리로 노멀을 복사합니다. 결과는 입력한 포인트 클라우드의 각 포인트에 대해 하나씩, 법선 벡터의 행렬로 얻을 수 있습니다. 노멀의 크기는 입력 포인트 클라우드의 크기와 같습니다.

참고

Zivid SDK의 Normals API는 포인트 클라우드 데이터가 GPU 메모리에 있는 동안 GPU에서 병렬로 계산이 수행되기 때문에 빠릅니다. 타사 라이브러리로 법선을 계산하는 것은 더 많은 시간이 소요될 수 있습니다. 일반적으로 CPU 계산은 훨씬 느리고 GPU 계산에는 다른 사본이 필요합니다. 자세한 내용은 Point Cloud Capture Process 를 참조하세요.

이미 버퍼가 있는 경우 다음을 사용하여 GPU 메모리에서 대상 버퍼로 직접 데이터를 복사할 수 있습니다. copyData 템플릿 매개변수로 NormalXYZ.

  • 포인트 클라우드 데이터가 GPU 메모리에 있는 동안 GPU가 이러한 모든 계산을 수행하기 때문에 보다 뛰어난 퍼포먼스를 위해 Zivid SDK를 통해 Normals, Downsample 및 Transform API 사용을 추천드립니다.

  • 최고의 성능을 위해 먼저 포인트 클라우드를 다운샘플링한 다음 노멀을 계산합니다.

  • 노멀은 포인트 클라우드의 복사를 요청할 때 포인트 클라우드에서 계산됩니다. 포인트 클라우드와 동일한 좌표계의 노멀을 갖도록 포인트 클라우드를 먼저 변환한 후 노멀을 계산합니다.

  • 노멀을 변환하려면 먼저 포인트 클라우드를 변환한 다음 변환된 포인트 클라우드에서 노멀을 계산해야 합니다. 노멀만 변환하는 것은 불가능합니다.

Normals in applications

다양한 이유로 다양한 응용 프로그램에는 포인트 클라우드에서 노멀을 계산해야 합니다. 노멀은 표면 방향을 설명하고 노멀의 변화율은 표면의 곡률을 설명합니다.

노멀을 활용하는 응용 프로그램의 몇 가지 예로는 CAD 기반 및 표면 기반 일치, 가장자리 감지 및 노멀의 차이를 기반으로 하는 분할 알고리즘이 있습니다. 노멀은 또한 메싱 알고리즘 및 필터링 알고리즘에서 활용되어 포인트 클라우드 아티팩트 또는 이상값을 제거합니다. 예를 들어 카메라 원점에서 점까지의 선에 거의 수직인 법선은 인공물을 나타내며 필터링될 수 있습니다.

노멀 계산과 PCL을 사용한 시각화

이 튜토리얼은 Zivid 포인트 클라우드에서 노멀을 계산하고, 포인트 클라우드와 노멀을 PCL 형식으로 변환하여 노멀 맵으로 3D 시각화하는 방법을 보여줍니다.

먼저 카메라에 연결하고 포인트 클라우드를 캡처합니다.

소스로 이동

source

std::cout << "Connecting to camera" << std::endl;
auto camera = zivid.connectCamera();

std::cout << "Creating settings" << std::endl;
Zivid::Settings settings = Zivid::Settings{
    Zivid::Settings::Acquisitions{ Zivid::Settings::Acquisition{ Zivid::Settings::Acquisition{} } },
    Zivid::Settings::Color{
        Zivid::Settings2D{ Zivid::Settings2D::Acquisitions{ Zivid::Settings2D::Acquisition{} } } }
};

std::cout << "Capturing frame" << std::endl;
const auto frame = camera.capture2D3D(settings);
const auto pointCloud = frame.pointCloud();

그런 다음 포인트 클라우드의 노머을 계산합니다.

소스로 이동

source

std::cout << "Computing point cloud normals" << std::endl;
const auto normals = pointCloud.copyData<Zivid::NormalXYZ>();

그런 다음 포인트 클라우드와 노멀을 PCL 형식으로 변환합니다.

소스로 이동

source

std::cout << "Creating PCL point cloud structure" << std::endl;
const auto data = pointCloud.copyData<Zivid::PointXYZColorRGBA_SRGB>();
const auto pointCloudPCL = convertToPCLPointCloud(data);
std::cout << "Creating PCL normals structure suited for visualization" << std::endl;
const auto pointCloudWithNormalsPCL = convertToPCLVisualizationNormals(data, normals);

마지막으로 포인트 클라우드와 노멀을 3D로 시각화합니다.

소스로 이동

source

std::cout << "Visualizing normals" << std::endl;
visualizePointCloudAndNormalsPCL(pointCloudPCL.makeShared(), pointCloudWithNormalsPCL.makeShared());

Version History

SDK

Changes

2.15.0

Normals 의 모서리가 더욱 선명하고 사실적으로 개선되었습니다.

2.8.0

Zivid Studio에 Normals 맵 기능이 추가되었습니다.

2.5.0

Normals API가 추가되었습니다.