Surface Match 3D

1 개요

레퍼런스 3D 표면 객체와 가장 유사한 표면을 찾는 알고리즘입니다.

2 알고리즘 상세 설명

Reference Surface Source 3D Match Result
Reference Data Source Data Result Data
Reference Data2 Source Data2 Result Data2
Fig. Surface Match 3D 동작 예시

Face 데이터 유무에 관계 없이 법선 벡터와 포인트 클라우드 정보만을 사용해 Reference 데이터와 가장 유사한 표면을 찾습니다. 위 사진의 첫 번째 예시와 같이 여러 객체를 한 번에 탐지하는 동작이 가능하며, 두 번째 예시와 같이 정확도 높은 3D 포즈 변화 측정도 가능합니다.

3 Reference 표면 데이터 생성 방법

3D Reference 표면 데이터는 아래와 같은 방법으로 생성할 수 있습니다.

3.1 반복 Crop을 통한 생성 방법

Realsense D405 카메라 포인트 클라우드 Crop 영역 지정
Realsense Data Crop Area
Fig. Realsense D405 카메라로 촬영한 데이터

Crop된 포인트 클라우드 반복 수행 한 결과
Cropped Data Result Reference
Fig. Crop 영역 및 반복 수행 결과


3.2 클러스터링을 사용한 방법

아래와 같은 데이터에서 유의미한 표면 데이터 영역을 쉽게 지정할 수 있습니다.

구조광 카메라 포인트 클라우드 FLImaging® Surface Match 3D GUI
Reference Data Cluster GUI
Cluster Learn Object Dialog Cluster 동작 결과
Cluster Result Crop Result
Fig. FLImaging® GUI Cluster 동작 방법

FLImaging®의 3D Viewer에 포인트 클라우드 데이터를 로드한 후, Surface Match 3D의 Learn 3D View에 해당 3D Viewer를 지정합니다. 3D Viewer를 지정한 뒤 Cluster Learn Object 버튼을 눌러 Cluster Learn Object Dialog를 띄웁니다.

Cluster 지정 Cluster 지정 후 Learn Data 생성 결과
Cluster Dialog Learn Result
Fig. Cluster 결과 영역 지정

왼쪽 사진의 Result Dialog에서 원하는 영역을 Shift, Ctrl 키를 사용해 연속 혹은 개별 지정합니다.

Fig. FLImaging® GUI Cluster 동작 방법의 Cluster Learn Object Dialog의 Learn 버튼 동작 시 오른쪽과 같은 Reference Data를 생성할 수 있습니다.

Crop 동작 결과 Crop 미동작 결과
Cluster Dialog Learn Result
Fig. Crop 버튼 동작에 따른 매치 결과 차이

3.2.1 Cluster 예제 코드

CSurfaceMatch3D surfaceMatch3D;
CFL3DObject floLearnObject;
CFLArray<CFLArray<int64_t>> flaResultCluster;
int64_t i64MinCount = 0; // Cluster를 이루는 포인트 클라우드의 최소 개수

surfaceMatch3D.SetLearnObject(floLearnObject);
surfaceMatch3D.ClusterLearn3DObject(0, true, i64MinCount, flaResultCluster); // bAutoRadius 설정 시 f32Radius값을 설정하여도 반영되지 않습니다.

int64_t i64GroupCount = flaResultCluster.GetCount(); // i64MinCount보다 개수가 높은 Cluster 배열의 개수

CFLArray<int64_t> flaIndices;
int64_t i64SelectIndex = 0;
int64_t i64GroupPointCount = flaResultCluster[i64SelectIndex].GetCount();_

for(int64_t i = 0; i < i64GroupPointCount; ++i) // 원하는 Group의 Cluster를 가져옵니다.
	flaIndices.PushBack(flaResultCluster[i64SelectIndex].GetAt(i));

surfaceMatch3D.SetLearnCluster(flaIndices);
surfaceMatch3D.Learn();

CSurfaceMatch3D surfaceMatch3D = new CSurfaceMatch3D();
CFL3DObject floLearnObject = new CFL3DObject();
List<List<long>> listResultCluster = new List<List<long>>();
long i64MinCount = 0; // Cluster를 이루는 포인트 클라우드의 최소 개수

surfaceMatch3D.SetLearnObject(ref floLearnObject);
surfaceMatch3D.ClusterLearn3DObject(0, true, i64MinCount, ref listResultCluster); // bAutoRadius 설정 시 f32Radius값을 설정하여도 반영되지 않습니다.

long i64GroupCount = listResultCluster.Count; // i64MinCount보다 개수가 높은 Cluster 배열의 개수
int i32SelectIndex = 0;
long i64GroupPointCount = listResultCluster[i64SelectIndex].Count;_

List<long> ListIndices = new List<long>();

for(int i = 0; i < i64GroupPointCount; ++i) // 원하는 Group의 Cluster를 가져옵니다.
	ListIndices.Add(listResultCluster[i32SelectIndex][i]);

surfaceMatch3D.SetLearnCluster(ListIndices);
surfaceMatch3D.Learn();
surfaceMatch3D = CSurfaceMatch3D()
floLearnObject = CFL3DObject()
listResultCluster = List[List[Int64]]()
i64MinCount = 0 # Cluster를 이루는 포인트 클라우드의 최소 개수

surfaceMatch3D.SetLearnObject(floLearnObject)
surfaceMatch3D.ClusterLearn3DObject(0, True, i64MinCount, listResultCluster) # bAutoRadius 설정 시 f32Radius값을 설정하여도 반영되지 않습니다.

i64GroupCount = listResultCluster.Count # i64MinCount보다 개수가 높은 Cluster 배열의 개수
i32SelectIndex = 0
i64GroupPointCount = listResultCluster[i32SelectIndex].Count

ListIndices = List[Int64]()

# 원하는 Group의 Cluster를 가져옵니다.
for i in range(0, i64GroupPointCount) : 
	ListIndices.Add(listResultCluster[i32SelectIndex][i])

surfaceMatch3D.SetLearnCluster(ListIndices)
surfaceMatch3D.Learn()

4 학습 데이터 Save & Load 방법 설명

학습한 데이터 파일을 저장 및 불러오기가 가능합니다. 가장 마지막으로 실행하였던 파라미터와 함께 저장되므로, 저장된 시점의 환경을 불러올 수 있습니다.

4.1 Save 동작 설명

학습을 진행한 후 해당 학습 데이터 파일을 *.flsm(Surface Match) *.flvm(Vertex Match)확장자로 저장할 수 있습니다.

CSurfaceMatch3D surfaceMatch3D;
CFL3DObject floLearnObjectData;

surfaceMatch3D.SetLearnObject(floLearnObjectData);
surfaceMatch3D.Learn();

surfaceMatch3D.Save(L"파일 경로//*.flsm"); // Vertex Match 3D : *.flvm
CSurfaceMatch3D surfaceMatch3D = new CSurfaceMatch3D();
CFL3DObject floLearnObjectData = new CFL3DObject();

surfaceMatch3D.SetLearnObject(ref floLearnObjectData);
surfaceMatch3D.Learn();
surfaceMatch3D.Save("파일 경로//*.flsm"); // Vertex Match 3D : *.flvm
surfaceMatch3D = CSurfaceMatch3D()
floLearnObjectData = CFL3DObject()

surfaceMatch3D.SetLearnObject(floLearnObjectData)
surfaceMatch3D.Learn()
surfaceMatch3D.Save("파일 경로//*.flsm") # Vertex Match 3D : *.flvm

4.2 Load 동작 설명

저장된 시점의 파라미터 및 학습 데이터를 불러온 뒤 바로 검사에 사용할 수 있습니다.

CSurfaceMatch3D surfaceMatch3D;
CFL3DObject floSourceObjectData;

surfaceMatch3D.Load(L"파일 경로//*.flsm"); // Vertex Match 3D : *.flvm
surfaceMatch3D.SetSourceObject(floSourceObjectData);
surfaceMatch3D.Execute();
CSurfaceMatch3D surfaceMatch3D = new CSurfaceMatch3D();
CFL3DObject floSourceObjectData = new CFL3DObject();

surfaceMatch3D.Load("파일 경로//*.flsm"); // Vertex Match 3D : *.flvm
surfaceMatch3D.SetSourceObject(ref floSourceObjectData);
surfaceMatch3D.Execute();
surfaceMatch3D = CSurfaceMatch3D()
floSourceObjectData = CFL3DObject()

surfaceMatch3D.Load("파일 경로//*.flsm") # Vertex Match 3D : *.flvm
surfaceMatch3D.SetSourceObject(floSourceObjectData)
surfaceMatch3D.Execute()

5 파라미터 설정 및 사용 방법

Learn/Find 공통 파라미터

Sampling Distance : 0.01 0.03 0.05 0.07
Cluster Dialog Learn Result Cluster Dialog Learn Result
Learn Result
Fig. Sampling 결과

Learn Result
Fig. Edge(Sharp Feature) Sampling 결과

Find 파라미터

Cluster Dialog Cluster Dialog
Fig. Noise Reduction 결과

6 알고리즘 수행 결과 취득 방법

결과는 전체 3D Pose Parameter의 Euler Angle 및 Sequence, Rotation Vector, Translation Vector, Score 및 Residual을 반환합니다.

개별 결과는 아래의 GetResultPoseMatrix() 함수를 통해 얻어올 수 있습니다.

7 예제 코드

CSurfaceMatch3D surfaceMatch3D;
CFL3DObject floLearnObjectData;
CFL3DObject floSourceObjectData;

floLearnObjectData.Load(L"C:\\Users\\Public\\Documents\\FLImaging\\ExampleImages\\SurfaceMatch3D\\Car wheel example.ply");
floSourceObjectData.Load(L"C:\\Users\\Public\\Documents\\FLImaging\\ExampleImages\\SurfaceMatch3D\\Car example.ply");

surfaceMatch3D.SetLearnObject(floLearnObjectData);
surfaceMatch3D.Learn();

surfaceMatch3D.SetSourceObject(floSourceObjectData);
surfaceMatch3D.Execute();
CSurfaceMatch3D surfaceMatch3D = new CSurfaceMatch3D();
CFL3DObject floLearnObjectData = new CFL3DObject();
CFL3DObject floSourceObjectData = new CFL3DObject();

floLearnObjectData.Load("C:\\Users\\Public\\Documents\\FLImaging\\ExampleImages\\SurfaceMatch3D\\Car wheel example.ply");
floSourceObjectData.Load("C:\\Users\\Public\\Documents\\FLImaging\\ExampleImages\\SurfaceMatch3D\\Car example.ply");

surfaceMatch3D.SetLearnObject(ref floLearnObjectData);
surfaceMatch3D.Learn();

surfaceMatch3D.SetSourceObject(ref floSourceObjectData);
surfaceMatch3D.Execute();
surfaceMatch3D = CSurfaceMatch3D()
floLearnObjectData = CFL3DObject()
floSourceObjectData = CFL3DObject()

floLearnObjectData.Load("C:\\Users\\Public\\Documents\\FLImaging\\ExampleImages\\SurfaceMatch3D\\Car wheel example.ply")
floSourceObjectData.Load("C:\\Users\\Public\\Documents\\FLImaging\\ExampleImages\\SurfaceMatch3D\\Car example.ply")

surfaceMatch3D.SetLearnObject(floLearnObjectData)
surfaceMatch3D.Learn()

surfaceMatch3D.SetSourceObject(floSourceObjectData)
surfaceMatch3D.Execute()