新闻详情

新闻详情

首页 / 资讯中心 / 详情

岩石裂缝与CT岩心语义分割:数据集、Python增强脚本与UNet训练避坑指南

发布时间:2026/9/28 1:28:47来源:尧图网络
岩石裂缝与CT岩心语义分割:数据集、Python增强脚本与UNet训练避坑指南
简介面向岩石工程、计算机视觉与深度学习方向的毕业设计、期末大作业和课程设计需求这份资源包提供基于 Python 的岩石裂缝与 CT 岩心裂缝语义分割完整方案自带配套数据集与标注图像并通过数据增强脚本和均值计算脚本完成样本扩充与预处理代码注释详细新手按说明部署即可复现。压缩包共 11 个文件核心为 3 个 Python 脚本配合 6 张图像样本、说明文档及 gitignore 配置整体约 1.13MB结构紧凑、路径清晰。目前已有 225 人学习浏览属于小巧完整的项目型内容。下载后可获得可运行源码、标注数据集、数据增强脚本和使用说明既能用于岩石裂缝分割实验也能帮助理解从数据准备、样本增强到模型训练评估的完整流程。对毕业设计答辩、期末作业演示及后续扩展训练而言这是一份实用且高分认可度高的参考模板。1. 岩石裂缝与CT岩心语义分割做毕设卡在数据上时这个资源能给你补上关键一环做岩石裂缝识别的毕设最耗时间的往往不是跑模型而是把图像和语义分割标注整理得能直接训练。我刚接CT岩心裂缝这个题时光是数据对齐和脚本补全就花了两周后来看到这个“基于python的岩石裂缝与CT岩心裂缝语义分割源码数据集”包第一反应是如果早拿到它至少能省一半时间在数据管线上。它把岩石、混凝土、CT岩心三组图像与对应的语义分割标注打包在一起还附带了数据增强和均值计算的Python脚本解压就能在本地重新组织成训练集。这份资源解决的是语义分割项目里“数据地基”那一层图片与mask的配对、增强脚本、归一化参数计算一次给到位。你不用再从零搜集岩石裂缝图也不用自己画一整轮标注尤其适合毕业设计、课程设计和期末大作业场景也适合刚接触语义分割算法、想找一份真实非玩具数据练手的从业者。只要会基础Python和PyTorch能跑通pip install这份资源大概率能让你在几小时内看到自己的分割结果而不是卡在数据准备的黑匣子里。配合后面几章的踩坑记录新手也能少走一段弯路。2. 数据集与工具链拆解三组影像、两套标注、三个Python脚本2.1 从文件列表看项目构成谁负责喂数据、谁负责画边界解压之后你会看到类似下面的文件分布这里我按作用重新归了类文件/目录内容在管线里的角色rock.jpg / rock_gt.jpg岩石表面照片 / 对应裂缝标注岩石裂缝分割主数据集concrete.jpg / concrete_gt.jpg混凝土表面照片 / 对应裂缝标注补充场景用于泛化对比CT.jpg / CT_gt.jpgCT岩心切片图像 / 对应裂缝标注灰度影像分割数据集example/样例输出或预处理样例验证流程的参考amplifyData.py / amplifyData-16.py数据增强脚本把有限标注扩充成可训练规模calc-mean.py计算训练集RGB均值归一化参数计算README.md使用说明部署入口这种分布其实透露了一个信息资源重心不在某一套现成的模型训练代码上而在于“数据集 数据准备工具”。它是为语义分割算法服务的原料包而不是一个开箱即用的端到端项目。所以拿到手之后第一件事不是急着找train.py而是把这个包当成数据工程基础自己补一个训练脚本。毕设里最常翻车的也正是这部分标注有了但不知道增强怎么做、mean怎么算、数据怎么喂给网络。从标注内容看三组数据有一个共同点都是“裂缝”这类细长结构前景像素占比普遍很低。这意味着后面选损失函数和评估指标时不能拿普通物体分割的思路来套。我一般拿到这样一份数据会先统计一下每张图前景像素的占比做到心里有数。2.2 amplifyData.py数据增强脚本的正确打开方式语义分割的增强和图像分类不一样它必须保证图像和标注mask经过完全相同的几何变换否则裂缝位置就对不上了。amplifyData.py做的核心就是这件事读入原图和gt施加一组随机几何变换和光度变换然后把同步变换后的图和mask写到增强目录。# amplifyData.py 的核心逻辑整理版 import cv2 import numpy as np def rotate_image_mask(image, mask, angle): # 图像和mask用完全相同的旋转矩阵保持裂缝位置对齐 h, w image.shape[:2] matrix cv2.getRotationMatrix2D((w / 2, h / 2), angle, 1.0) image cv2.warpAffine(image, matrix, (w, h), flagscv2.INTER_LINEAR) mask cv2.warpAffine(mask, matrix, (w, h), flagscv2.INTER_NEAREST) return image, mask def fliplr(image, mask): # 水平翻转mask必须跟着翻转否则裂缝出现在相反方向 image cv2.flip(image, 1) mask cv2.flip(mask, 1) return image, mask def adjust_brightness(image, alpha): # 亮度扰动只改图像mask不参与 return cv2.convertScaleAbs(image, alphaalpha, beta0) # 每张原图按随机组合生成 N 张增强样本 for angle in [-15, -10, -5, 0, 5, 10, 15]: img, msk rotate_image_mask(img, msk, angle) if np.random.rand() 0.5: img, msk fliplr(img, msk) cv2.imwrite(fout/p_{i}_rot{angle}.jpg, img) cv2.imwrite(fout/p_{i}_rot{angle}_gt.png, msk)这段逻辑里需要注意两个关键点。第一mask在warpAffine时插值方式必须用INTER_NEAREST不能用默认的线性插值否则标注边缘会出现0到255之间的过渡值等于给模型注入了错误的soft标签。第二几何变换旋转、翻转、缩放、平移必须图和mask一起做而光度变换亮度、对比度、加噪声只做在图像上mask直接跳过。amplifyData-16.py看命名应该在增强数量上做了扩展比如把单张图扩到16张甚至加入了裁剪和缩放组合。使用它的原则不变确认输出目录里每张jpg旁边都有一张对应的gt数量一致、命名对应这是增强后最该检查的事。2.3 calc-mean.py为什么岩石裂缝分割要单独算均值很多语义分割的新手会直接把ImageNet训练的均值R:0.485, G:0.447, B:0.406拿来用这在岩石和CT图像上经常出问题。岩石表面照片和CT灰度影像的分布与自然图像差别很大硬套ImageNet均值会拖慢收敛。calc-mean.py就是用来解决这个问题的遍历训练集所有原图统计RGB三通道的像素均值供训练和推理阶段归一化使用。# calc-mean.py 的核心逻辑整理版 import cv2 import glob import numpy as np images glob.glob(dataset/**/*.jpg, recursiveTrue) \ glob.glob(dataset/**/*.png, recursiveTrue) total np.zeros(3, dtypenp.float64) # 累加三通道像素值 count 0 for path in images: # 统一按三通道读入灰度图自动复制为三通道 img cv2.imread(path).astype(np.float64) if img.ndim 2: img cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) img cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # cv2读进来是BGR转成RGB再算 total img.sum(axis(0, 1)) count img.shape[0] * img.shape[1] mean total / count print(RGB mean:, mean)这个脚本统计的是原图不是标注mask因为归一化作用在送入网络的输入图上。跑完之后把打印出来的三个值记下来训练脚本里Normalize要填这组数推理脚本也必须沿用同一组两边不一致是隐蔽的坑我在后面避坑章节会细说。另外提醒一点如果数据同时有彩色岩石图和灰度CT图按三通道读入统一统计更合理避免灰度图因为单通道读数参与不了均值计算。3. 环境搭建与数据准备把标注图变成模型能吃的样子3.1 最小依赖清单Python环境怎么配需要哪些库先配环境推荐Python 3.8到3.10之间配PyTorch 2.x即可不需要装最新的开发版。依赖清单如下pip install torch torchvision opencv-python numpy在vscode里配置python环境时注意解释器要选到创建虚拟环境的那一个不然pip装完的包在终端能import、在调试器里却报ModuleNotFoundError这个问题在毕设阶段很常见。装好后可以跑一句python -c import torch, cv2; print(torch.__version__, cv2.__version__)确认环境通顺再继续。3.2 目录规整与标注图预处理灰度mask统一二值化下载解压后先把数据集整理成统一目录结构。我一般按场景建三个子目录每个子目录下分images和masks# 整理目录结构的示意脚本 import os import cv2 # 目标结构 # dataset/ # rock/images/... # rock/masks/... # ct/images/... # ct/masks/... # concrete/images/... # concrete/masks/... pairs [ (rock.jpg, rock_gt.jpg, rock), (CT.jpg, CT_gt.jpg, ct), (concrete.jpg, concrete_gt.jpg, concrete), ] for img_file, gt_file, scene in pairs: os.makedirs(fdataset/{scene}/images, exist_okTrue) os.makedirs(fdataset/{scene}/masks, exist_okTrue) img cv2.imread(img_file) gt cv2.imread(gt_file, cv2.IMREAD_GRAYSCALE) # 关键步骤标注统一二值化避免jpg压缩带来的过渡像素 gt_bin cv2.threshold(gt, 127, 255, cv2.THRESH_BINARY)[1] cv2.imwrite(fdataset/{scene}/images/001.jpg, img) cv2.imwrite(fdataset/{scene}/masks/001.png, gt_bin)说明标注图一定要转成灰度读入再做阈值二值化。明明是一份语义分割数据如果mask里混进了0、127、255三档灰阶网络会在训练时反复犹豫边界预测全是灰色的概率输出。这类问题靠训练很难自己修复应该在预处理阶段就彻底清干净。mask统一输出为png原因也很实际jpg是有损压缩反复读写会在标注边界产生伪影png无损读写适合当标注格式。3.3 训练集/验证集划分岩石、混凝土与CT不要混在一起随机切三类场景的照片风格差异非常大如果把它们全混在一起再随机切分验证集里很可能只抽到混凝土或者只抽到CT单次验证的指标会剧烈抖动。我一般每个场景单独划分按8:2比例再合并成全局train/val列表# 划分训练集与验证集 import random from glob import glob def split_scene(scene, val_ratio0.2, seed42): images sorted(glob(fdataset/{scene}/images/*.jpg)) masks [p.replace(images, masks).replace(.jpg, .png) for p in images] pairs list(zip(images, masks)) random.Random(seed).shuffle(pairs) split int(len(pairs) * (1 - val_ratio)) return pairs[:split], pairs[split:] train_pairs, val_pairs [], [] for scene in [rock, ct, concrete]: tr, va split_scene(scene) train_pairs tr val_pairs va with open(train.txt, w) as f: for img, msk in train_pairs: f.write(f{img} {msk}\n) with open(val.txt, w) as f: for img, msk in val_pairs: f.write(f{img} {msk}\n)每个场景独立划分后val里三类数据都覆盖到IoU的方差会小很多。到这里数据链路已经跑通下一步就是补一个训练脚本把模型跑起来。4. 训练与评估补上训练脚本跑通语义分割的闭环4.1 为什么用UNet做基线裂缝分割的边界恢复是关键这份资源原始包里没有给出训练主模型但它既然配套了标注和增强脚本说明目标就是让使用者自己接一个语义分割模型。裂缝这种细长结构分割难点在边界裂缝宽度只有几个像素池化层多卷一次高分辨率特征就被稀释了。UNet的优势在于跳跃连接它把下采样丢失的高分辨率信息直接拼回到上采样路径对恢复裂缝边界很友善。如果显存足够也可以换DeepLabV3但UNet的代码量小、好调试、参数也直观适合先跑通再优化。我在毕设项目里通常先拿UNet跑一版拿到baseline指标再决定要不要换更强的backbone而不是一上来就堆大模型。4.2 train.py的关键实现损失函数、优化器与训练循环下面这一版train.py是按最常见配套方案补全的骨架可以直接跟这份资源的数据集对接import torch import cv2 import numpy as np from torch import nn from torch.utils.data import Dataset, DataLoader # 简化的UNet核心结构double conv 上采样加跳跃连接 class DoubleConv(nn.Module): def __init__(self, in_ch, out_ch): super().__init__() self.conv nn.Sequential( nn.Conv2d(in_ch, out_ch, 3, padding1), nn.BatchNorm2d(out_ch), nn.ReLU(inplaceTrue), nn.Conv2d(out_ch, out_ch, 3, padding1), nn.BatchNorm2d(out_ch), nn.ReLU(inplaceTrue), ) def forward(self, x): return self.conv(x) # 数据集读取按train.txt里记录的图像和标注路径取数 class CrackDataset(Dataset): def __init__(self, path_list, size256): self.samples [] self.size size with open(path_list) as f: for line in f: img_path, msk_path line.strip().split() self.samples.append((img_path, msk_path)) def __len__(self): return len(self.samples) def __getitem__(self, idx): img_path, msk_path self.samples[idx] img cv2.imread(img_path) img cv2.cvtColor(img, cv2.COLOR_BGR2RGB) msk cv2.imread(msk_path, cv2.IMREAD_GRAYSCALE) img cv2.resize(img, (self.size, self.size)) msk cv2.resize(msk, (self.size, self.size), interpolationcv2.INTER_NEAREST) img img.astype(np.float32) / 255.0 msk (msk 127).astype(np.float32) # 这里使用calc-mean.py算出的均值不要直接套ImageNet mean np.array([0.41, 0.38, 0.36], dtypenp.float32) img - mean img torch.from_numpy(img).permute(2, 0, 1).float() msk torch.from_numpy(msk).unsqueeze(0).float() return img, msk这个示例里UNet在forward里会用maxpool下采样四层再逐层上采样并拼接encoder输出本段为了篇幅只保留了DoubleConv和数据集部分你按标准UNet把forward补全即可。训练里有两个参数值得盯住size256是输入尺寸显存小的卡可以用224甚至192但裂缝太细时分辨率降太多会让正样本更稀疏mean那三个值务必替换成你用calc-mean.py实际算出来的结果否则后面验证时指标对不上。损失函数我一般用BCE加Dice的组合因为纯BCE在裂缝这种极度不平衡的二分类上容易把背景学得过猛class BCEDiceLoss(nn.Module): def __init__(self, dice_weight0.5): super().__init__() self.dice_weight dice_weight def forward(self, pred, target): # pred是sigmoid后的概率图 bce nn.functional.binary_cross_entropy(pred, target) smooth 1.0 inter (pred * target).sum() dice 1 - (2 * inter smooth) / (pred.sum() target.sum() smooth) return bce self.dice_weight * dice这个损失里dice_weight默认0.5是个比较稳的起点。如果训练中观察到正样本区域几乎没什么梯度可以把它调到1.0反过来如果loss已经很低但图输出全是灰色模糊一片就把dice_weight降回0.3。优化器直接用Adamlr设1e-3训练60个epoch左右配合ReduceLROnPlateau在验证IoU不再涨时把lr降到原来的1/10能让指标再往上走两三个点。4.3 评估时看什么IoU、Dice与PA的计算方式训练过程的loss曲线只能说明拟合状况能不能用要看验证集的指标。裂缝分割场景关注三个数字Pixel Accuracy像素准确率、IoU交并比、DiceF1的几何等价形式。其中IoU对细裂缝最敏感因为裂缝只占几个像素漏掉一条细缝union区域变化不大但intersection会显著变小IoU能如实反映出来。def compute_metrics(pred_mask, gt_mask): pred_mask (pred_mask 0.5).astype(np.uint8) gt_mask (gt_mask 0.5).astype(np.uint8) inter np.logical_and(pred_mask, gt_mask).sum() union np.logical_or(pred_mask, gt_mask).sum() pa (pred_mask gt_mask).mean() iou inter / (union 1e-6) dice 2 * inter / (pred_mask.sum() gt_mask.sum() 1e-6) return pa, iou, dice注意在算IoU之前一定要把预测概率图阈值化成0/1有些代码直接把概率图参与交集计算算出来的IoU虚高答辩时被导师一问就露馅。验证阶段通常在裂缝这个类别上单独看IoU背景不参与计算因为背景占比太大把背景算进去会掩盖裂缝预测质量。5. 避坑手册岩石裂缝分割最容易翻车的五个环节5.1 数据增强后mask跟着图错位现象训练loss正常下降但预测出来的裂缝整体偏离真实位置尤其在旋转过、翻转过的图上裂缝仿佛从正确位置“平移”了一段。原因自己写的增强逻辑里图像用了cv2.warpAffine、cv2.flipmask却只做了缩放或根本没做同样的变换导致图和标注对不上。解决强制让图像和mask走同一套几何变换函数mask的插值统一用INTER_NEAREST。我给自己的规则是对每个样本在同一个随机种子下生成一组几何参数然后图和mask分别调用变换做完后立刻随机抽5张图做轮廓叠加检查。用amplifyData.py增强完成后也建议先输出一张对比图到example目录确认对齐再进训练。5.2 直接用ImageNet均值归一化收敛慢到怀疑人生现象同样的epoch数别人用数据自身均值训练出来的验证IoU已经到70%你却还在30%附近磨蹭损失曲线像一条平线。原因岩石照片和CT切片的像素分布与自然图像差异很大尤其是CT灰度图数值集中在很窄的区间硬套(0.485, 0.447, 0.406)这组均值等于把数据平移到一个不合适的位置。解决训练前先跑一遍资源里自带的calc-mean.py把输出的三通道均值填进NormalizeCT灰度图如果按三通道读入也算进统计。从那以后每次换数据集我都把算均值当成固定动作不再迷信ImageNet。5.3 CT灰度图输入网络后输出一片黑现象rock场景分割正常一旦训练或推理放到CT数据上预测输出几乎全是背景裂缝全部丢失。原因CT图是灰度图但被读成了三通道后三个通道内容完全一样这种特性会让网络在batch norm初始化时统计分布偏向单一方向如果同时用了ImageNet预训练权重第一个卷积层的通道权重预期与灰度数据也不匹配迁移过来的特征基本失效。解决两种方案只能选一个并保持训练推理一致——要么灰度图复制成三通道输入从头初始化训练要么把网络输入通道改成1读图时用cv2.IMREAD_GRAYSCALE对应的均值也按单通道算。我一般选后者省内存而且逻辑干净。5.4 裂缝占图像面积太小loss被背景淹没现象训练loss一直在降但看预测结果模型把几乎整张图都预测成背景只零零碎碎输出几个白点。原因岩石裂缝往往只占图像面积的1%到3%BCE对每个像素等权对待正样本贡献的梯度微乎其微模型直接学成“全部预测背景”反而loss更低。解决换用第4章提到的BCEDice混合损失Dice天然按整体重叠度计算不受前景占比影响也可以反向做两次crop训练时把样本集中裁剪到裂缝密集区域。动手训练前先统计一下整组数据的前景像素占比如果低于5%强烈建议把损失从纯BCE换成混合损失。5.5 标注图用jpg保存边界全是噪点现象预测结果的边缘有一圈零碎小点像围了一串白毛边形态学处理也难消干净。原因这份资源里的gt图是jpg格式而jpg是有损压缩裂缝边缘会被压缩算法揉出过渡像素和伪影。直接把这当mask训练等于告诉模型边界是个模糊带。解决预处理阶段统一做二值化重写为png阈值取127之后所有训练和验证都从png读。用自己的数据也一样标注环节尽量导出png不要为图省事存jpg这是我在第一次做混凝土裂缝分割时留下的血泪教训。6. 从98分到实际可用验证分割效果的三个额外手段98分的毕设项目、漂亮的内页截图只能证明提交节点上模型是work的但真正到现场或评审演示时最怕的是模型在没见过的岩石照片上效果打折扣。这一章聊三个我在交付前必做的小手段。第一大图直接整张推理很容易爆显存尤其是岩石表面照片往往是大尺寸高分辨率图。先把图切成256×256的重叠小块推理后再拼回去重叠区域取平均这样大图也能稳定出结果还顺带缓解了边缘拼接缝的问题# 滑动窗口推理的关键参数示意 import numpy as np def sliding_infer(model, img, size256, stride128): h, w img.shape[:2] out np.zeros((h, w), dtypenp.float32) count np.zeros((h, w), dtypenp.float32) for y in range(0, h - size 1, stride): for x in range(0, w - size 1, stride): patch img[y:ysize, x:xsize] pred model_predict_patch(model, patch) # 返回0~1概率图 out[y:ysize, x:xsize] pred count[y:ysize, x:xsize] 1 count[count 0] 1 return out / countstride取128、重叠一半是性价比最高的设置重叠太少拼接痕迹明显重叠太多推理时间翻倍。第二别只盯着loss曲线把预测的mask用OpenCV画轮廓叠到原图上并排看。具体做法是把预测mask转成cv2.findContours的轮廓再cv2.drawContours画到原图上。这一步能看出预测裂缝是否贴合真实纹理走向、有没有越界连到其它岩理纹路上。第三跑完模型后做一次轻量后处理先做开运算去掉几个像素以下的孤立白点再按连通域面积过滤掉小于50像素的碎块。这两个参数对不同分辨率图像很敏感我一般先用一张验证图观察效果再定。从那以后我每次跑岩石裂缝分割哪怕是临时验证一版模型也会强制走一遍“滑动窗口推理 轮廓叠图抽查 开运算后处理”的流程再小的细节改动也复查一次。这会占用额外时间但它能把答辩现场那种“模型在训练集上很漂亮、一换图就露馅”的风险提前干掉。希望帮到你。本文还有配套的精品资源点击获取
网站建设高端定制企业官网
RELATED

相关资讯

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

较早相关资讯

最新相关资讯

东莞公司网站开发避坑指南:3套方案对比评测 2026/9/28 5:02:03

东莞公司网站开发避坑指南:3套方案对比评测

东莞公司网站开发避坑指南:3套方案对比评测 找东莞建站公司,最怕的不是做得丑,而是报价单上藏着三四个“坑”。今天这篇对比评测,直接给你扒开底裤。 设计原则:别被“高大上”忽悠…

阅读更多 →
大模型推理优化:vLLM与TensorRT-LLM配置参数深度详解与实践 2026/9/28 5:02:03

大模型推理优化:vLLM与TensorRT-LLM配置参数深度详解与实践

大模型推理优化:vLLM与TensorRT-LLM配置参数深度详解与实践吞吐优先选vLLM,延迟苛刻选TensorRT-LLM——看似简单的选型背后,隐藏着两大框架上百个参数的精细调优。本文基于vLLM v0.6.3与TensorRT-LLM 0.14.0,从核心机制到关键参数…

阅读更多 →
JSP+Access手机销售系统:Java Web毕设快速落地指南 2026/9/28 5:02:03

JSP+Access手机销售系统:Java Web毕设快速落地指南

简介:这是一份面向Java初学者与Web开发入门者的完整课程设计实践资源,聚焦基于JSP动态网页技术与Access轻量级数据库构建手机销售管理系统的全流程实现。资源解决中小型商贸场景下商品库存、客户信息、订单处理等核心业务的信息化管理需求,兼…

阅读更多 →
1400张小麦杂草YOLO数据集:从数据解析到yolov8训练调参实战 2026/9/28 5:02:03

1400张小麦杂草YOLO数据集:从数据解析到yolov8训练调参实战

简介:面向小麦田地杂草识别与定位的目标检测数据集,包含约1400幅已标注图像,采用YOLO标注格式,覆盖8类常见杂草(RAD1、RAD2、RAD3、RAD4、RD2、RAD23、RDA3、RA1),可支撑YOLOv5等目标检测模型的…

阅读更多 →
基于Python-OpenCV与dlib的人脸录入与识别系统实战 2026/9/28 5:02:03

基于Python-OpenCV与dlib的人脸录入与识别系统实战

简介:基于Python OpenCV与dlib机器学习库开发的人脸录入与识别系统,面向有一定Python基础、希望将人脸识别落地的学习者与开发者,覆盖人脸采集、特征提取、实时比对、姓名录入等核心环节。压缩包共25个文件,包含9个py源码&#xf…

阅读更多 →
储能BMS三级架构详解:BMU/BCU/BAU功能分工与硬件设计实战 2026/9/28 5:01:56

储能BMS三级架构详解:BMU/BCU/BAU功能分工与硬件设计实战

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

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

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

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