资讯考证相关

基于Python的CT岩心与岩石裂缝语义分割系统源码及数据集实战

2026/10/12 11:06:11 安证通 考证咨询 特种作业
基于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 图里是暗线还是亮线、宽度大概几个像素、有没有矿物填充导致的灰度变化这些都得自己盯着图看几遍。从那以后我每次拿到新的岩石分割数据都强制先做一遍像素值分布统计和掩膜格式检查再动模型。希望帮到你。本文还有配套的精品资源点击获取
本文仅供参考,具体政策以官方公告为准 返回资讯列表 →
延伸阅读

更多相关内容

相关资讯、最新动态、本周本月更新,都在这里。

电工抢修工作业绩说明最新政策解读

电工抢修工作业绩说明最新政策解读

电工抢修业绩说明避坑指南:电子证书申领全解析 别再把培训费当交智商税了,很多人考不过、拿证慢,根本卡死在“电工抢修工作业绩说明”这一关。 你以为背熟题库就能过?错。实操和业绩审核才是隐形杀手,尤其涉及电子证书生成时,材料不规范直接驳回。…

查看 →
AI会话失忆怎么办?用claude-mem为终端AI助手搭建长期记忆层

AI会话失忆怎么办?用claude-mem为终端AI助手搭建长期记忆层

1. 每个会话都是“第一次见面”:我为什么会对记忆工具上头 先说个场景。你手里同时维护着两三个项目,每个项目都有一堆背景约束、技术债、历史决策。这天你调完一个 bug,隔了两天再打开终端,想继续之前那条思路,结果 A…

查看 →
电工证哪个级别高?别被忽悠,教你在哪考才靠谱

电工证哪个级别高?别被忽悠,教你在哪考才靠谱

电工证哪个级别高?别被忽悠,教你在哪考才靠谱 很多刚入行或者想转行的朋友,后台私信问得最多的就是:“老师,我听说电工证分高低,到底电工证哪个级别高?还有,我想考证,不知道在哪考,怕花几千块被黑中介坑了,最后证还考不下来。”…

查看 →
白银票据原理与实战:Kerberos横向移动技术详解

白银票据原理与实战:Kerberos横向移动技术详解

1. 项目概述:一张伪造的“内部通行卡”如何绕过身份核验“域渗透之(白银票据利用)”——这标题里带括号的写法,是安全圈老手才懂的暗号。它不讲大道理,不堆概念,直指一个具体、危险、且在真实攻防对抗中高频…

查看 →
电工证过度怎么办?3步搞定真实经历避坑

电工证过度怎么办?3步搞定真实经历避坑

电工证过度怎么办?3步搞定真实经历避坑 别被那些“包过”“内部渠道”的中介忽悠了,电工证过度(注:此处指复审或换发,业内常误传为“过度”,实为有效期满后的延续或状态变更)这事儿,我自己刚办完,全是真实经历。最让人头疼的就是不知道去哪报名,怕交了几千块冤枉钱还办不下来。 一、…

查看 →
内部消息揭秘:考低压电工证有难度?郑州金水区水利人避坑指南

内部消息揭秘:考低压电工证有难度?郑州金水区水利人避坑指南

内部消息揭秘:考低压电工证有难度?郑州金水区水利人避坑指南 是不是每次看到朋友圈里有人晒电工证,心里痒痒的,想考一个备用,又怕被那些满大街发广告的中介坑得明明白白?这种“不知道去哪报名、怕交钱后没下文”的焦虑,我太懂了。在郑州金水区搞水利工程的,咱们干的是实打实的辛苦活,证书这东西,水太深,稍不留神…

查看 →
内部消息:涿州市电工证培训跨省转办全流程解析

内部消息:涿州市电工证培训跨省转办全流程解析

内部消息:涿州市电工证培训跨省转办全流程解析 很多在外地干了几年电工的老伙计,最近都在问同一个问题:之前考的那个电工证,现在回涿州干活,还能不能用?或者说,需不需要重新在涿州市找个地方重新培训一遍?这确实是咱们一线从业者最头疼的事,毕竟谁也不想白交那几百上千的学费,更不想耽误接活儿的时间。今天我就结…

查看 →
3招看懂中级电工证能干嘛用,避开官方报名入口陷阱

3招看懂中级电工证能干嘛用,避开官方报名入口陷阱

3招看懂中级电工证能干嘛用,避开官方报名入口陷阱 很多人怕考不过白交培训费,这种焦虑我太懂了。毕竟电工证是安监局(现应急管理局)发的硬通货,考不过不仅钱打水漂,还耽误找工作的时间。 别慌,今天咱们不聊虚的,直接拆解【中级电工证能干嘛用】,顺便把 官方报名入口…

查看 →
官方回应:怎么申领电工证电子证?异地转证全攻略

官方回应:怎么申领电工证电子证?异地转证全攻略

官方回应:怎么申领电工证电子证?异地转证全攻略 之前考的证在外省能不能转过来?这是无数在外打拼的电工兄弟最关心的事儿。别急,今天就把这事儿掰开了揉碎了讲清楚。 很多师傅拿着纸质本,担心换个城市工地就废了。其实, 国家安全生产考试网…

查看 →
箱面接地电工作业报名门槛低,考下来多少钱才合理

箱面接地电工作业报名门槛低,考下来多少钱才合理

箱面接地电工作业报名门槛低,考下来多少钱才合理 学历不高,怕报不上名?别自己瞎琢磨,直接看这里。 很多刚出校门的朋友,尤其是许昌这边刚毕业学工程的学弟学妹,手里攥着身份证,心里打鼓:我是不是得先拿个本科证才能考这个证?是不是得去报个几千块的培训班才能过?其实,关于 箱面接地电工作业…

查看 →
建湖高压电工证外省能转吗?官方回应来了

建湖高压电工证外省能转吗?官方回应来了

建湖高压电工证外省能转吗?官方回应来了 之前在外省考的高压电工证,回到江苏建湖能直接用吗?能不能直接转过来?这是很多跨省流动电工最头疼的问题。别急,关于【建湖高压电工证】异地互认的疑惑, 官方回应…

查看 →
相关服务

看完文章,下一步可以直接办

报考、备考、复审相关的服务入口,都在这里。

考试批次时间

近期各工种批次安排与报名截止提醒。

查看详情 →

报考条件查询

年龄、学历、体检条件逐项对照。

查看详情 →

材料免费预审

报名材料逐项核对,缺什么当场补齐。

查看详情 →

复审流程

复审时间、材料与流程一次说清。

查看详情 →
报名流程

从咨询到拿证,就四步

每一步都有明确产出,每一步都有人盯着。

01

意向沟通

说清岗位与目标,顾问推荐对应工种与报考方向。

02

材料预审

身份证、学历、体检逐项核对,缺什么当场补齐。

03

批次报名

锁定最近考试批次,考务信息逐一确认。

04

培训考试

题库辅导加实操要点,考完节点逐一跟进拿证。

免费咨询

想报考特种作业证?找顾问聊一聊

根据你的工作经历推荐工种,确认批次与材料,30 秒登记当天回访。