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的值都转换为正值。
最后重建效果:
有时候,你想证明给一万个人看,到后来,你发现只得到了一个明白的人,那就够了。
时间: 2024-10-26 21:22:42