Vtk,(visualization toolkit)是一个开源的免费软件系统,主要用于三维计算机图形学、图像处理和可视化。
VTK编程中主要用到的几个对象 vtkRenderer ,vtkRenderWindow,vtkActor,vtkMapper,其渲染场景如下图所示(图片来自东灵工作室博客) 在VTK的封装类中有一个专门为用三维杂序点进行重建曲面的类:vtkSurfaceReconStructionFilter,用法如下代码
#include "vtkRenderer.h" #include "vtkRenderWindow.h" #include "vtkRenderWindowInteractor.h" #include "vtkDoubleArray.h" #include "vtkCamera.h" #include "vtkPolyDataMapper.h" #include "vtkPointData.h" #include "vtkActor.h" #include "vtkProperty.h" #include "vtkSmartPointer.h" #include "vtkCamera.h" #include "vtkPoints.h" #include "vtkCellArray.h" #include "vtkSurfaceReconstructionFilter.h" #include "vtkContourFilter.h" #include "vtkColorTransferFunction.h" #include "vtkFloatArray.h" #include "vtkLookupTable.h" void main() { double pts[90][3] = { {-66.86613555, -15.37129518, -1.46109303}, {-63.50111262, -15.39360582, -1.42579352}, {-60.14054701, -15.41253741, -1.35936929}, {-56.77259559, -15.43453109, -1.28025259}, {-53.39760281, -15.46061016, -1.21183624}, {-50.01931678, -15.47979721, -1.13792528}, {-46.63485969, -15.50477386, -1.04673482}, {-43.24944983, -15.51889706, -0.93241489}, {-39.85608627, -15.54185755, -0.81250043}, {-36.45658892, -15.56413378, -0.70419848}, {-33.05726092, -15.57931762, -0.59383403}, {-29.64176959, -15.59570483, -0.47579830}, {-26.22753520, -15.61633956, -0.35447626}, {-22.80893579, -15.63382247, -0.24179654}, {-19.38948014, -15.64980505, -0.10829890}, {-15.96237648, -15.66633908, 0.02885251}, {-12.53531382, -15.68483294, 0.17521597}, {-9.11300888, -15.69815189, 0.34004644}, {-5.68584107, -15.70172520, 0.52212893}, {-2.24439145, -15.71884642, 0.69806322}, {1.18757124, -15.73626126, 0.90753476}, {4.61785265, -15.75580746, 1.14952645}, {8.06161398, -15.76796698, 1.45781831}, {11.51229876, -15.78690032, 1.76816861}, {14.99239390, -15.80860091, 1.97760383}, {18.47639638, -15.81547177, 2.06419612}, {21.94924482, -15.81428189, 1.98127065}, {25.41689354, -15.81542406, 1.76967423}, {28.87542580, -15.80926747, 1.57866627}, {32.33834264, -15.79571493, 1.41242164}, {35.80684444, -15.79097267, 1.30735241}, {39.27610309, -15.79300531, 1.23871364}, {42.74527805, -15.79203661, 1.19851593}, {46.22405520, -15.78999737, 1.17620413}, {49.72172758, -15.79560644, 1.14144294}, {53.19109547, -15.79205115, 1.16761234}, {56.68482902, -15.79497856, 1.16506005}, {60.17640268, -15.78780256, 1.19856109}, {63.66701816, -15.77626843, 1.23841060}, {67.16524986, -15.77233422, 1.26941066}, {70.66300124, -15.75908281, 1.28802443}, {74.16788876, -15.75381248, 1.29174331}, {77.67216724, -15.74308501, 1.31570711}, {81.18653982, -15.74007265, 1.34906857}, {84.69322354, -15.73775855, 1.38790555}, {-66.71551168, -18.58176397, -1.42658500}, {-63.33137250, -18.57804840, -1.39207017}, {-59.96784443, -18.60021979, -1.32443957}, {-56.59482914, -18.62727782, -1.25235909}, {-53.22406065, -18.66065285, -1.17658921}, {-49.84839845, -18.67752379, -1.08362602}, {-46.46434000, -18.69720275, -0.98611151}, {-43.07768236, -18.71746605, -0.87308283}, {-39.68102222, -18.74177776, -0.76380339}, {-36.28148354, -18.77150552, -0.66341288}, {-32.87773767, -18.78892764, -0.54612610}, {-29.46414801, -18.80573588, -0.42962725}, {-26.05306322, -18.82442890, -0.30998017}, {-22.63369254, -18.84875538, -0.20557495}, {-19.21083196, -18.86908237, -0.08174312}, {-15.78255539, -18.88573089, 0.04592415}, {-12.35216519, -18.90642420, 0.17856646}, {-8.92430533, -18.92026678, 0.33663118}, {-5.48916601, -18.93123777, 0.49188004}, {-2.04901375, -18.94876927, 0.65084508}, {1.38383046, -18.96823282, 0.83653353}, {4.82318066, -18.99209573, 1.04541979}, {8.27350396, -19.01476635, 1.26816461}, {11.72442851, -19.03754426, 1.49306617}, {15.19277923, -19.04737422, 1.65359806}, {18.67213835, -19.06622167, 1.71350768}, {22.14305915, -19.05553337, 1.66391618}, {25.60806383, -19.06221171, 1.52556772}, {29.06747470, -19.05900092, 1.38099561}, {32.54039319, -19.05046573, 1.25731971}, {36.01017096, -19.04771303, 1.17897233}, {39.47749871, -19.05119856, 1.11799090}, {42.94914353, -19.05337810, 1.08090714}, {46.43235136, -19.05840592, 1.05110734}, {49.92868079, -19.06107017, 1.02851649}, {53.40689486, -19.05908369, 1.04612148}, {56.89682093, -19.05793113, 1.06394371}, {60.38615604, -19.05615188, 1.07610977}, {63.88089266, -19.05394355, 1.10209738}, {67.38361779, -19.05853399, 1.10583032}, {70.88005211, -19.04991379, 1.12797225}, {74.38553140, -19.03656088, 1.13285509}, {77.88358227, -19.02216068, 1.18255000}, {81.39315883, -19.01505009, 1.21189356}, {84.90954822, -19.02367087, 1.23875988} }; vtkLookupTable *pColorTable=vtkLookupTable::New(); pColorTable->SetNumberOfColors(6); pColorTable->SetTableValue(0,1,0,0,1); pColorTable->SetTableValue(1,0,0,1,1); pColorTable->SetTableValue(2,1,1,1,1); pColorTable->SetTableValue(3,1,1,1,1); pColorTable->SetTableValue(4,1,1,0,1); pColorTable->SetTableValue(5,1,1,0,1); pColorTable->Build(); double meanX,meanY,meanZ; meanX=meanY =meanZ=0; // maxz=pts[0][2]; // minz=pts[0][2]; for(int p=0;p<90;p++) { meanX=meanX+pts[p][0]; meanY=meanY+pts[p][1]; meanZ=meanZ+pts[p][2]; } meanX=meanX/90; meanY=meanY/90; meanZ=meanZ/90; vtkCamera *myCamer=vtkCamera::New(); myCamer->SetClippingRange(0.01,1000);//设定远、近裁减平面 myCamer->SetFocalPoint(meanX+20,meanY+20,meanZ);//设定焦点位置 myCamer->SetPosition(meanX,meanY+80,meanZ+80);//设定相机位置 myCamer->SetViewUp(0.0,0,1.0);//设定相机向上方向 myCamer->ComputeViewPlaneNormal();//设定视平面法线 myCamer->SetEyeAngle(0);//设定视角 vtkSmartPointer<vtkRenderer>ren=vtkSmartPointer<vtkRenderer>::New(); //设置绘制者(绘制对象指针) vtkSmartPointer<vtkRenderWindow>renWin=vtkSmartPointer<vtkRenderWindow>::New(); //设置绘制窗口 ren->SetActiveCamera(myCamer); vtkSmartPointer<vtkRenderWindowInteractor>iren=vtkSmartPointer<vtkRenderWindowInteractor>::New();//设置绘制交互操作窗口的 vtkSmartPointer<vtkPoints>m_Points=vtkSmartPointer<vtkPoints>::New(); vtkSmartPointer<vtkCellArray>vertices=vtkSmartPointer<vtkCellArray>::New(); //_读进点云数据信息 vtkFloatArray *scalars =vtkFloatArray::New(); for(int i=0;i<90;i++) { m_Points->InsertPoint(i,pts[i][0],pts[i][1],pts[i][2]); //cout<<pts[i][0]<<" "<<pts[i][1]<<" "<<pts[i][2]<<endl; } vtkSmartPointer<vtkPolyData>points=vtkSmartPointer<vtkPolyData>::New(); points->SetPoints(m_Points); // points->SetPolys(vertices); //points->GetPointData()->SetScalars(scalars); vtkSmartPointer<vtkSurfaceReconstructionFilter>surf=vtkSmartPointer<vtkSurfaceReconstructionFilter>::New(); surf->SetInput(points); vtkSmartPointer<vtkContourFilter>contour=vtkSmartPointer<vtkContourFilter>::New(); contour->Update(); vtkSmartPointer<vtkPolyData>points1=contour->GetOutput(); int e; e= points1->GetNumberOfPoints(); double* xinxi; double zhong=0; double maxz,minz; xinxi=points1->GetPoint(0); for(int k4=0;k4<e;k4++) { xinxi=points1->GetPoint(k4); //cout<<xinxi[0]<<" "<<xinxi[1]<<" "<<xinxi[2]<<endl; if(xinxi[2]>3) { scalars->InsertTuple1(k4,0); } else { scalars->InsertTuple1(k4,1); } } points1->GetPointData()->SetScalars(scalars); // points1->GetPointData()->SetScalars(scalars); vtkSmartPointer<vtkPolyDataMapper>pointMapper=vtkSmartPointer<vtkPolyDataMapper>::New(); pointMapper->SetInput(points1); //pointMapper->SetInput(contour->GetOutput()); pointMapper->SetScalarRange(0,1); //pointMapper->SetScalarRange(1,0.1); pointMapper->SetLookupTable(pColorTable); vtkSmartPointer<vtkActor>actor=vtkSmartPointer<vtkActor>::New(); actor->SetMapper(pointMapper); ren->AddActor(actor); renWin->AddRenderer(ren); renWin->SetSize(800,800); iren->SetRenderWindow(renWin); renWin->Render(); iren->Start(); }代码中
vtkSmartPointer<vtkSurfaceReconstructionFilter>surf=vtkSmartPointer<vtkSurfaceReconstructionFilter>::New(); surf->SetInput(points);用来根据点集进行三维曲面的重建 重建后曲面的点数会进行一定的扩充,如我用了90个点进行曲面的重建,进行拟合后的曲面实际的点数为326个,这个在进行颜色的映射时要注意;
for(int p=0;p<90;p++) { meanX=meanX+pts[p][0]; meanY=meanY+pts[p][1]; meanZ=meanZ+pts[p][2]; } meanX=meanX/90; meanY=meanY/90; meanZ=meanZ/90; vtkCamera *myCamer=vtkCamera::New(); myCamer->SetClippingRange(0.01,1000);//设定远、近裁减平面 myCamer->SetFocalPoint(meanX+20,meanY+20,meanZ);//设定焦点位置 myCamer->SetPosition(meanX,meanY+80,meanZ+80);//设定相机位置 myCamer->SetViewUp(0.0,0,1.0);//设定相机向上方向 myCamer->ComputeViewPlaneNormal();//设定视平面法线 myCamer->SetEyeAngle(0);//设定视角由于是三维杂序点,所以曲面重建的位置不固定所以需要对视角进行调整,来适合视角;
vtkLookupTable *pColorTable=vtkLookupTable::New(); pColorTable->SetNumberOfColors(6); pColorTable->SetTableValue(0,1,0,0,1); pColorTable->SetTableValue(1,0,0,1,1); pColorTable->SetTableValue(2,1,1,1,1); pColorTable->SetTableValue(3,1,1,1,1); pColorTable->SetTableValue(4,1,1,0,1); pColorTable->SetTableValue(5,1,1,0,1); pColorTable->Build();为建立颜色的映射表
for(int k4=0;k4<e;k4++) { xinxi=points1->GetPoint(k4); //cout<<xinxi[0]<<" "<<xinxi[1]<<" "<<xinxi[2]<<endl; if(xinxi[2]>3) { scalars->InsertTuple1(k4,0); } else { scalars->InsertTuple1(k4,1); } }为进行颜色的映射 这里要注意进行曲面重建后的坐标点的位置已经改变,如我这里按z的值进行颜色映射,原来z的值有正有负,重建后z的值都转换为正值。 最后重建效果: 有时候,你想证明给一万个人看,到后来,你发现只得到了一个明白的人,那就够了。
相关资源:基于vtk的彩色面绘制