参考文章:vmtk c++ vs2019安装过程
按照文章步骤配置包含目录,库目录,附加依赖项
配置lib文件时,快速读取文件名的代码:
#include
#include "windows.h"
#include
#include
#include
#include
#include
using namespace std;
//读取全部路径
void GetAllFormatFiles(string path, vector<string>& files, string format)
{
//文件句柄
long long hFile = 0;
//文件信息
struct _finddata_t fileinfo;
string p;
if ((hFile = _findfirst(p.assign(path).append("\\*" + format).c_str(), &fileinfo)) != -1)
{
do
{
if ((fileinfo.attrib & _A_SUBDIR))
{
if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)
{
//files.push_back(p.assign(path).append("\\").append(fileinfo.name) );
GetAllFormatFiles(p.assign(path).append("\\").append(fileinfo.name), files, format);
}
}
else
{
files.push_back(p.assign(path).append("\\").append(fileinfo.name));
}
} while (_findnext(hFile, &fileinfo) == 0);
_findclose(hFile);
}
}
//只读取文件名
void getFiles(string path, vector <string>& files)
{
long long hFile = 0;
struct _finddata_t fileinfo;
string pathp;
if ((hFile = _findfirst(pathp.assign(path).append("\\*").c_str(), &fileinfo)) != -1)
{
do
{
if ((fileinfo.attrib & _A_SUBDIR))
{
if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)
{
getFiles(pathp.assign(path).append("/").append(fileinfo.name), files);
}
}
else
{
string filestr = fileinfo.name;
files.push_back(filestr);
}
} while (_findnext(hFile, &fileinfo) == 0);
_findclose(hFile);
}
}
int main()
{
string filePath = "F:\\miniconda3\\envs\\foo\\Library\\lib";
vector<string> files;
const char* distAll = "AllFiles.txt";
//读取所有格式为txt的文件
string format = ".lib";
getFiles(filePath, files);
ofstream ofn(distAll);
int size = files.size();
ofn << size << endl;
for (int i = 0; i < size; i++)
{
ofn << files[i] << endl;
cout << files[i] << endl;
}
ofn.close();
return 0;
}
刚看到有个作者提出了一个更快获取lib文件的代码:
VS2019配置VMTK、VTK库
提取文件夹中.lib文件名称快速方法
记录一下作者的方法,下面是该作者的东西:
运行代码,
文章作者:机器人学渣
VTK(四)—VMTK血管中心线提取
报错,找不到vmtk的相关dll文件
百度如何配置dll路径,VS引用dll的目录配置
最终将F:\miniconda3\envs\foo\Library\bin目录下的所有文件复制到project下。
运行成功。
刚刚看到,说第一个方法我做了没用,是因为定义环境变量之后,必须要重启电脑。
头文件
F:\miniconda3\envs\foo\Library\include\vmtk\vtkvmtkPolyDataCenterlines.h
和
F:\miniconda3\envs\foo\Library\include\vmtk\vtkvmtkCapPolyData.h
报错“VTK_OVERRIDE”: 未知重写说明符
查看源代码,没有改动。
不知道如何解决,索性将VTK_OVERRIDE删除,竟然没有报错,不知道是什么原因。
COMPUTING CENTERLINES
中心线是对容器形状的有力描述。虽然什么是中心线的概念或多或少是直观的,但它们的数学定义并不独特。文献中已经提出了许多方法来计算从血管造影图像和三维模型的中心线。在vmtk中实现的算法从曲面模型开始计算中心线,具有很好的数学特性和对表面扰动相当稳定的优点。详情请参考出版物和卢卡的博士论文。
简单地说,中心线被确定为两个极值点之间的加权最短路径。为了确保最终的线实际上是中心的,路径不能位于空间的任何地方,而必须运行在容器模型的Voronoi图上。有大量关于Voronoi图的文献,但是,作为第一近似,你可以把它看作是最大内环线球的中心被定义的地方。当一个物体内的球面没有其他的球面包含它时,这个球面被称为最大值。因此,对于属于Voronoi图的每一个点,都有一个以该点为中心的球,这是一个最大内切球(因此,在Voronoi图中,与半径相关的信息被定义为处处)。
下面中间的图显示了与颈动脉分叉形状相关的Voronoi图(或者更准确地说,它的内部子集)。颜色是指最大内切球的半径(红色:小,蓝色:大)。如您所见,Voronoi图是一个非流形曲面(也就是说,不同的薄片可以在一个边缘相遇的曲面)。还有一点需要注意的是,Voronoi图看起来非常嘈杂:表面上的小扰动可以产生那些你在图中看到的头发状结构(事实上它们是红色的,表明它们与小的最大内切线球体有关)。虽然这通常是形状分析的一个问题,但这些结构根本不会影响我们的中心线,所以我们只是保持它们本来的样子。
中心线被确定为Voronoi图表中定义的路径,该路径最小化沿路径的最大内切球体半径的积分,这相当于在半径度量中寻找最短路径。他们的方法是通过使用半径的倒数作为波速从源点(中心线的一个端点)传播波,并在Voronoi图的所有点上记录波的到达时间,然后从目标点(中心线的另一个端点)沿着到达时间的梯度向下回溯线。传播用Eikonal方程描述,在代码中用快速推进法计算。显然,由于中心线是在Voronoi图上定义的,中心线的每个点都与相应的最大内切球半径相关联。
允许在vmtk中计算中心线的脚本是vmtkcenterlines。它输入一个曲面,然后吐出中心线、Voronoi图及其对偶、Delaunay镶嵌(或者,更好的是,曲面内部Delaunay镶嵌的子集)。
如果您输入vmtkcenterlines—help,您将得到很多options,我们现在将概述最重要的option。假设你在通常的foo中有一个容器模型。VTP文件,你想从中计算中心线。如果你写
vmtkcenterlines -ifile foo.vtp -ofile foo_centerlines.vtp
一个渲染窗口将弹出,要求您指定的点在表面将作为源点
Please position the mouse and press space to add source points, 'u' to undo
请定位鼠标并按空格键添加源点,按“u”键撤销
当你满意时按q(注意:你必须点击网格点来进行选择(一个红色的球体应该出现)。如果你做不到,试着放大到你想要的点)。现在你会被提示:
当你满意时按q(注意:你必须点击网格点来进行选择(一个红色的球体应该出现)。如果你做不到,试着放大到你想要的点)。现在你会被提示:
Please position the mouse and press space to add target points, ‘u’ to
undo
与上面一样。当你按下q后,计算机将开始处理数字(主要是那些需要计算德劳内镶嵌的数字,这是一个相当昂贵的操作)。最后,你会得到你的中心线。注意,在每条中心线上都定义了一个数组(默认命名为MaximumInscribedSphereRadius)。你可以这样看待结果
vmtksurfacereader -ifile foo.vtp --pipe vmtkcenterlines --pipe vmtkrenderer --pipe vmtksurfaceviewer -opacity 0.25 --pipe vmtksurfaceviewer -i @vmtkcenterlines.o -array MaximumInscribedSphereRadius
如果您想查看定义了中心线的Voronoi图表,请执行以下操作
vmtksurfacereader -ifile foo.vtp --pipe vmtkcenterlines --pipe vmtkrenderer --pipe vmtksurfaceviewer -opacity 0.25 --pipe vmtksurfaceviewer -i @vmtkcenterlines.voronoidiagram -array MaximumInscribedSphereRadius --pipe vmtksurfaceviewer -i @vmtkcenterlines.o
如果你仔细观察中心线,你会注意到它们并没有完全到达种子和目标点,但它们只是接近它们。原因是中心线位于Voronoi图上,而Voronoi图不触及表面(对于感兴趣的人来说,中心线止于与种子点和目标点相关的两极;看这里)找出什么是极点)。如果您希望中心线精确地结束于源点和目标点,请指定选项-端点1:(specify
the option -endpoints 1:)这样,从源和目标到各自极点的段将附加到中心线上。
如果您的模型是开放式的,您还可以指定种子和目标作为模型的开放概要文件的重心(specify seeds and targets as the
barycenters of the open profiles of your model)。 你通过命令来做到这一点:
vmtkcenterlines -seedselector openprofiles -ifile foo.vtp -ofile foo_centerlines.vtp
通常的渲染窗口将弹出,显示模型和所有打开的配置文件由一个数字标识。按q后你会看到
Please input list of inlet profile ids:
并且您必须指定与您想要定义源点的概要文件相对应的id列表(空格分隔)。然后你会被提示
Please input list of outlet profile ids:
你必须对目标点做同样的事情(我把它们命名为入口和出口,而不是源和目标……我必须在某个时候做出决定!)无论如何,过了这个点,你就只能等待中心线被计算出来了。
以上就是这个例子的全部内容。下个教程见!