基于Python的CT岩心与岩石裂缝语义分割系统源码及数据集实战
简介这份资源面向计算机视觉与地质工程方向的本科生、研究生及课程设计开发者提供一套基于Python的CT岩芯与岩石裂缝语义分割完整方案可用于期末大作业、课程设计或相关课题的快速复现与二次开发。压缩包共15个文件约1.15MB包含3个py源码脚本、6张jpg示例图像、3个zbak备份文件以及zip、gitignore、md等辅助文件源码覆盖数据增强、均值计算等训练前处理环节示例图则对应岩石、混凝土与CT岩芯的原图及标注掩码便于直接验证分割效果。资源采用Pillow、OpenCV与TensorFlow/PyTorch等主流工具链构建从图像预处理到像素级分类的端到端流程可帮助读者理解裂隙识别在地质构造与油气勘探中的量化分析思路。目前已有73人学习适合希望以较低成本获取可运行代码与配套数据、快速完成项目搭建的读者参考。1. 从一张 CT 岩心切片说起这套 Python 语义分割源码到底能干什么去年帮一个做地质数字化的朋友看岩心扫描图他手里有几百张 CT 切片想自动把裂缝区域抠出来量面积、算密度人工描边一张要十几分钟一天下来眼睛都花了。这类需求其实非常典型输入是一张岩石或 CT 岩心的灰度图输出是一张同尺寸的掩膜图裂缝像素标白、背景标黑这就是语义分割要干的事。这套「基于 Python 的 CT 岩心与岩石裂缝语义分割系统源码及数据集」正好卡在这个场景上它把训练数据、增强脚本、均值计算脚本和示例图打包在一起拿到手就能跑通一条从数据到可视化的最小闭环。它适合三类人一是做课程设计或期末大作业的学生需要一份结构完整、能讲清楚流程的工程二是地质、石油工程方向想入门图像分割的研究者拿它当 baseline 快速验证想法三是已经会 PyTorch 或 TensorFlow、但没接触过岩石裂缝这类低对比度目标的工程师想看看别人怎么处理数据。资源本身不绑定某个框架的完整训练代码重点在数据组织和预处理环节这也是我看重它的原因——分割任务里真正拉开差距的往往不是模型结构而是数据这一层。2. 拆开压缩包目录结构、文件职责与数据组织逻辑2.1 从文件清单反推工程意图先把压缩包里的东西按职责分个类这样后面动手时不会乱。清单里出现的文件大致可以归成四组文件/目录类型作用dataset-kit目录数据集主体通常放原图与对应掩膜amplifyData.py/amplifyData-16.py脚本数据增强扩充样本量calc-mean.py脚本计算数据集均值供归一化使用example目录示例图含原图与 gt 掩膜README.md文档使用说明.gitignore/.zbak/备份文件.zip杂项版本控制与备份可忽略example目录里的命名很规整rock.jpg配rock_gt.jpgconcrete.jpg配concrete_gt.jpgCT.jpg配CT_gt.jpg。_gt后缀是 ground truth 的惯例写法说明这是一套「原图 标注掩膜」成对出现的数据组织方式。岩石、混凝土、CT 三类样本放在一起意味着这套代码想覆盖的不仅是岩心还包括类岩石材料泛化场景更宽一些。2.2 数据增强脚本 amplifyData.py 的定位amplifyData.py和amplifyData-16.py两个版本从命名推测 16 可能是针对 16 位深图像的处理分支。CT 岩心图常见 16 位灰度直接按 8 位读会丢动态范围这个细节如果不注意后面训练时裂缝和基质的对比度会被压掉一大截。常见做法是用 OpenCV 的IMREAD_UNCHANGED标志读取再按需归一化到 0-255 或保留浮点。增强脚本一般做几何变换翻转、旋转、裁剪和像素变换亮度、对比度、噪声。对裂缝分割来说几何变换要特别小心旋转和翻转必须原图和掩膜同步做否则标签就错位了。下面是一段我常用的同步增强骨架思路和amplifyData.py应该是一致的import cv2 import numpy as np import os def augment_pair(img_path, gt_path, out_dir, idx): # IMREAD_UNCHANGED 保留 16 位深度避免 CT 图动态范围丢失 img cv2.imread(img_path, cv2.IMREAD_UNCHANGED) gt cv2.imread(gt_path, cv2.IMREAD_UNCHANGED) # 水平翻转原图与掩膜必须用同一个 flipCode img_f cv2.flip(img, 1) gt_f cv2.flip(gt, 1) # 旋转 90 度k1 表示逆时针一次 img_r np.rot90(img, 1) gt_r np.rot90(gt, 1) cv2.imwrite(os.path.join(out_dir, fimg_{idx}_f.png), img_f) cv2.imwrite(os.path.join(out_dir, fgt_{idx}_f.png), gt_f) cv2.imwrite(os.path.join(out_dir, fimg_{idx}_r.png), img_r) cv2.imwrite(os.path.join(out_dir, fgt_{idx}_r.png), gt_r)逻辑说明读图用IMREAD_UNCHANGED是关键普通IMREAD_COLOR会把 16 位压成 8 位。翻转和旋转对原图、掩膜用完全相同的参数保证像素级对齐。参数上flipCode1是水平翻转np.rot90的第二个参数控制旋转次数每次 90 度。输出文件名带后缀区分增强类型方便回溯。提示增强后的掩膜如果是二值图旋转插值要用最近邻否则边缘会出现 0.3、0.7 这种非 0/1 的灰度值训练时算 loss 会出问题。2.3 calc-mean.py 为什么不能省calc-mean.py负责算数据集的均值和标准差用于归一化。很多人做分割直接套 ImageNet 的均值方差但岩石 CT 图和自然图像分布差很远用错均值会让模型收敛慢甚至不收敛。这个脚本的存在说明作者是认真对待数据分布的。它的逻辑通常是遍历所有训练图累加像素值再求平均import os import cv2 import numpy as np img_dir dataset-kit/train/img means, stds [], [] for name in os.listdir(img_dir): img cv2.imread(os.path.join(img_dir, name), cv2.IMREAD_GRAYSCALE) img img.astype(np.float32) / 255.0 means.append(img.mean()) stds.append(img.std()) print(mean:, np.mean(means), std:, np.mean(stds))逻辑说明逐图算均值和标准差再取平均比把所有像素堆一起算更稳避免某张大图主导结果。参数上除以 255 是先把范围压到 0-1如果你保留 16 位这一步要改成除以 65535。算出来的值填进训练脚本的Normalize(mean[x], std[y])里灰度图只有一个通道别写成三个。3. 把数据喂进模型从掩膜格式到训练配置的完整链路3.1 掩膜的二值化与类别约定语义分割的掩膜有两种常见格式一种是灰度图像素值 0 表示背景、255 表示目标另一种是索引图像素值直接是类别 id0、1、2…。这套资源里的_gt.jpg大概率是前者。训练前要确认清楚因为损失函数的选择依赖它。如果是 0/255用BCEWithLogitsLoss前要把掩膜除以 255 变成 0/1如果是多类别索引图就得用CrossEntropyLoss。import cv2 import numpy as np gt cv2.imread(example/CT_gt.jpg, cv2.IMREAD_GRAYSCALE) # 查看掩膜里到底有哪些像素值 unique_vals np.unique(gt) print(unique_vals) # 期望看到 [0, 255] 或 [0, 1] # 统一转成 0/1 浮点供 BCE 使用 gt_bin (gt 127).astype(np.float32)逻辑说明np.unique是排查掩膜格式最快的手段一眼就能看出是二值还是多类。阈值 127 是 0/255 图转 0/1 的常用分界如果掩膜边缘有抗锯齿产生的中间值这个阈值能把它归到目标侧。参数上astype(np.float32)是为了和模型输出的浮点 logits 对齐。3.2 训练集与验证集的划分策略岩石裂缝数据往往样本量不大example里就几张图dataset-kit里估计也就几十到上百张。这种规模下划分要讲究不能纯随机否则同一块岩心的不同切片可能同时进训练和验证造成数据泄漏验证指标虚高。常见做法是按岩心编号或图像来源分组划分同一来源的图只进一个集合。import os import random all_imgs sorted(os.listdir(dataset-kit/img)) # 按文件名前缀分组假设前缀代表不同岩心来源 groups {} for name in all_imgs: prefix name.split(_)[0] groups.setdefault(prefix, []).append(name) keys list(groups.keys()) random.seed(42) random.shuffle(keys) split int(len(keys) * 0.8) train_keys, val_keys keys[:split], keys[split:] train_imgs [n for k in train_keys for n in groups[k]] val_imgs [n for k in val_keys for n in groups[k]] print(len(train_imgs), len(val_imgs))逻辑说明先按前缀分组再划分保证同源数据不跨集。random.seed(42)固定随机性方便复现。参数上 0.8 是训练比例样本少时可以调到 0.7 给验证留更多。如果前缀规则不明确退而求其次可以按文件名排序后隔几张取一张做验证但效果不如分组稳。3.3 损失函数与评价指标的搭配裂缝分割有个典型问题裂缝像素占比往往不到 5%正负样本极度不平衡。这时候纯 BCE 会让模型倾向于全预测背景准确率看着很高但 IoU 惨不忍睹。常见做法是 BCE 加 Dice Loss 组合Dice 对前景敏感能拉住不平衡。import torch import torch.nn as nn class BCEDiceLoss(nn.Module): def __init__(self, bce_weight0.5): super().__init__() self.bce nn.BCEWithLogitsLoss() self.bce_weight bce_weight def forward(self, logits, targets): bce_loss self.bce(logits, targets) probs torch.sigmoid(logits) # Dice 计算前把维度拉平避免 batch 维度干扰 probs_flat probs.view(-1) targets_flat targets.view(-1) intersection (probs_flat * targets_flat).sum() dice_loss 1 - (2 * intersection 1e-6) / (probs_flat.sum() targets_flat.sum() 1e-6) return self.bce_weight * bce_loss (1 - self.bce_weight) * dice_loss逻辑说明BCE 提供稳定的逐像素梯度Dice 直接优化重叠度。1e-6是防止分母为零的平滑项别省。参数bce_weight控制两者权重0.5 是起点如果发现前景召回低就调小它、让 Dice 占更大比重。评价指标上除了 IoU建议单独看裂缝类的 recall因为漏检一条裂缝比多标一块背景代价大得多。4. 避坑与排查跑这套源码时最容易翻车的五个地方4.1 现象训练 loss 一直不降输出全黑原因掩膜没做二值化或者归一化用了 ImageNet 的均值方差和岩石图分布不匹配。CT 图整体偏暗用自然图像的均值会把有效信号压没。解决先跑calc-mean.py拿到真实均值和标准差填进 Normalize。再用np.unique确认掩膜只有 0/1 或 0/255训练前统一转成 0/1 浮点。4.2 现象增强后图像和掩膜对不上边缘错位原因原图和掩膜用了不同的插值方式或者旋转时一个用了cv2.rotate一个用了np.rot90两者对边界的处理不一致。解决所有几何变换对原图和掩膜用同一套函数、同一组参数。掩膜旋转插值固定用INTER_NEAREST原图可以用INTER_LINEAR但坐标映射必须一致。4.3 现象16 位 CT 图读进来变成全白或全黑原因用cv2.imread默认的IMREAD_COLOR读 16 位图OpenCV 会做截断高动态范围信息丢失。解决读图时显式传cv2.IMREAD_UNCHANGED或cv2.IMREAD_ANYDEPTH拿到原始位深后再决定归一化策略。如果模型输入要求 8 位用cv2.normalize按百分位拉伸别直接除以 256。4.4 现象验证集 IoU 高得离谱实际预测一塌糊涂原因数据泄漏。同一块岩心的相邻切片被分到了训练集和验证集模型见过几乎一样的图。解决按岩心来源分组划分同源数据只进一个集合。如果文件名没有来源信息至少按采集批次或时间戳分组别用纯随机。4.5 现象推理时显存爆掉或 batch size 只能设 1原因CT 岩心图分辨率通常很大直接整图送进网络特征图占的显存随分辨率平方增长。解决训练时随机裁 patch比如 256×256 或 512×512推理时用滑窗加重叠拼接。重叠区域取平均能消除拼接缝。这套资源的example图可以先裁小跑通流程再上全图。5. 进阶玩法用滑窗推理把大图分割跑稳附一套验证习惯数据量小的时候除了增强还有一个提分手段是测试时增强TTA把图翻转、旋转几个版本分别推理再把结果平均回去。对裂缝这种方向性强的目标TTA 能明显稳住边缘。下面是一段滑窗加 TTA 的推理骨架import cv2 import numpy as np import torch def sliding_window_inference(model, img, patch256, stride128, devicecuda): model.eval() h, w img.shape[:2] prob_map np.zeros((h, w), dtypenp.float32) count_map np.zeros((h, w), dtypenp.float32) for y in range(0, h - patch 1, stride): for x in range(0, w - patch 1, stride): patch_img img[y:ypatch, x:xpatch] # 转 tensor 并加 batch、channel 维度 tensor torch.from_numpy(patch_img).float().unsqueeze(0).unsqueeze(0).to(device) with torch.no_grad(): # TTA原图 水平翻转两次结果平均 out1 torch.sigmoid(model(tensor)) out2 torch.sigmoid(model(torch.flip(tensor, dims[3]))) out2 torch.flip(out2, dims[3]) prob ((out1 out2) / 2).squeeze().cpu().numpy() prob_map[y:ypatch, x:xpatch] prob count_map[y:ypatch, x:xpatch] 1 # 重叠区域取平均避免拼接缝 prob_map prob_map / np.maximum(count_map, 1e-6) return (prob_map 0.5).astype(np.uint8) * 255逻辑说明滑窗的stride小于patch是为了制造重叠重叠区靠count_map做平均消除边界突变。TTA 部分对水平翻转的预测再翻回来和原预测平均能压掉一部分随机噪声。参数上patch256、stride128是显存和精度的折中显存够可以调大 patch但 stride 建议保持 patch 的一半左右。阈值 0.5 是默认值如果发现漏检多就降到 0.4 试试。验证习惯上我一般会固定三件事一是每次改完预处理先拿example里那几张图跑一遍可视化肉眼看掩膜边缘对不对二是记录每次实验的均值方差、损失权重、学习率写在 README 里不然过两天就忘了哪组参数最好三是留一张完全不参与训练的图做最终测试别用验证集的结果下结论。这套源码给了一个能跑通的起点但真正决定效果的是你对数据的理解——裂缝在 CT 图里是暗线还是亮线、宽度大概几个像素、有没有矿物填充导致的灰度变化这些都得自己盯着图看几遍。从那以后我每次拿到新的岩石分割数据都强制先做一遍像素值分布统计和掩膜格式检查再动模型。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

团队协作必备:Git版本管理规范与提交约束实战指南

团队协作必备:Git版本管理规范与提交约束实战指南

简介:这份Git版本管理使用规范文档面向新入职开发人员及需要统一协作流程的技术团队,用于解决多人开发中分支混乱、代码冲突频发、版本难以追溯等问题。文档围绕master主干、developer、feature、bugfix四类分支展开,明确各自的命名规则与使用…

2026/10/12 11:05:18 阅读更多 →
OFDM链路级仿真MATLAB实战:从帧结构到BER曲线

OFDM链路级仿真MATLAB实战:从帧结构到BER曲线

简介:这份MATLAB OFDM链路级仿真程序面向无线通信初学者与工程研究人员,用于在MATLAB环境中搭建并验证完整的OFDM收发链路。资源以m脚本为主体,共12个文件,压缩包约7KB,涵盖主流程入口、OFDM调制解调、加窗与重叠处理、…

2026/10/12 11:05:18 阅读更多 →
技术参考资源整理指南:分类筛选与高效使用方法

技术参考资源整理指南:分类筛选与高效使用方法

1. 为什么“参考资源”这一章最容易被跳过,却最不该被跳过做技术内容这些年,我见过太多人翻书、翻文档、翻教程时,看到“参考资源”四个字就直接翻页。理由也很统一:不就是一堆链接和书名吗,能有什么营养?说…

2026/10/12 11:05:17 阅读更多 →

最新新闻

二叉树进阶攻略:递归、迭代、层序与经典题型全解析

二叉树进阶攻略:递归、迭代、层序与经典题型全解析

算法训练营第十四天:二叉树(2) 到了第十三天,我们基本上把二叉树的"骨架"摸清了:节点结构、树的定义、递归遍历的套路。那十四天干嘛?两个字:深化。二叉树(2)…

2026/10/12 14:48:18 阅读更多 →
卫星通信入网三关:物理连通、协议接入与业务可用性验证

卫星通信入网三关:物理连通、协议接入与业务可用性验证

简介:本资源是一份面向通信工程专业学生、卫星地面站建设工程师及网络测试技术人员的实务型教学课件,系统讲解卫星通信网络从建站、入网验证到系统测试的全流程规范与关键技术。内容覆盖新地球站入网申请审批(国内经原邮电部电信总局、国际由…

2026/10/12 14:48:18 阅读更多 →
Agent记忆系统实战:上下文窗口限制与MCP统一工具记忆

Agent记忆系统实战:上下文窗口限制与MCP统一工具记忆

1. 先理解Agent为什么“记不住”:上下文窗口的边界与失真1.1 上下文窗口是工作台,不是仓库我最早做Agent原型时犯过一个很天真的错误:以为模型能记住对话里出现过的所有信息。后来被现实狠狠教育了一课——上下文窗口更像一张有限大小的办公桌…

2026/10/12 14:48:18 阅读更多 →
Keras复现YOLOv1:从零训练自己的数据集实战指南

Keras复现YOLOv1:从零训练自己的数据集实战指南

简介:这份资源面向希望上手目标检测的深度学习研究者与开发者,围绕Keras版YOLOv1算法,提供训练自有数据集的完整配套材料。YOLOv1将检测视为回归问题,速度优势明显,而Keras高层API降低了实现门槛,二者结合便…

2026/10/12 14:48:18 阅读更多 →
MATLAB读取RINEX观测文件:从解析到定位解算的完整指南

MATLAB读取RINEX观测文件:从解析到定位解算的完整指南

简介:这份资源面向从事GNSS数据处理、测绘与导航定位方向的科研人员和工程技术人员,提供了一套用MATLAB读取RINEX格式GPS观测文件的程序,并附带测试数据用于验证解析结果。RINEX作为接收机独立交换格式,广泛用于GPS、GLONASS、Gal…

2026/10/12 14:48:18 阅读更多 →
WorkBuddy低代码工作流实战:从单点任务到业务闭环

WorkBuddy低代码工作流实战:从单点任务到业务闭环

1. 这不是一场普通征稿:WorkBuddy 应用指南征集背后的“真实战场”你点开这个标题,第一反应可能是——又一个企业发的软广?领积分、换周边?听起来像行政部发的季度团建通知。但如果你真这么想,就错过了一个正在 quietl…

2026/10/12 14:47:16 阅读更多 →

日新闻

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

在数码相机、高清显示屏与现代矢量图形技术高度发达的今天,画面可以做到绝对的锐利、平滑与无瑕。然而,当一张秋日手账插画或拍立得照片过于“平整无瑕”时,往往会散发出一种冰冷生硬的“数码塑料感(Digital Plasticity&#xff0…

2026/10/12 0:00:59 阅读更多 →
活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

在现代网页与移动端设计中,横排(Horizontal Layout)早已经成为了绝对的主流。然而,当我们翻开泛黄的线装古籍、宋版木刻诗集,或是欣赏一张茶道雅集的手写便签时,那种**自上而下纵向书写、自右向左逐列铺展&…

2026/10/12 0:00:59 阅读更多 →
周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

每到周日的晚上八点到十点,很多人心里都会悄悄亮起一盏警示灯。 在心理学上,这种现象有一个专门的称谓——“周日夜晚焦虑症(Sunday Scaries)”。明天又是周一,闹钟又要重新在七点响彻卧房;脑海里仿佛有一个…

2026/10/12 0:00:59 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/12 0:16:30 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/12 0:16:43 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 10:45:37 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:53 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:54 阅读更多 →