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文件后,我们可以查看到完全一致的效果:

相关推荐
云飞云共享云桌面3 小时前
智能装备工厂研发团队如何利用单台服务器承载 10 路 SolidWorks 并发?
运维·服务器·3d·自动化·制造
cuicuiniu5218 小时前
3D图纸交付格式不对怎么办?如何快速进行3D格式转换?
3d·cad·cad看图·cad看图王
greasyfork10 小时前
Ps 2026 v27.6 For Mac:专业图像处理工作流解析
图像处理·人工智能·macos·ps
云飞云共享云桌面11 小时前
机械企业三维设计优化:一台高性能 SolidWorks 服务器满足 10 人建模需求
运维·服务器·3d·自动化·负载均衡
玖玥拾21 小时前
Unity3D RPG 入门项目(十一)主角完整战斗、怪物自动刷新、四大类型技能系统
游戏·3d·unity·游戏引擎
飞奔的猫1 天前
锈了儿—游戏素材用的在线图形处理工具
图像处理·人工智能·游戏美术
敢敢のwings1 天前
世界模型与FlashWorld:从“在梦中学习“到秒级3D场景生成
android·学习·3d
雾沉川2 天前
d3dx9_43.dll 丢失报错原因分析及三种标准修复方法
microsoft·3d
这张生成的图像能检测吗2 天前
即插即用模块 + 改进思路汇总目录
图像处理·人工智能·深度学习·目标检测·机器学习
Ming_studying2 天前
Python批量压缩图片:支持JPG_PNG_WebP、尺寸限制与CSV报告
开发语言·图像处理·python·pillow·图片压缩