Surface Match 3D
1 개요
레퍼런스 3D 표면 객체와 가장 유사한 표면을 찾는 알고리즘입니다.
2 알고리즘 상세 설명
Reference Surface | Source | 3D Match Result |
---|---|---|
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
Face 데이터 유무에 관계 없이 법선 벡터와 포인트 클라우드 정보만을 사용해 Reference 데이터와 가장 유사한 표면을 찾습니다. 위 사진의 첫 번째 예시와 같이 여러 객체를 한 번에 탐지하는 동작이 가능하며, 두 번째 예시와 같이 정확도 높은 3D 포즈 변화 측정도 가능합니다.
3 Reference 표면 데이터 생성 방법
3D Reference 표면 데이터는 아래와 같은 방법으로 생성할 수 있습니다.
3.1 반복 Crop을 통한 생성 방법
Realsense D405 카메라 포인트 클라우드 | Crop 영역 지정 |
---|---|
![]() |
![]() |
- 위 사진의 왼쪽과 같은 3D Object를 촬영한 후, 찾고자 하는 표면과 유사한 부분을 Crop합니다. 원하는 영역의 Crop을 위해 FLImaging® 3D Viewer에서 Shift + Drag 동작 후 우클릭 시 나타나는 팝업메뉴에서 Crop 버튼을 클릭합니다. Ctrl + Shift + Drag시 선택된 영역 중 원하는 영역을 취소할 수 있습니다.
Crop된 포인트 클라우드 | 반복 수행 한 결과 |
---|---|
![]() |
![]() |
- 위 사진의 왼쪽은 Fig. Realsense D405 카메라로 촬영한 데이터의 오른쪽 사진을 Crop한 결과이며 오른쪽 사진은 해당 동작을 반복 수행한 결과입니다.
3.2 클러스터링을 사용한 방법
아래와 같은 데이터에서 유의미한 표면 데이터 영역을 쉽게 지정할 수 있습니다.
구조광 카메라 포인트 클라우드 | FLImaging® Surface Match 3D GUI |
---|---|
![]() |
![]() |
Cluster Learn Object Dialog | Cluster 동작 결과 |
![]() |
![]() |
FLImaging®의 3D Viewer에 포인트 클라우드 데이터를 로드한 후, Surface Match 3D의 Learn 3D View에 해당 3D Viewer를 지정합니다. 3D Viewer를 지정한 뒤 Cluster Learn Object 버튼을 눌러 Cluster Learn Object Dialog를 띄웁니다.
-
Auto Radius : 내부적으로 Cluster의 최소 거리를 자동 계산
-
Radius : Auto Radius 체크박스 체크 해제 후 값 입력 시 사용자가 지정한 최소 거리로 Cluster 생성
-
Min Count : Cluster를 이루는 최소 개수
Cluster 지정 | Cluster 지정 후 Learn Data 생성 결과 |
---|---|
![]() |
![]() |
왼쪽 사진의 Result Dialog에서 원하는 영역을 Shift, Ctrl 키를 사용해 연속 혹은 개별 지정합니다.
Fig. FLImaging® GUI Cluster 동작 방법의 Cluster Learn Object Dialog의 Learn 버튼 동작 시 오른쪽과 같은 Reference Data를 생성할 수 있습니다.
Crop 동작 결과 | Crop 미동작 결과 |
---|---|
![]() |
![]() |
-
Crop 버튼 동작 시 Reference Object의 전체/부분 출력 차이만 있으며, 결과 차이는 발생하지 않습니다.
-
ClusterLearn3DObject(float f32Radius, bool bAutoRadius, int64_t i64MinCount)
- f32Radius : 점 간 최소 거리
- bAutoRadius : 점 간 최소 거리 자동 계산
- i64MinCount : Cluster 최소 개수
-
FLImaging® GUI에서 동일한 파라미터로 설정 후 결과를 얻을 수 있습니다. 결과는 CFLArray[GroupIndex] = {Vertex Indices} 형식으로 되어 있으며,
SetLearnCluster(CFLArray<int64_t> flaCluster)
멤버함수를 사용해 설정할 수 있습니다.
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();
4 학습 데이터 Save & Load 방법 설명
학습한 데이터 파일을 저장 및 불러오기가 가능합니다. 가장 마지막으로 실행하였던 파라미터와 함께 저장되므로, 저장된 시점의 환경을 불러올 수 있습니다.
4.1 Save 동작 설명
학습을 진행한 후 해당 학습 데이터 파일을 *.flsm(Surface Match) *.flvm(Vertex Match)
확장자로 저장할 수 있습니다.
Save(CFLString<wchar_t> strFilePath)
- strFilePath : 저장할 파일 경로
CSurfaceMatch3D surfaceMatch3D;
CFL3DObject floLearnObjectData;
surfaceMatch3D.SetLearnObject(floLearnObjectData);
surfaceMatch3D.Learn();
surfaceMatch3D.Save(L"파일 경로//*.flsm"); // Vertex Match 3D : *.flvm
4.2 Load 동작 설명
저장된 시점의 파라미터 및 학습 데이터를 불러온 뒤 바로 검사에 사용할 수 있습니다.
Load(CFLString<wchar_t> strFilePath)
- strFilePath : 데이터 파일 경로
CSurfaceMatch3D surfaceMatch3D;
CFL3DObject floSourceObjectData;
surfaceMatch3D.Load(L"파일 경로//*.flsm"); // Vertex Match 3D : *.flvm
surfaceMatch3D.SetSourceObject(floSourceObjectData);
surfaceMatch3D.Execute();
5 파라미터 설정 및 사용 방법
Sampling Distance : 0.01 | 0.03 | 0.05 | 0.07 | ![]() |
![]() |
![]() |
![]() |
---|

SetSceneSamplingDistance(double f64Distance)
SetLearnSamplingDistance(double f64Distance)
- f64Distance : Voxel Grid 샘플링 거리
- Default Value : 0.03
- Recommended Value : 0.01 ~ 0.1

-
EnableTrainEdge(bool bTrainEdge)
-
EnableBackgroundRemoval(bool bBackgroundRemoval)
- Default Value : false
- 3D Object의 Edge Point(Sharp Feature) 사용 여부
-
SetTrainEdgeThreshold(double f64Threshold)
-
SetSceneEdgeThreshold(double f64Threshold)
- f64Threshold
- Default Value : 0.01
- Recommended Value : 0.005 ~ 0.05
- Sampling된 점의 Curvature가 설정된 Threshold 값 보다 큰 점을 Edge(Sharp Feature)로 탐지합니다. 해당 점의 Curvature가 크다면 해당 점이 평면에 놓여있지 않을 확률이 높으므로 이를 Edge로 간주합니다.
-
SetEulerSequence(Foundation::EEulerSequence eOrder)
- 결과 행렬의 Euler Sequence를 설정합니다.
- eOrder : 결과 행렬의 Euler Sequence
- Default Value : EEulerSequence_Extrinsic_ZYX
-
SetClusterRange(double f64Range)
- 3D Match 결과의 주변 포즈 허용 범위를 설정합니다.
- f64Range : Reference Object의 Bounding Box 중심점과의 거리 배율
- Default Value : 0.02
- Recommended Value : 0.001 ~ 0.1
-
SetIntersectionThreshold(double f64IntersectionThreshold)
- 3D Match 결과의 주변 포즈와 겹치는 비율의 임계 값을 설정합니다.
- Default Value : 0.2
- Recommended Value : 0.01 ~ 0.3
-
SetKeyPointRatio(double f64Ratio)
- 샘플링 된 점들 중 사용할 점들의 비율을 설정합니다.
- Default Value : 0.5
- Recommended Value : 0.1 ~ 1
-
SetMinScore(double f64MinScore)
- 탐색에서 허용될 수 있는 결과 점수를 설정합니다.
- Default Value : 0.5
- Recommended Value : 0.5, 0.6, 0.7
-
SetMaxObject(int32_t i32MaxObject)
- 탐색에서 허용될 수 있는 결과 점수를 설정합니다.
- i32MaxObject : 0 설정 시 현재 설정된 MinScore 기준을 충족하는 모든 결과를 반환합니다.
- Default Value : 0
- Recommended Value : 0 ~ 1
-
SetInitialScore(double f64InitialScore)
- 초기 탐색 결과의 Score 비율을 설정합니다. 초기 탐색 결과 중 가장 높은 Score *f64InitialScore보다 낮은 초기 Score를 가진 포즈를 제외합니다.
- Default Value : 0.3
- Recommended Value : 0.1, 0.2, 0.3, 0.4, 0.5
![]() |
![]() |
-
EnableNoiseReduction(bool bNoiseReduction)
- 분포가 고르지 않은 Point Cloud를 제거합니다.
- Default Value : false
-
SetNoiseReductionIteration(int32_t i32Iteration)
- Noise Reduction 동작의 반복 횟수를 설정합니다.
- Default Value : 2
6 알고리즘 수행 결과 취득 방법
결과는 전체 3D Pose Parameter의 Euler Angle 및 Sequence, Rotation Vector, Translation Vector, Score 및 Residual을 반환합니다.
SPoseMatrixParameters
- tp3Angle : 오일러 각도
- tp3RotationVector : 회전 벡터
- tp3TranslationVector : 이동 벡터
- f64Score : 점수
- f64Residual : 잔차
- EEulerSequence : 탐색 시 설정한 오일러 순서
개별 결과는 아래의 GetResultPoseMatrix()
함수를 통해 얻어올 수 있습니다.
-
GetResultPoseMatrix(int64_t i64Index, SPoseMatrixParameters sResult)
- i64Index : 개별 요소의 인덱스 값
- sResult : 결과 구조체
-
GetResultPoseMatrix(int64_t i64Index, CMatrix<float or double> matResult)
- i64Index : 개별 요소의 인덱스 값
- matResult : 결과 변환 행렬
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();