计算俩个模型的距离,利用VTK生成热图

【作用】:将自己的三维点云数据与金标准数据进行配准,计算俩个模型的距离,利用VTK(DistancePolyDataFilter)生成热图,将误差直观化。
  直接上代码:(注:本代码是搬运其它博客而来,但原文没有说明怎么进行配置,我对此进行了补充,原文内容我将放于文后)

源码

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include

int main(int argc, char *argv[]) {
    vtkSmartPointer<vtkPolyData> input1;
    vtkSmartPointer<vtkPolyData> input2;
    
    vtkSmartPointer<vtkSTLReader> reader1 =
        vtkSmartPointer<vtkSTLReader>::New();
    reader1->SetFileName("E:/MyProject/Heat_Map/src/data/head-1.stl");//输入模型1的数据
    reader1->Update();
    input1 = reader1->GetOutput();
    vtkSmartPointer<vtkSTLReader> reader2 =
        vtkSmartPointer<vtkSTLReader>::New();
    reader2->SetFileName("E:/MyProject/Heat_Map/src/data/head-2.stl");//输入模型2的数据
    reader2->Update();
    input2 = reader2->GetOutput();

    vtkSmartPointer<vtkNamedColors> colors =
        vtkSmartPointer<vtkNamedColors>::New();

    vtkSmartPointer<vtkCleanPolyData> clean1 =
        vtkSmartPointer<vtkCleanPolyData>::New();
    clean1->SetInputData(input1);

    vtkSmartPointer<vtkCleanPolyData> clean2 =
        vtkSmartPointer<vtkCleanPolyData>::New();
    clean2->SetInputData(input2);

    vtkSmartPointer<vtkDistancePolyDataFilter> distanceFilter =
        vtkSmartPointer<vtkDistancePolyDataFilter>::New();
    distanceFilter->SetInputConnection(0, clean1->GetOutputPort());
    distanceFilter->SetInputConnection(1, clean2->GetOutputPort());
    distanceFilter->Update();
  
    // VTK 保存
    vtkSmartPointer<vtkPolyDataWriter> vtkWriter = vtkSmartPointer<vtkPolyDataWriter>::New();
    vtkWriter->SetInputConnection(distanceFilter->GetOutputPort());
    vtkWriter->SetFileName("E:/MyProject/Heat_Map/src/save/Distance.vtk");
    vtkWriter->Write();
    vtkWriter->Update();
    
//修改色调颜色由蓝到红
    vtkSmartPointer<vtkLookupTable> lut =
        vtkSmartPointer<vtkLookupTable>::New();
    lut->SetHueRange(0.6667, 0.0);//大致走向(0.83, 0.0)色调从红色到蓝色,(0,0.67)蓝色到红色
//    lut->SetAlphaRange(1.0, 1.0);
//    lut->SetValueRange(1.0, 1.0);
//    lut->SetSaturationRange(1.0, 1.0);
//    lut->SetNumberOfTableValues(256);
//    lut->SetRange(scalarRange);
    lut->Build();

    vtkSmartPointer<vtkPolyDataMapper> mapper =
        vtkSmartPointer<vtkPolyDataMapper>::New();
    mapper->SetInputConnection(distanceFilter->GetOutputPort());
    mapper->SetLookupTable(lut);
//    mapper->SetScalarRange(
//    distanceFilter->GetOutput()->GetPointData()->GetScalars()->GetRange()[0],
//    distanceFilter->GetOutput()->GetPointData()->GetScalars()->GetRange()[1]);//获取映射的范围
    mapper->SetScalarRange(0.2, 2);//设置映射的范围
    
    vtkSmartPointer<vtkActor> actor =
        vtkSmartPointer<vtkActor>::New();
    actor->SetMapper(mapper);
    //vtkScalarBar用于绘制分级的颜色图例,一般与vtkLookupTable配套使用
    vtkSmartPointer<vtkScalarBarActor> scalarBar =
        vtkSmartPointer<vtkScalarBarActor>::New();
    scalarBar->SetLookupTable(mapper->GetLookupTable());
    scalarBar->SetTitle("Distance");
    scalarBar->SetNumberOfLabels(10);//设置要显示的刻度标签数。
    //自己设定色带的位置
    scalarBar->GetPositionCoordinate()->SetCoordinateSystemToNormalizedViewport();
    scalarBar->GetPositionCoordinate()->SetValue(0.01, 0.49);//参数越小越靠左,第二个参数越大越往上
    scalarBar->SetWidth(0.16);
    scalarBar->SetHeight(0.5);
    // scalarBar->SetTextPositionToPrecedeScalarBar();//标题和刻度标记是否应在标量栏之前(文字会出现在条形左边)
    //设置标题和条形之间的边距
    scalarBar->SetVerticalTitleSeparation(10);
    //设置标题颜色
    scalarBar->GetTitleTextProperty()->SetColor(0.0, 0.0, 0.0);

    vtkSmartPointer<vtkRenderer> renderer =
        vtkSmartPointer<vtkRenderer>::New();
    renderer->SetBackground(colors->GetColor3d("Silver").GetData());//调整背景颜色
    renderer->SetBackground2(colors->GetColor3d("Gold").GetData());//调整背景颜色
    renderer->GradientBackgroundOn();

    vtkSmartPointer<vtkRenderWindow> renWin =
        vtkSmartPointer<vtkRenderWindow>::New();
    renWin->AddRenderer(renderer);

    vtkSmartPointer<vtkRenderWindowInteractor> renWinInteractor =
        vtkSmartPointer<vtkRenderWindowInteractor>::New();
    renWinInteractor->SetRenderWindow(renWin);

    renderer->AddActor(actor);
    renderer->AddActor2D(scalarBar);

    renWin->Render();
    renWinInteractor->Start();

    return EXIT_SUCCESS;
}

cmakelists:

配置该文件使用到了cmake,下面是配置文件cmakelists:

cmake_minimum_required(VERSION 3.0)
PROJECT(Head_Map)
set(CMAKE_AUTOMOC ON)
# Set (BASEDIR "E:/MyProject/Heat_Map/src")

#vtk
find_package(VTK REQUIRED)
include(${VTK_USE_FILE})
link_directories(${VTK_LIBRARY_DIRS})

FILE(GLOB SRC_FILES "./*.cpp")
            
ADD_EXECUTABLE(Head_Map ${SRC_FILES})

TARGET_LINK_LIBRARIES( Head_Map ${VTK_LIBRARIES} )

结果:

计算俩个模型的距离,利用VTK生成热图_第1张图片
注:本代码需要用cmake进行编译,将VTK的环境配置进去。如果运行过程发生以下错误:
0x00007FFADED8AA70 (vtkCommonColor-8.2.dll)处(位于 Head_Map.exe 中)引发的异常: 0xC0000005: 读取位置 0x000000C5F4100000 时发生访问冲突。
计算俩个模型的距离,利用VTK生成热图_第2张图片
最简单的方法是将debug模式改为release模式即可。

参考文章链接:

https://blog.csdn.net/weixin_44723106/article/details/107056931

https://blog.csdn.net/a15005784320/article/details/104857883?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165642204116781818790911%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=165642204116781818790911&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-2-104857883-null-null.142v24huaweicloudv2,157v15new_3&utm_term=DistancePolyDataFilter&spm=1018.2226.3001.4187

你可能感兴趣的:(c++,计算机视觉,3d)