界面重建——Marching cubes算法

Posted spacerunnerZ

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了界面重建——Marching cubes算法相关的知识,希望对你有一定的参考价值。

一、引子

对于一个标量场数据,我们可以描绘轮廓(Contouring),包括2D和3D。2D的情况称为轮廓线(contour lines),3D的情况称为表面(surface)。他们都是等值线或等值面。

以下是一个2D例子:

 为了生成轮廓,必须使用某种形式的插值。这是因为我们只在数据集中的一个有限点集上有标量值,而我们的等高线值可能位于这两个点的值之间。由于最常见的插值技术是线性插值,我们通过沿边缘的线性插值在轮廓表面上生成。如果一条边在其两个端点上有标量值10和0,如果我们试图生成一条值为5的等高线,则边缘插值计算该等高线通过边缘的中点

 

二、Marching cubes算法——从2D理解

运用了分治思想,对每个单元格(cell)独立地进行处理。该技术的基本假设是,一个轮廓只能以有限数量的方式通过一个单元格。我们可以构造一个案例表(case table),它枚举一个单元的所有可能的拓扑状态(topological state)。拓扑状态的数量取决于单元格顶点的数量,以及一个顶点相对于轮廓值可以具有的内部/外部关系的数量。标量值大于轮廓值的顶点被称为在轮廓之内。标量值小于轮廓值的顶点被称为在轮廓之外。例如,如果一个单元格有四个顶点,并且每个顶点可以在轮廓内部或外部,则有2^4 = 16种可能的方式通过单元格(在实现时可以用bit来实现)。在案例表中,我们不感兴趣的是轮廓通过单元格的位置(例如,geometrical intersection),感兴趣的只是它如何通过单元格(即单元格中轮廓的topology)。

一旦我们选择好属于哪一种case之后,就可以使用插值来计算contour line与cell edge相交的位置。该算法处理一个单元格,然后移动,或行进到下一个单元格。在访问所有单元格后,将完成轮廓。因此称为marching cubes。


算法的步骤如下:

1. Select a cell.
2. Calculate the inside / outside state of each vertex of the cell.
3. Create an index by storing the binary state of each vertex in a separate bit.
4. Use the index to look up the topological state of the cell in a case table.
5. Calculate the contour location (via interpolation) for each edge in the case table.
 
 这个过程将在每个单元格中构造独立的几何原元。在单元格边界处,可以创建重复的顶点和边。这些重复项可以通过使用一个特殊的重合点合并(point merging)操作来消除。请注意,沿着每条边的插值都应该在相同的方向上进行。若不这样,数值舍入很可能导致生成的点不完全一致(not precisely coincident),并且不能正确合并(merge)。这一步骤称为merge coincident points。
 
三、Marching cubes算法——3D情况
对于6面体,有8个顶点,因此有2^8 = 256中情况,又由于对称性,最后只保留15种情况,如下图:

 四、算法需要注意的事项

在2D中,轮廓模糊(ambiguos cases,如Fig6.5中的Case 5和Case 10)很容易处理:对于每个模糊的情况,我们选择实现两种可能的情况中的一种。根据选择的不同,轮廓可以延伸或打破当前的轮廓,如Fig 6.9所示。任何一种选择都是可以接受的,因为产生的等高线(contour line)将是连续的和封闭的(或将在数据集(data set)边界结束)。

 在3D中,这个问题更为复杂。我们不能简单地选择一个独立于所有其他模糊案例的模糊案例。例如,Fig 6.9显示了如果我们不小心实现了两个相互独立的情况,会发生什么。在这个图中,我们使用了通常的情况3,但用它的互补情况替换了情况6。互补的情况是通过将“暗”顶点与“光”顶点交换而形成的。(这相当于将顶点标量值从等值面值以上切换到等值面值以下,反之亦然。)将这两种情况配对的结果是在等值面上留下了一个孔(hole)。

一个简单而有效的解决方案通过添加额外的互补案例(complementary cases),扩展了原来的15个marching cubes案例。这些情况被设计成与邻近的情况兼容,并防止在等值面上产生孔。需要6个互补的情况,分别对应于行进立方体的情况3、6、7、10、12和13。互补的行进立方体案例如Fig 6.10所示。

 此外,尽管我们说该算法用于规则类型,如四边形和立方体,但marching cubes可以应用于任何拓扑上等同于立方体的单元类型(例如,六面体或非立方体体素)。

五、应用


Fig 6.11d是由marching cubes创建的等值面。图6.11b是一个来自计算机断层扫描(CT)x射线成像系统的恒定图像强度(image intensity)的表面。(图6.11a是该数据的二维子集。)其强度水平对应于人的骨骼。图6.11c为恒定流密度(flow density)的等值面。图6.11d为铁蛋白分子的电子势等值面。由于我们熟悉人体解剖学,图6.11b中所示的图像可以立即被识别出来。然而,对于计算流体动力学和分子生物学领域的从业者来说,图6.11c和图6.11d同样熟悉。正如这些例子所显示的,轮廓形成的方法是各领域可视化数据的强大而又通用的技术。

 

参考文档:VTKTextBook Scalar Algorithms

我在STM32单片机上跑神经网络算法—CUBE-AI

摘要:为什么可以在STM上面跑人工智能?简而言之就是通过X-Cube-AI扩展将当前比较热门的AI框架进行C代码的转化,以支持在嵌入式设备上使用,目前使用X-Cube-AI需要在STM32CubeMX版本7.0以上,目前支持转化的模型有Keras、TF lite、ONNX、Lasagne、Caffe、ConvNetJS。Cube-AI把模型转化为一堆数组,而后将这些数组内容解析成模型,和Tensorflow里的模型转数组后使用原理是一样的。

一、环境安装和配置

  1. STM32CubeMX
  2. MDK/IAR/STM32CubeIDE
  3. F4/H7/MP157开发板

二、AI神经网络模型搭建

这里使用官方提供的模型进行测试,用keras框架训练:

https://github.com/Shahnawax/HAR-CNN-Keras

模型介绍

在Keras中使用CNN进行人类活动识别:此存储库包含小型项目的代码。该项目的目的是创建一个简单的基于卷积神经网络(CNN)的人类活动识别(HAR)系统。该系统使用来自3D加速度计的传感器数据,并识别用户的活动,例如:前进或后退。HAR意为Human Activity Recognition (HAR) system,即人类行为识别。这个模型是根据人一段时间内的3D加速度数据,来判断人当前的行为,比如走路,跑步,上楼,下楼等,很符合Cortex-M系列MCU的应用场景。使用的数据如下图所示。

存储库包含以下文件

  1. HAR.py,Python脚本文件,包含基于CNN的人类活动识别(HAR)模型的Keras实现,
  2. actitracker_raw.txt、包含此实验中使用的数据集的文本文件,
  3. model.h5,一个预训练模型,根据训练数据进行训练,
  4. evaluate_model.py、Python 脚本文件,其中包含评估脚本。此脚本在提供的 testData 上评估预训练 netowrk 的性能,
  5. testData.npy,Python 数据文件,包含用于评估可用预训练模型的测试数据,
  6. groundTruth.npy,Python 数据文件,包含测试数据的相应输出的地面真值和
  7. README.md.

这么多文件不要慌,模型训练后得到model.h5模型,才是我们需要的。

三、新建工程

1.这里默认大家都已经安装好了STM32CubeMX软件。

在STM32上验证神经网络模型(HAR人体活动识别),一般需要STM32F3/F4/L4/F7/L7系列高性能单片机,运行网络模型一般需要3MB以上的闪存空间,一般的单片机不支持这么大的空间,CUBEMX提供了一个压缩率的选项,可以选择合适的压缩率,实际是压缩神经网络模型的权重系数,使得网络模型可以在单片机上运行,压缩率为8,使得模型缩小到366KB,验证可以通过;

然后按照下面的步骤安装好CUBE.AI的扩展包

这个我安装了三个,安装最新版本的一个版本就可以。

接下来就是熟悉得新建工程了

因为安装了AI的包,所以在这个界面会出现artificial intelligence这个选项,点击Enable可以查看哪一些芯片支持AI

接下来就是配置下载接口和外部晶振了。

然后记得要选择一个串口作为调试信息打印输出。

选择Software Packs,进入后把AI相关的两个包点开,第一个打上勾,第一个选择Validation

  • System Performance工程:整个应用程序项目运行在STM32MCU上,可以准确测量NN推理结果,CP∪U负载和内存使用情况。使用串行终端监控结果(e.g.Tera Term)
  • Validation工程:完整的应用程序,在桌面PC和基于STM32 Arm Cortex-m的MCU嵌入式环境中,通过随机或用户测试数据,递增地验证NN返回的结果。与 X-CUBE-A验证工具一起使用。
  • Application Template工程:允许构建应用程序的空模板项目,包括多网络支持。

之后左边栏中的Software Packs点开,选择其中的X-CUBE-AI,弹出的Mode窗口中两个复选框都打勾,Configuration窗口中,点开network选项卡。

选择刚刚配置的串口作为调试用。

点击add network,选择上述下载好的model点h5模型,选择压缩倍数8;

点击分析,可从中看到模型压缩前后的参数对比

点击validation on desktop 在PC上进行模型验证,包括原模型与转换后模型的对比,下方也会现在验证的结果。

致此,模型验证完成,下面开始模型部署

四、模型转换与部署

时钟配置,系统会自动进行时钟配置。按照你单片机的实际选型配置时钟就可以了。

最后点击GENERATE CODE生成工程。

然后在MDK中编译链接。

选择好下载器后就可以下载代码了。

然后打开串口调试助手就可以看到一系列的打印信息了。

代码烧写在芯片里后,回到CubeMX中下图所示位置,我们点击Validate on target,在板上运行验证程序,效果如下图,可以工作,证明模型成功部署在MCU中。

这次就这样先跑一下官方的例程,以后再研究一下,跑跑自己的模型。

参考资料:

  • https://youtube/grgNXdkmzzQ?t=10
  • https://youtube/grgNXdkmzzQ?t=103

以上是关于界面重建——Marching cubes算法的主要内容,如果未能解决你的问题,请参考以下文章

Marching Cubes 如何处理无符号距离?

大数据Kylin:Kylin构建Cube算法

在 Snowflake 中构建 OLAP Cube

Kylin实战—— Kylin Cube构建算法

六十五Kylin Cube的构建

我在STM32单片机上跑神经网络算法—CUBE-AI