VTK Landmark配准

来源:互联网 发布:订酒店哪个软件好 知乎 编辑:程序博客网 时间:2024/05/25 21:34

1、Landmark是vtk中比较经典的配准算法之一,基于标记点,使两个点集在配准后的平均距离最小,输入为两个点集(点数相等),做线性变换,适用于粗配准,优点是效率高,需要注意的是源标记点集和目标标记点集序号要对应。示例代码如下:
vtkLandmarkTransform使用简单,只需设置源标记点和目标标记点。

 vtkSmartPointer<vtkLinearTransform> transform =      LandmarkReg(pointsTreated, pointsNontreated); DxMatrix4x4 matrix = TransformActor(transform, sourceActor);
vtkSmartPointer<vtkLandmarkTransform> LandmarkReg(    vtkSmartPointer<vtkPoints> points1, vtkSmartPointer<vtkPoints> points2){    vtkSmartPointer<vtkLandmarkTransform> landmarkTransform =         vtkSmartPointer<vtkLandmarkTransform>::New();    landmarkTransform->SetSourceLandmarks(points1);//设置源点集    landmarkTransform->SetTargetLandmarks(points2);//设置目标点集    landmarkTransform->SetModeToRigidBody();//指定刚性变换(移动+旋转),还支持SetModeToSimilarity设置相似变换(平移 + 旋转 + 缩放),SetModeToAffine 放射变换,默认为相似变换。    landmarkTransform->Modified();    landmarkTransform->Update();    return landmarkTransform;}DxMatrix4x4 TransformActor(vtkSmartPointer<vtkLinearTransform> transform, vtkSmartPointer<vtkActor> actor){   return TransformActor(transform->GetMatrix(), actor);}DxMatrix4x4 TransformActor(vtkSmartPointer<vtkMatrix4x4> matrix, vtkSmartPointer<vtkActor> actor)//配准结果应用于源actor{    vtkSmartPointer<vtkMatrix4x4> orgMatrix = actor->GetUserMatrix();    vtkSmartPointer<vtkMatrix4x4> newMatrix = vtkSmartPointer<vtkMatrix4x4>::New();    vtkMatrix4x4::Multiply4x4(matrix, orgMatrix, newMatrix);    actor->SetUserMatrix(newMatrix);    DxMatrix4x4 dxMatrix;    dxMatrix.FromVtkMatrix4x4(newMatrix);    return dxMatrix;}

下面是将变所得变换应用于点集的两种方法
方法1、

 DxPoint newPoint(transform->TransformPoint(point.X(), point.Y(), point.Z()), 3);

方法2、(比较麻烦,先将点集生成polydata,然后对polydata进行变换,再从polydata中得到对应的点集)

void TransformMarrowAxisPolydata( QVector<DxPoint> &MarrowAxis, vtkSmartPointer<vtkAbstractTransform> transform ){      //将点集生成polydata   vtkSmartPointer<vtkPolyData> MarrowAixsPolyData = vtkSmartPointer<vtkPolyData>::New();      vtkSmartPointer<vtkPoints> MarrowAixsPoints =  vtkSmartPointer<vtkPoints>::New();      vtkSmartPointer<vtkCellArray> MarrowAxisVertices =  vtkSmartPointer<vtkCellArray>::New();      DxPoint StartPoint = MarrowAxis[0];      DxPoint EndPoint = MarrowAxis[1];      vtkIdType pid[2];      pid[0]  = MarrowAixsPoints->InsertNextPoint(StartPoint.X(),StartPoint.Y(),StartPoint.Z());      pid[1]  = MarrowAixsPoints->InsertNextPoint(EndPoint.X(),EndPoint.Y(),EndPoint.Z());      MarrowAxisVertices->InsertNextCell(2,pid);      MarrowAixsPolyData->SetPoints(MarrowAixsPoints);//几何机构      MarrowAixsPolyData->SetVerts(MarrowAxisVertices);//拓扑结构     //对polydata应用变换      vtkSmartPointer<vtkTransformPolyDataFilter> transformFilter =          vtkSmartPointer<vtkTransformPolyDataFilter>::New();      transformFilter->SetInputData(MarrowAixsPolyData);      transformFilter->SetTransform(transform);      transformFilter->Update();      MarrowAixsPolyData->ShallowCopy(transformFilter->GetOutput());     //从变换后的Polydata得到点集    MarrowAixsPoints = MarrowAixsPolyData->GetPoints();      double startPoint[3];      double endPoint[3];      MarrowAixsPoints->GetPoint(0,startPoint);      MarrowAixsPoints->GetPoint(1,endPoint);      MarrowAxis.clear();      MarrowAxis.push_back(DxPoint(startPoint[0],startPoint[1],startPoint[2]));      MarrowAxis.push_back(DxPoint(endPoint[0],endPoint[1],endPoint[2]));}
原创粉丝点击