VTK 曲面构建+颜色映射

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的值都转换为正值。
最后重建效果:
这里写图片描述
这里写图片描述
有时候,你想证明给一万个人看,到后来,你发现只得到了一个明白的人,那就够了。

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值