【作用】:将自己的三维点云数据与金标准数据进行配准,计算俩个模型的距离,利用VTK(DistancePolyDataFilter)生成热图,将误差直观化。
直接上代码:(注:本代码是搬运其它博客而来,但原文没有说明怎么进行配置,我对此进行了补充,原文内容我将放于文后)
源码
#include <vtkSmartPointer.h>
#include <vtkSTLReader.h>
#include <vtkLookupTable.h>
#include <vtkActor.h>
#include <vtkDistancePolyDataFilter.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkPolyDataReader.h>
#include <vtkCleanPolyData.h>
#include <vtkProperty.h>
#include <vtkPointData.h>
#include <vtkScalarBarActor.h>
#include <vtkSphereSource.h>
#include <vtkNamedColors.h>
#include <vtkPolyDataWriter.h>
#include<vtkTextProperty.h>
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} )
结果:
注:本代码需要用cmake进行编译,将VTK的环境配置进去。如果运行过程发生以下错误:
0x00007FFADED8AA70 (vtkCommonColor-8.2.dll)处(位于 Head_Map.exe 中)引发的异常: 0xC0000005: 读取位置 0x000000C5F4100000 时发生访问冲突。
最简单的方法是将debug模式改为release模式即可。
参考文章链接:
https://blog.youkuaiyun.com/weixin_44723106/article/details/107056931
https://blog.youkuaiyun.com/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