CT(DCM)外轮廓实时识别 → 逐层拼3D → 导出STL到Blender

目录

一、看「过程」

二、整体流程

三、步骤一:在切片上查找关键点

原理

效果

​编辑

伪代码

四、步骤二:排除无效区域

原理

效果

伪代码

五、步骤三:查找真正的外周点

原理

效果

伪代码

六、步骤四:外周点排序并闭合

原理

效果

伪代码

七、步骤五:多切片合成三维模型

原理

效果

伪代码

[八、导出与查看(STL / Blender)](#八、导出与查看(STL / Blender))

九、小结


医院 CT(DCM)切片如何逐层找出外轮廓得到有序外周点, 以及多切片如何实时拼成三维模型。

一、看「过程」

三维重建的成品往往很「安静」:一个光滑的表面模型静静摆在屏幕上。 但真正有趣的地方,常常发生在它「长出来」之前------ 每一层 CT 图像里,边缘点如何被发现?杂质如何被清掉?外周点如何变得有序?


二、整体流程

  1. 查找关键点:在单张切片上找到「看起来像边缘」的亮点集合。
  2. 排除无效区域:去掉不属于目标外轮廓的连通块/噪声区域。
  3. 查找外周点:从剩余点中进一步收敛到真正的外周候选。
  4. 排序并闭合:让点按周向有序排列,形成可闭合的轮廓环。
  5. 切片合成:多层轮廓按层间距堆叠、缝合,实时生成 3D 网格。

三、步骤一:在切片上查找关键点

原理

CT 灰度图上,组织与背景常存在对比。外轮廓附近的像素,往往比邻域更「亮」或更「陡」。 第一阶段要做的事情很朴素:

  • 按行(或按扫描线)遍历图像有效区域;
  • 对每个像素,比较它与周围邻域的平均亮度;
  • 若自身相对邻域更突出,则记为一个候选关键点

这一步得到的是「边缘感很强的点云」,数量通常很多,且可能包含内部结构、噪声、伪影。 所以它只是起点,不是终点。

效果

伪代码

复制代码
for each pixel p in slice (with margin):
    if brightness(p) > average(brightness of neighbors around p):
        mark p as keypoint candidate

四、步骤二:排除无效区域

原理

关键点会自然聚成许多连通区域(八邻域连通即可)。 其中只有一部分对应我们关心的外层结构;更多可能是内部空洞边缘、局部噪声块、次要组织边界。

排除无效区域的核心思路通常是:

  1. 对关键点做连通分量分组,得到若干「区块」;
  2. 用外接矩形、是否靠近图像中心、是否被更大区块包含等几何关系判断「外层 / 内层」;
  3. 保留目标相关区块,清除其余区块中的点(演示里常做成飞散消失,便于观看)。

直观理解:先把「一整片可疑边缘」分成若干团,再看哪一团才像主体外轮廓?哪一团只是里面的杂质?

效果

排除无效区域:非目标区块被清除,主体相关点保留

伪代码

复制代码
// 连通分组 → 判定外层目标 → 丢弃其它
blocks = connected_components(keypoints)
target = select_main_outer_block(blocks)  
for block in blocks:
    if block is not related_to(target):
        remove points of block  

五、步骤三:查找真正的外周点

原理

即使去掉大量无效区域,剩余点仍可能「厚」:同一方向上既有更靠外的点,也有偏里的点。 外周点的目标是:在轮廓的周向上,尽量只保留最外侧的代表点。

一种非常适合可视化的演示策略是「中心 + 周向扫描」:

  • 估计点集中心(质心);
  • 把平面按角度分成很多扇区(例如每 2° 一格);
  • 指针顺时针扫一周,每个角度只保留距中心最远的那一个点;
  • 扇区内其它点视为扫过即可清除。

效果

查找外周点:周向扫描后收敛到外周候选点

伪代码

复制代码
// 按角度分箱,每箱只留最远点
center = centroid(remaining_points)
for angle_bin in 0 .. N-1:
    pts = points_falling_into(angle_bin)
    keep farthest_from(center, pts)
    discard the others

六、步骤四:外周点排序并闭合

原理

「有一圈点」还不够,建模与展示需要它们是有序的。 有序意味着:沿着边界走一圈,点的先后关系稳定,并且首尾可以闭合。

排序的直觉很直接:

  • 以中心为原点,按极角(例如从上方向起顺时针)排序;
  • 必要时做等弧长重采样,让相邻点间距更均匀;
  • 用方向箭头或折线连接,明确「从第 i 个点走向第 i+1 个点」;
  • 最后连回起点,形成闭环轮廓。

效果

外周点排序并闭合:方向性箭头与闭环连线,强调「有序」

伪代码

复制代码
// 极角排序 → 连线 → 闭合
ring = sort_by_polar_angle(outer_points, center)
for i in 0 .. ring.Count-1:
    connect ring[i] → ring[(i+1) % ring.Count]

七、步骤五:多切片合成三维模型

原理

每一层 CT 都得到一条(或一组)二维闭环轮廓后,就可以进入三维阶段:

  1. 把像素坐标换算到毫米坐标(像素间距、层厚/层间距来自 DICOM 几何信息);
  2. 按切片顺序把轮廓放到对应的高度(Z);
  3. 在相邻两层之间做缝合:连接对应点,生成三角面片;
  4. 随着新切片不断识别完成,网格逐步「长高」,实现实时预览。

缝合策略可以很简单(例如两层都重采样到相同点数,再按索引连接), 也可以更激进(全点就近匹配)。演示里常见的「平均等分」就是为了让对应关系稳定、易于理解。

效果

切片合成:多层轮廓实时堆叠、缝合为三维模型

伪代码

复制代码
// 相邻层轮廓 loft 成三角网格
for layer in 0 .. layers-2:
    A = resample(contours[layer],   N)
    B = resample(contours[layer+1], N)
    for i in 0 .. N-1:
        add_quad_as_two_triangles(A[i], A[i+1], B[i+1], B[i])

八、导出与查看(STL / Blender)

当网格足够完整后,可导出为常见的 STL / PLY。 STL 记录的是三角面片汤(triangle soup),Blender、MeshLab 等软件都能直接打开。

在 Blender 中查看时,关注:

  • 整体形态是否与预期解剖结构一致;
  • 层与层之间是否出现明显扭曲(通常与轮廓对应或层间距有关);
  • 法线朝向、封闭性是否满足后续处理需求。

九、小结

从 CT 灰度里找出「像边缘的点」,剔掉不该留下的区域, 再收敛成有序外周闭环,最后把多层闭环缝成可导出的三维网格。

导出为stl文件后,我们可以查看到完全一致的效果:

相关推荐
郝旭帅电子设计团队15 小时前
图像处理是什么
图像处理·fpga开发·郝旭帅电子设计团队·郝旭帅
云飞云共享云桌面20 小时前
广东精密机械设备工厂8-10人共享一台SolidWorks设计服务器
运维·服务器·3d·自动化·汽车·制造
AI视觉网奇1 天前
bambu-studio-ai 踩坑实战笔记
人工智能·3d
MagicUrban1 天前
经纬管网MagicPipe3D V3.8.1发布,参数化自主可控三维管线建模工具
3d·gis·智慧城市·bim·地下管网
sali-tec1 天前
C# 基于OpenCv的视觉工作流-章100-抠图
图像处理·人工智能·opencv·计算机视觉
LONGZETECH1 天前
传统实训 vs 仿真实训:从技术架构拆解新能源汽车教学的范式之变
c语言·3d·unity·架构·汽车
科技之门2 天前
AI3D从建模到贴图、绑骨和动画的完整流程怎么做?V2Fun完整工作流指南
人工智能·3d·贴图
dalong102 天前
WPF:3D甜甜圈
3d·c#·wpf·甜甜圈
在水一缸3 天前
PGSimCity:当数据库内核变成一座可以漫步的城市
数据库·postgresql·可视化·开源项目·数据库内核·pgsimcity·技术科普