Landmark를 가지고 있는 경우 source -> target으로 정합한 매트릭스를 반환한다.
void myLandmarkTransform(vtkSmartPointer<vtkPolyData> source, vtkSmartPointer<vtkPolyData> target)
{
vtkSmartPointer<vtkLandmarkTransform> landmarkTransform = vtkSmartPointer<vtkLandmarkTransform>::New();
landmarkTransform->SetSourceLandmarks(source->GetPoints());
landmarkTransform->SetTargetLandmarks(target->GetPoints());
landmarkTransform->SetModeToRigidBody(); // 형태를 유지한다;
landmarkTransform->Update();
vtkSmartPointer<vtkTransformPolyDataFilter> transformFilter = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
transformFilter->SetInputData(source);
transformFilter->SetTransform(landmarkTransform);
transformFilter->Update();
vtkMatrix4x4* mat = landmarkTransform->GetMatrix();
std::cout << "Matrix: " << *mat << std::endl;
source->ShallowCopy(transformFilter->GetOutput());
}
vtkLandmarkTransform 의 사용법은 간단하다.
이동을 시킬 vtkPoints 를 SetSourceLandmarks 에 넣고
정합 대산인 vtkPoints 를 SetTargetLandmarks 에 넣는다.
모드를 설정한 뒤 Update() 를 호출한다. 정합 모드는 VTK_LANDMARK_SIMILARITY 가 기본 값이다.
vtkLandmarkTransform은 3가지의 모드가 있다.
landmarkTransform->SetModeToRigidBody() : rotation and traslation only
landmarkTransform->SetModeToSimilarity() : rotation and traslation and isotropic scaling (default)
landmarkTransform->SetModeToAffine()
- 정합 전 (source : white, target : red)
- 정합 후
정합 후 결과 확인을 위한 Sample Code (두 Polydata의 점이 완전히 쌍을 이루는 경우)
double calculateDistanceBetweenPoints(vtkSmartPointer<vtkPoints> p0, vtkSmartPointer<vtkPoints> p1)
{
double totalDistance = 0;
double averageDistance = 0;
if (p0->GetNumberOfPoints() == p1->GetNumberOfPoints() && p0->GetNumberOfPoints() != 0)
{
int numPoints = p0->GetNumberOfPoints();
double squaredDistance;
for (int i = 0; i < numPoints; i++)
{
squaredDistance = vtkMath::Distance2BetweenPoints(p0->GetPoint(i), p1->GetPoint(i));
totalDistance += sqrt(squaredDistance);
}
averageDistance = totalDistance / numPoints;
}
return averageDistance;
}
댓글 없음:
댓글 쓰기