新闻详情

新闻详情

首页 / 资讯中心 / 详情

岩石CT图像裂缝分割实战:从数据增强到U-Net训练全流程

发布时间:2026/9/12 19:58:10来源:尧图网络
岩石CT图像裂缝分割实战:从数据增强到U-Net训练全流程
简介面向岩石裂缝与CT岩心裂缝语义分割任务的Python项目基于深度学习方法提供完整源码与配套数据集适合毕业设计、期末大作业、课程设计等场景也方便新手通过注释清晰的代码快速上手。压缩包共11个文件包含Python脚本、JPG图像及标注样例、Markdown说明文档等整体大小仅1.13MB部署轻量。其中三个Python脚本分别处理数据增强、均值计算等图像预处理环节图像样例覆盖岩石、混凝土及CT图像与对应裂缝标注便于对照理解语义分割的输入输出格式。项目为个人手打高分作业导师认可度较高代码注释详尽从数据准备到模型训练的关键步骤均有说明下载后简单调整数据路径即可运行能帮助读者快速复现岩石裂缝分割流程并可作为后续算法改进或功能扩展的参考基础。目前已有225人学习下载适合需要完成相关课题、课程设计以及初次接触图像分割的开发者学习借鉴。1. 从CT岩心到裂缝掩膜这个项目到底在做什么岩石裂缝与CT岩心裂缝分割本质是像素级二分类每个像素要么是裂缝要么是背景。肉眼看岩心照片还能数出主裂缝换成CT灰度序列后人眼既慢又不可复现裂缝往往只有几个像素宽矿物纹理、颗粒噪声和CT圆环伪影混在一起阈值分割会输出大片假边缘。这个项目把整条链路补齐岩石、混凝土、CT三组带掩膜标注的样例图amplifyData.py、amplifyData-16.py两套增强脚本calc-mean.py均值统计脚本配合常见语义分割模型可以直接训练出逐像素输出裂缝概率的模型。对毕业设计或期末大作业来说是套省时间的工程框架对入门语义分割的开发者它一次性摆出了小目标、细长结构、类别不均衡三个典型难题。下文按数据准备、增强、统计、训练验证的顺序展开讲清参数怎么设、坑在哪。2. 图像-掩膜对与 dataset-kit 的数据组织2.1 一张原图配一张掩膜语义分割的最小数据单位语义分割和图像分类、目标检测的区别在输出粒度。分类给整张图一个标签检测给目标一个框分割则要给每个像素一个类别。项目里rock.jpg是输入原图rock_gt.jpg是对应的 ground truth 掩膜_gt后缀是分割数据集里常见的命名约定。掩膜通常用灰度图保存背景像素为 0裂缝像素为 255 或 1。动手前先确认掩膜的真实编码我用这段代码检查from PIL import Image import numpy as np mask np.array(Image.open(rock_gt.jpg).convert(L)) print(mask.shape) print(np.unique(mask))输出如果只有[0, 255]说明是二值掩膜如果出现[0, 128, 255]这类多值说明标签里混入了其他类别或标注笔误。裂缝任务一般只有前景背景两类统一转成 0/1 更稳妥mask (np.array(Image.open(rock_gt.jpg).convert(L)) 127).astype(np.uint8)这个转换必须放在所有预处理之前否则交叉熵损失会把 255 当作一个独立类别训练时梯度方向直接错掉。项目里的concrete_gt.jpg、CT_gt.jpg都可以用同样方式检查。2.2 dataset-kit 目录应该怎么搭项目自带的dataset-kit目录承担的就是数据管家职责源码和模型代码放在外面数据统一收进这个目录后复制、打包、写训练脚本都方便。一套常见的组织方式路径内容约定dataset-kit/images/全部输入原图JPG 或 PNG训练时统一转 RGBdataset-kit/masks/与 images 中文件名一一对应的掩膜PNG 格式0/255 或 0/1dataset-kit/train.txt训练集清单每行一个不带扩展名的文件名dataset-kit/val.txt验证集清单每行一个不带扩展名的文件名dataset-kit/mean.npy归一化均值和标准差由calc-mean.py生成掩膜存 PNG 而不是 JPG 是有原因的。JPG 是有损压缩裂缝边缘会出现一圈灰色过渡像素等于给硬标签加了模糊噪声PNG 无损存储能保持边界干净。项目自带的 README 里应该已经写明了目录约定保持这份工程习惯后面算指标时能省去很多返工。2.3 先扩增还是先划分顺序影响评估可信度推荐流程是先扩增、再划分。如果先划分再扩增验证集里会出现训练集的翻转和旋转版本模型在验证集上的分数会虚高。下面这段脚本在扩增后的文件列表上按 8:2 随机划分import os import random names [] for f in os.listdir(dataset-kit/images/): name os.path.splitext(f)[0] if os.path.exists(fdataset-kit/masks/{name}.png): names.append(name) random.seed(2024) random.shuffle(names) n_val max(1, int(len(names) * 0.2)) with open(dataset-kit/train.txt, w) as fp: for n in names[:-n_val]: fp.write(n \n) with open(dataset-kit/val.txt, w) as fp: for n in names[-n_val:]: fp.write(n \n)代码里固定了随机种子保证两次运行划分一致排查问题时能对比训练轮次和指标变化。划分时还要注意一个业务细节岩石、混凝土、CT 三种图像来源差异很大最好按来源分桶各取 20% 作为验证集再合并到一起。如果把某张 CT 切片同时分进训练集和验证集模型会通过记忆圆形轮廓来猜裂缝验证分数虚高换到新岩心上直接失效。3. amplifyData.py把三组样例扩成能训练的数据集3.1 裂缝分割为什么必须做数据增强压缩包里原图只有 rock、concrete、CT 三对直接训练必过拟合。数据增强的价值不只是增加数量更在于让模型对旋转、光照、尺度变化不敏感。裂缝在图像里是细长结构占比常常不到 5%训练初期模型很容易把所有像素都预测为背景因为这样准确率也有 95% 以上。数据增强配合 Dice 损失才能把模型的注意力拉到裂缝区域。这和遥感影像语义分割里的道路提取很像都是细长结构、背景占绝对多数这类问题对数据增强的要求也很接近几何扰动比颜色扰动更有效。项目的三种图像噪声模式完全不同。岩石表面照片有颗粒和阴影混凝土表面有气泡和模板纹路CT 灰度图有环形伪影和灰度漂移增强手段要跟着数据源调整。3.2 同步变换是数据增强的生命线原图和掩膜必须应用完全相同的几何变换否则标签错位。旋转、翻转、缩放属于几何变换亮度、对比度、模糊属于像素变换只作用于原图掩膜保持不变。amplifyData.py里最常见的同步变换实现import cv2 import numpy as np def hflip_pair(image, mask): return cv2.flip(image, 1), cv2.flip(mask, 1) def rotate_pair(image, mask, angle): h, w image.shape[:2] matrix cv2.getRotationMatrix2D((w // 2, h // 2), angle, 1.0) img cv2.warpAffine(image, matrix, (w, h), flagscv2.INTER_LINEAR) msk cv2.warpAffine(mask, matrix, (w, h), flagscv2.INTER_NEAREST) return img, msk def brightness_pair(image, mask, alpha): img cv2.convertScaleAbs(image, alphaalpha, beta0) return img, mask两个 interpolation 参数是这个函数最值得注意的地方原图用INTER_LINEAR双线性插值保持灰阶过渡自然掩膜用INTER_NEAREST最近邻插值避免在裂缝边缘插出灰色中间值。如果掩膜旋转后出现锯齿不要用模糊去平滑应该回到插值方式找问题。alpha是亮度增益大于 1 提亮小于 1 压暗对岩石照片取 0.81.2 比较安全。3.3 amplifyData-16.py 的 16 倍从哪里来amplifyData-16.py是把数据量扩到 16 倍的版本。16 倍通常由几何变换组 × 像素变换组组合得到例如 4 种翻转乘 2 种旋转乘 2 档亮度。一组常用组合变换维度具体取值组合数翻转原图、水平翻转、垂直翻转、双翻转4旋转0°、90°、180°、270°4亮度/对比度原亮度、降低对比度2噪声不加、轻微高斯噪声2如果全部组合就是 64 倍明显超出 16 倍所以实际脚本会做筛选。一个信息量较高的 16 倍配方是翻转变换 4 × 旋转 {90°, 270°} 2 × 亮度 {0.9, 1.1} 2总计 16。这个组合里不会出现同一变换重复作用导致的视觉重复样本。对 CT 灰度图亮度抖动范围应该比岩石照片小CT 的灰度分布本来就被窗宽窗位压缩得很窄alpha 超过 1.2 会引入非物理的灰度变化。3.4 增强完必须做的一次人工检查脚本跑完后不要直接开始训练先抽几张结果看标签是否对齐。我一般会在增强脚本最后加一段自检输出把原图和掩膜横向拼接保存import cv2 import numpy as np img cv2.imread(rock.jpg) mask cv2.imread(rock_gt.jpg, cv2.IMREAD_GRAYSCALE) mask_color cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR) cv2.imwrite(check_rock.png, np.hstack([img, mask_color]))看拼接图时重点确认三点裂缝有没有被旋转出画面掩膜的白色区域是否与图像中的裂缝位置重合翻转后图上如果存在文字类标记是否也一起镜像了。这个检查看似朴素但能挡住八成标签错位问题。增强脚本产出的文件名最好带上变换标识比如rock_rot90_hflip.png后面要排除某类增强样本时直接按文件名过滤就行。4. calc-mean.py重新统计岩石与CT图像的归一化参数4.1 直接套 ImageNet 均值为什么不够好很多语义分割代码默认使用 ImageNet 数据集的 mean[0.485, 0.456, 0.406]、std[0.229, 0.224, 0.225]。这套参数适合自然照片但岩石、混凝土、CT 图像的灰度分布和自然照片差异明显。CT 岩心图像素值偏暗且集中在很窄的区间岩石照片表面存在强烈的高光与阴影混凝土表面整体偏灰。直接套用 ImageNet 统计量输入分布和预训练权重期望的分布不一致网络前几个 epoch 会花大量时间去适应输入尺度。calc-mean.py解决的问题就是重新统计当前数据集的 RGB 均值和标准差。4.2 按批次累加的统计实现一个适合数据量不断增大的实现是逐图累加像素和与平方和最后再除总数不需要把全部图像载入内存import glob import numpy as np from PIL import Image images glob.glob(dataset-kit/images/*.png) total_pixels 0 sum_pixels np.zeros(3, dtypenp.float64) sum_squares np.zeros(3, dtypenp.float64) for path in images: img np.array(Image.open(path).convert(RGB), dtypenp.float64) / 255.0 h, w, _ img.shape total_pixels h * w sum_pixels img.reshape(-1, 3).sum(axis0) sum_squares (img ** 2).reshape(-1, 3).sum(axis0) mean sum_pixels / total_pixels std np.sqrt(sum_squares / total_pixels - mean ** 2) print(mean:, mean) print(std:, std)标准差用了等价公式 E[x²] - E[x]²只需保存两个累加量。用 float64 是为了避免几十万张图累加时的精度损失float32 在数据量上来后误差会明显变大。拿到输出后把数值填进训练脚本的归一化层from torchvision import transforms normalize transforms.Normalize( mean[0.486, 0.451, 0.423], std[0.211, 0.205, 0.197] )PyTorch 的ToTensor()会把像素缩放到 01所以统计脚本里也要先除以 255两边口径一致避免重复缩放。生成的 mean 和 std 可以存成 npy 文件后续训练脚本直接加载import numpy as np mean, std np.load(dataset-kit/mean.npy)4.3 分域统计还是全局统计项目里同时有岩石、混凝土、CT 三类图像灰度分布差异很大。拿 CT 图和岩石照片一起算全局均值结果对两类图都不是最优。三种数据源的使用建议数据源图像特点mean/std 使用建议岩石表面光照不均有高光颗粒可配合较强亮度抖动混凝土表面整体偏灰纹理粗糙重点做对比度增强CT 岩心灰度集中有环形伪影亮度扰动要小几何变换为主实际处理时我会先按文件名前缀分组分别输出三组 mean/std再决定是训练三个模型还是统一做一个模型。如果做统一模型统计结果能看出哪类图更偏亮、哪类更偏暗据此调整增强参数如果做毕业设计分域统计还能多出一组对比实验分析价值很高。需要特别强调的是均值和标准差一定要在增强后的全量数据上计算不要只用原始三张图算。颜色增强会改变像素分布用原始图统计的参数无法覆盖增强后的数据范围。5. U-Net 训练参数与裂缝分割结果验证5.1 模型选型与最小训练配置对岩石裂缝、CT 岩心裂缝这类二维图像分割任务U-Net 是最稳的出发点。它的编码器-解码器结构加上跳跃连接能把浅层边缘特征和高层语义特征融合适合裂缝这种边界敏感的小目标。如果拿它和 DeepLabV3 对比DeepLab 的空洞卷积在感受野上有优势但样本量不大时调参成本更高。如果把输入换成三维点云那是点云语义分割的范畴要处理邻域特征和坐标变换和本项目的二维图像分割不是一条路线。下载解压后建议先按 README 建一个虚拟环境装好 torch、opencv-python、Pillow 再开始跑。训练参数我实际用过这一组配置项推荐值理由输入尺寸512×512CT 大图建议切片到 512保留裂缝细节batch size8显存不够优先减半不要动分辨率优化器Adam(lr1e-4)分割任务收敛稳定学习率1e-430 轮后乘 0.1先快速拟合再精细微调训练轮次100用验证集 mIoU 选最佳权重损失函数BCE Dice缓解裂缝/背景比例失衡评估指标mIoU、Dice、F1准确率在裂缝分割中参考价值很低损失组合是训练里的另一个关键。BCE 逐像素计算背景数量占优时梯度被背景主导Dice Loss 直接度量预测区域与真实区域的重叠度对前景更敏感。常见做法是二者相加两个损失量级接近 1不需要额外加权。5.2 裂缝分割结果的可视化验证训练结束后光看 mIoU 数字不够裂缝分割要逐张检查预测。建议把原图、叠加图、掩膜三列拼在一起输出比单独保存掩膜更直观。一段可以复用的验证代码import cv2 import numpy as np img cv2.imread(CT.jpg) prob model.predict(img) # 输出 (H, W, 1) 的概率图 mask (prob.squeeze() 0.5).astype(np.uint8) overlay img.copy() overlay[:, :, 2] np.maximum(overlay[:, :, 2], mask * 255) vis np.hstack([img, overlay, cv2.cvtColor(mask * 255, cv2.COLOR_GRAY2BGR)]) cv2.imwrite(val_CT_overlay.png, vis)np.maximum把红色通道在裂缝位置直接拉高背景细节不受影响比cv2.addWeighted混叠更清晰。检查叠加图时优先看 CT 图边缘和矿物颗粒边缘CT 圆环伪影是最容易被误判成裂缝的位置如果叠加图上圆环边缘一圈都红了说明模型学的是 CT 图像的环形结构而不是裂缝本身。遇到这种情况可以在增强时加入局部灰度扰动或者把图像裁剪到岩心内部区域绕开环形边框。5.3 让实验可复现的一次小改造调参时最怕同一个脚本这次跑 0.71、下次跑 0.69说不清是随机性还是参数变化。做法是训练前固定所有随机种子import random import numpy as np import torch random.seed(args.seed) np.random.seed(args.seed) torch.manual_seed(args.seed) torch.cuda.manual_seed_all(args.seed)再把 seed 和学习率、增强参数一起记录到train_log.txt。固定种子之后每一次 mIoU 掉点都能往前追溯到是增强参数、学习率衰减还是标签文件改动造成的。源码包里的.gitignore已经具备工程化雏形把生成的图片和权重文件忽略掉只跟踪代码和标注清单反复调参时每次实验都能对应到一组可解释的参数组合。本文还有配套的精品资源点击获取
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

PFC中的二极管反向恢复电流 2026/9/12 20:46:17

PFC中的二极管反向恢复电流

摘要:本文以爆闪灯产品开发为背景,介绍 PFC 与 APFC 的基本原理。文章先说明 PFC 用于改善电源输入端的功率因数,再介绍 APFC 通过主动控制开关管使输入电流跟踪电压波形,将功率因数提升到 0.95 以上;随后结合 UCC2818…

阅读更多 →
Metabase DatetimeSubtract 表达式完全指南:语法、参数、实战案例与底层实现 2026/9/12 20:46:17

Metabase DatetimeSubtract 表达式完全指南:语法、参数、实战案例与底层实现

Metabase DatetimeSubtract 表达式完全指南:语法、参数、实战案例与底层实现 【免费下载链接】metabase The easy-to-use open source Business Intelligence and Embedded Analytics tool that lets everyone work with data :bar_chart: 项目地址: https://gitc…

阅读更多 →
Python模块缺失错误(ModuleNotFoundError)排查与解决指南 2026/9/12 20:46:17

Python模块缺失错误(ModuleNotFoundError)排查与解决指南

1. 问题现象与背景分析 当你尝试在Python环境中运行 pip install 安装某个依赖包时,突然遇到 ModuleNotFoundError: No module named altair 的错误提示,这种情况在Python开发中相当常见。作为一名长期使用Python的数据可视化开发者,我几…

阅读更多 →
SSM家政小程序实战:从数据库设计到订单并发全解析 2026/9/12 20:46:17

SSM家政小程序实战:从数据库设计到订单并发全解析

简介:基于JavaSSMMySQL微信小程序的家政项目小程序,是一套面向高校毕业设计、课程设计与期末大作业的完整源码包,前后端代码齐全,且已通过严格调试,适合计算机相关专业学生直接参考或二次开发。资源共1213个文件&#…

阅读更多 →
DevSecOps国产化工具的技术演进与实践 2026/9/12 20:46:17

DevSecOps国产化工具的技术演进与实践

1. 项目概述"安全左移"正在成为DevSecOps领域的核心趋势。2023年全球应用安全测试(AST)市场规模已达72亿美元,而中国市场的年复合增长率高达42%,远超全球平均水平。在这个背景下,国产DevSecOps工具正在经历从"能用"到&qu…

阅读更多 →
RTL8153b替代新选择:方寸微PT153s芯片迁移与千兆网卡设计实战 2026/9/12 20:43:16

RTL8153b替代新选择:方寸微PT153s芯片迁移与千兆网卡设计实战

做硬件这些年,我最怕的不是设计难点,而是明明方案已经量产了,突然告诉你核心芯片缺货,或者价格翻倍,那感觉就像辛辛苦苦盖了大楼,结果地基材料被人抽走了。前阵子在做一款便携USB千兆网卡,原来一…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞