Thin Plate Spline Mapping

1.1.1 개요

Thin plate spline mapping은 주로 비선형 변환을 수행할 때 사용되는 보간 기법으로, 점 사이의 부드러운 변형을 지원하며 이미지 워핑, 얼굴 매칭, 3D 모델링 등 다양한 분야에서 활용됩니다. 이 기법의 이름은 얇은 철판(thin plate)이 휘어지는 물리적 성질에서 유래했으며, 변형을 적용할 때 최소한의 에너지를 사용하여 가장 부드럽게 곡선을 그리는 방식입니다. 이는 주어진 두 지점 간의 변형을 자연스럽게 이어주는 역할을 합니다.

1.1.2 기본 동작

Source control point와 Target control point를 설정하고 알고리즘을 동작하면 Control point 사이의 모든 위치에 대해 이차적인 곡선을 따라 부드러운 표면의 값을 계산하여 좌표 변환이 가능합니다. 아래의 이미지는 빨간색 Source control Point와 파란색 Target control point를 설정하여 Mapping을 진행한 후에, 그 사이의 좌표들을 변환한 결과입니다. Source -> Target 으로 변환이 가능하며, Target -> Source 로의 복원 변환도 지원합니다.

Thin Plate Spline Mapping 변환 결과
Fig. Thin Plate Spline Mapping 변환 결과

1.1.3 세부 동작

Mapping 할 범위에 해당되는 Control point들을 설정하고 Finish 함수를 호출하여 Mapping을 진행합니다. Mapping이 완료되면 Save 함수를 통해 파일에 저장이 가능하며, 세팅이 완료된 상태에서 변환을 진행합니다.

1.1.3.1 Control Point 설정

AddControlPoint 함수를 통해 Mapping할 범위의 Source 좌표와 Target 좌표를 설정합니다.

CThinPlateSplineMapping tpsMapping;
tpsMapping.AddControlPoint(flpSource, flpTarget);
CThinPlateSplineMapping tpsMapping = new CThinPlateSplineMapping();
tpsMapping.AddControlPoint(flpSource, flpTarget);
tpsMapping = CThinPlateSplineMapping()
tpsMapping.AddControlPoint(flpSource, flpTarget)

1.1.3.2 Mapping

Control Point를 모두 설정하였으면, Finish 함수를 호출하여 설정한 데이터를 통해 Mapping을 진행합니다. Finish 함수 동작에 성공하면 좌표변환을 사용할 수 있으며, Save 함수로 Mapping 데이터를 파일로 저장하여 이후 실행에서 Finish 함수 없이 데이터를 Load 하여 바로 재사용이 가능합니다.

if(tpsMapping.Finish().IsOK())
{
    tpsMapping.Save(L"C:/Manual/MappingData.fltps");
}
if(tpsMapping.Finish().IsOK())
{
    tpsMapping.Save("C:/Manual/MappingData.fltps");
}
if tpsMapping.Finish().IsOK():
    tpsMapping.Save("C:/Manual/MappingData.fltps")

데이터가 있을 경우 Finish 없이 Load 하여 사용 가능

 tpsMapping.Load(L"C:/Manual/MappingData.fltps");
tpsMapping.Load("C:/Manual/MappingData.fltps");
tpsMapping.Load("C:/Manual/MappingData.fltps")

1.1.3.3 좌표 변환 및 검증

ConvertSourceToTarget 함수를 사용하여 범위 내의 임의의 좌표를 변환할 수 있습니다. ConvertTargetToSource 함수를 사용하면 Target에 해당하는 임의의 좌표를 본래 Source 좌표로 역변환 할 수 있습니다.

 tpsMapping.ConvertSourceToTarget(flpSource, flpTarget);
tpsMapping.ConvertSourceToTarget(flpSource, ref flpTarget);
tpsMapping.ConvertSourceToTarget(flpSource, flpTarget)
 tpsMapping.ConvertTargetToSource(flpTarget, flpConvertedSource);
tpsMapping.ConvertTargetToSource(flpTarget, ref flpConvertedSource);
tpsMapping.ConvertTargetToSource(flpTarget, flpConvertedSource)