公司动态
基于报告弱标签与裂缝分割的岩芯自动化分析
钻孔岩芯是地质勘探中最直接的证据但也是让工程师最头疼的数据。一个钻孔动辄几十米岩芯编录、拍照、裂缝识别、岩性判断全靠肉眼。人看一天岩芯腰酸背痛是小事漏掉关键裂缝可能导致工程判断失误。近年来有不少团队尝试用深度学习做岩芯自动分析但卡在一个现实问题上优质标注数据太贵。请地质专家逐像素标注岩芯图像成本高到无法规模化。“Automated Borehole Core Analysis with Report-Derived Weak Labels and Supervised Crack Segmentation”这个方向提供了一条更务实的路径先利用已有的地质编录报告生成弱标签再用少量精细标注做裂缝分割。它真正解决的不是“AI 能不能看懂岩芯”而是“在标注极其昂贵的场景下AI 如何低成本启动”。这篇文章会拆解这套技术思路的原理、流程、关键代码和工程落地建议。1. 这篇文章真正要解决的问题如果只看标题很多人会以为这只是一篇“用深度学习做图像分割”的论文。但它的核心价值不在模型结构而在数据策略。岩芯分析长期依赖人工瓶颈主要有三个第一专家时间极其稀缺。岩芯编录需要地质专业人员现场或室内完成一个熟练工程师一天最多完整编录十几米岩芯。如果是深孔一个孔位就需要数周。第二图像标注成本远高于普通图像。自然图像标注看一遍就能标岩芯图像则需要懂地质背景才能判断裂缝性质、充填物、岩性边界。找学生打杂标不了必须专家上手。第三历史数据没有被利用。矿区积累了大量地质编录报告和岩芯照片但这些数据分散在 Word、Excel、PDF 里无法直接变成训练集。这套技术的核心判断是与其花巨资重新标注不如把已有报告变成标签。报告里的文字描述天然带有类别信息和区域信息尽管它是弱标签质量不如像素级标注但胜在量大、零成本、可持续更新。文章后面会解答几个关键问题报告文本如何变成可用于训练的弱标签弱标签和精细标注如何混合使用裂缝分割模型如何设计、训练和评估实际落地的边界在哪里2. 自动化岩芯分析的任务拆解与整体框架要理解这套方案先要看清岩芯分析到底包含哪些任务。从计算机视觉角度看可以分成四类。2.1 岩性识别与岩性边界分割岩性是岩芯描述的基本单位决定地层划分和矿产赋存层位。传统做法是工程师按深度记录岩性名称、颜色、结构构造。视觉模型要做的是把图像中的岩性区域分割出来属于语义分割任务。2.2 裂缝检测与裂缝分割裂缝直接影响工程稳定性和渗透性评估。工程师在编录中会记录裂缝的深度、倾角、宽度、充填物、开闭性。视觉上的裂缝分割属于细线目标分割难度高于一般物体分割因为裂缝细、对比度低、容易被噪声干扰。2.3 矿化识别与品位相关特征提取矿化区域如黄铁矿化、硅化是找矿的直接指示。这部分通常需要光谱或高分辨率图像配合是后续深化方向。2.4 结构面产状测量这已经超出纯图像识别需要结合岩芯定向信息和三维重建。但裂缝分割结果可以作为输入。这篇文章重点讨论其中两条主线岩性/地质对象的粗略定位用报告派生弱标签解决。裂缝的精细分割用监督式分割模型解决。两套方法合在一起形成“报告驱动粗分 像素级精细分割”的完整自动化分析框架。3. 报告派生弱标签Report-Derived Weak Labels核心原理3.1 什么是弱标签弱监督学习是深度学习的重要分支核心理念是用不完美、不完整、有噪声的标签训练模型。常见的弱标签形式包括图像级标签只告诉模型这张图里有裂缝不告诉裂缝在哪里。点标签在目标上点一个点不画边界。涂鸦标签画几条线表示目标所在区域。文本标签利用文字描述推断目标位置。报告派生弱标签属于“文本标签”与“图像级标签”的结合体。地质报告中的编录描述通常包含深度区间、岩性类别、裂缝发育程度、充填物性质等信息。通过深度区间对齐可以把文本标签映射到对应的岩芯图像上。3.2 为什么报告是弱标签的理想来源从工程角度看报告是零成本监督信号。矿区在勘探阶段必须形成地质编录报告这不是额外工作量而是既有产物。一份典型的岩芯编录表大致包含字段示例深度区间120.50m - 123.80m岩性花岗岩中粒结构裂缝发育程度较发育裂隙面平直充填物方解石脉充填RQD65%从这些文本中可以抽出“120.50m - 123.80m 是花岗岩裂缝较发育”这样的弱标签。如果这段岩芯有对应照片照片就被标记为“花岗岩 含裂缝”。3.3 从报告到弱标签的转换流程报告文本不是现成的 JSON需要解析。流程如下清洗 OCR 或电子表格中的编录数据。抽取深度区间、岩性描述、裂缝描述字段。根据深度区间切割岩芯图像序列。为每个图像片段生成一个图像级标签。对标签做去重和冲突处理。这里最容易出问题的是深度对齐。拍照时岩芯盒子上的深度标记可能模糊或者照片不是按箱排列的。实践中需要先做图像匹配建立照片到深度的映射表再做标签分配。3.4 弱标签的局限报告派生弱标签无法给出裂缝的精确位置只能提示“这段岩芯有裂缝”。这正是为什么需要用监督式裂缝分割做补充。弱标签的作用是让模型先学会“哪些区域值得关注”精细分析则交给分割模型。4. Supervised Crack Segmentation裂缝分割的技术方案裂缝分割是岩芯自动化分析中技术含量最高的部分。它难度大是因为裂缝具有极强的结构性特征细长、宽度不均、可能被矿物充填、光照变化下对比度不稳定。4.1 模型选型从材料看这个方向普遍采用编码器-解码器结构的语义分割网络。常见选择包括U-Net医学图像分割经典结构数据量小时表现稳定适合作为基线。DeepLabV3空洞卷积扩大感受野对细线目标有一定优势。SegFormer / Swin TransformerTransformer 结构能捕获长距离依赖适合跨岩芯段的大范围裂缝追踪但数据需求更大。工程上建议先用 U-Net 跑通再根据裂缝连续性要求决定是否升级到 Transformer 结构。4.2 损失函数选择裂缝分割存在严重的类别不平衡问题背景像素占比往往超过 95%。单纯使用交叉熵损失会导致模型退化。推荐组合# 示例组合 Dice Loss 和 BCE Loss import torch import torch.nn as nn import torch.nn.functional as F class DiceBCELoss(nn.Module): def __init__(self, smooth1e-6): super(DiceBCELoss, self).__init__() self.smooth smooth def forward(self, logits, targets): probs torch.sigmoid(logits) # BCE bce F.binary_cross_entropy_with_logits(logits, targets) # Dice intersection (probs * targets).sum() dice 1.0 - (2.0 * intersection self.smooth) / ( probs.sum() targets.sum() self.smooth ) return bce diceDice Loss 解决前景背景不平衡BCE 保持像素级误差信号两者互补。4.3 增强策略裂缝对几何变换敏感度较低所以仿射变换、弹性变换都可以用。比较有效的增强组合包括随机旋转 90 度、180 度、270 度。水平垂直翻转。随机亮度和对比度调整。弹性形变。随机裁剪到固定尺寸。需要特别注意的是岩芯图像有深度连续性的先验切片打乱后做标准增广没问题但推理时如果要恢复全孔裂缝分布最好保留深度顺序信息。5. 环境准备与数据组织5.1 运行环境本文示例以 Python PyTorch 为主版本以实际项目为准通用思路如下Python 3.9。PyTorch 2.x。torchvision。OpenCV。albumentations。pandas / openpyxl读取编录表。wandb 或 tensorboard实验跟踪。不建议一开始就上大规模分布式训练单卡 RTX 3090/4090 足够跑小批量实验。5.2 数据目录结构岩芯分析的数据组织建议按“孔号-箱号-图像”三级管理。data/ ├── borehole_BH01/ │ ├── box_001/ │ │ ├── BH01_box_001_top.jpg │ │ └── BH01_box_001_bottom.jpg │ └── box_002/ ├── reports/ │ └── BH01_core_log.csv ├── labels/ │ ├── weak_labels/ │ └── fine_masks/ └── splits/ ├── train.txt └── val.txt这种结构的好处是新钻孔数据可以直接追加不需要改动代码。5.3 报告解析示例假设编录表是一个 CSV 文件结构为深度起、深度止、岩性、裂缝描述。# 文件路径scripts/parse_report.py import pandas as pd def parse_core_log(csv_path): df pd.read_csv(csv_path, encodingutf-8-sig) # 字段标准化 df.columns [c.strip().lower() for c in df.columns] # 深度区间 df[depth_from] pd.to_numeric(df[depth_from], errorscoerce) df[depth_to] pd.to_numeric(df[depth_to], errorscoerce) # 裂缝发育程度映射 crack_map { 不发育: 0, 较发育: 1, 发育: 2, 极发育: 3, } df[crack_level] df[crack_desc].map(crack_map) return df if __name__ __main__: log parse_core_log(data/reports/BH01_core_log.csv) print(log[[depth_from, depth_to, lithology, crack_desc]].head())运行后输出depth_from depth_to lithology crack_desc 0 10.50 12.00 花岗岩 不发育 1 12.00 13.50 砂岩 较发育 2 13.50 15.00 灰岩 发育从这里可以看到报告不仅给出了岩性标签还给出了裂缝的等级信息。裂缝等级可以作为后续分割模型的后验判断辅助。6. 核心流程拆解与代码实现6.1 整体流程完整的自动化岩芯分析流程分五步读取编录报告构建深度到标签的映射。根据照片元数据建立图像到深度的映射。按深度区间为图像分配弱标签。用弱标签训练一个粗分类或注意力模型定位关注区域。用精细标注训练裂缝分割模型输出像素级裂缝掩膜。6.2 图像到深度的映射照片的深度信息通常写在岩芯盒侧面的标签上。也可以通过文件名规则解析。更可靠的方式是读取照片 EXIF 或人工检查后生成映射表。# 文件路径scripts/build_image_depth_map.py import os import re import pandas as pd def build_image_depth_map(image_dir): records [] for filename in os.listdir(image_dir): # 假设命名规则BH01_box_001_top_10.50_12.00.jpg m re.match( r([A-Z0-9])_box_(\d)_(\w)_([\d.])_([\d.])\.jpg, filename, ) if m: hole_id, box_id, position, depth_from, depth_to m.groups() records.append({ image_path: os.path.join(image_dir, filename), hole_id: hole_id, box_id: int(box_id), position: position, depth_from: float(depth_from), depth_to: float(depth_to), }) df pd.DataFrame(records) df df.sort_values([hole_id, depth_from]) return df if __name__ __main__: image_map build_image_depth_map(data/borehole_BH01) print(image_map.head())如果实际项目的照片命名没有这么规范就要用 OCR 识别盒子标签上的深度。OCR 的识别错误是深度错位的主要来源最好在生成映射后人工抽查 5% 的照片。6.3 弱标签分配拿到报告映射表和图像映射表后按深度区间做连接就可以把报告的文字标签分配到每张图片上。# 文件路径scripts/assign_weak_labels.py import pandas as pd def assign_weak_labels(report_df, image_df): weak_labels [] for _, img in image_df.iterrows(): # 查找图像深度区间与报告区间有交集的记录 mask ( (report_df[depth_from] img[depth_to]) (report_df[depth_to] img[depth_from]) ) matched report_df[mask] if len(matched) 0: continue # 如果图像跨多个地质区间取重叠比例最大的那个 overlap_start matched[depth_from].clip(lowerimg[depth_from]) overlap_end matched[depth_to].clip(upperimg[depth_to]) overlap_len (overlap_end - overlap_start).clip(lower0) best_idx overlap_len.idxmax() best matched.loc[best_idx] weak_labels.append({ image_path: img[image_path], lithology: best[lithology], crack_level: best[crack_level], }) return pd.DataFrame(weak_labels)这个逻辑的关键点是“重叠比例最大”。一张岩芯照片可能跨两个地层分界只保留重叠最大的标签虽然损失了边界信息但降低了错误标签比例。6.4 裂缝分割训练示例裂缝分割用 U-Net 作为基线。为了控制文章篇幅这里给出核心训练循环。# 文件路径train_segmentation.py import torch import torch.nn as nn from torch.utils.data import DataLoader, Dataset import cv2 import numpy as np class CrackDataset(Dataset): def __init__(self, image_paths, mask_paths, size(512, 512)): self.image_paths image_paths self.mask_paths mask_paths self.size size def __len__(self): return len(self.image_paths) def __getitem__(self, idx): image cv2.imread(self.image_paths[idx]) image cv2.cvtColor(image, cv2.COLOR_BGR2RGB) mask cv2.imread(self.mask_paths[idx], cv2.IMREAD_GRAYSCALE) image cv2.resize(image, self.size) mask cv2.resize(mask, self.size, interpolationcv2.INTER_NEAREST) image image / 255.0 mask (mask 0).astype(np.float32) image torch.from_numpy(image).permute(2, 0, 1).float() mask torch.from_numpy(mask).unsqueeze(0).float() return image, mask训练时注意裂缝掩膜是单通道二值图1 表示裂缝像素。def train_one_epoch(model, loader, optimizer, criterion, device): model.train() total_loss 0.0 for images, masks in loader: images images.to(device) masks masks.to(device) optimizer.zero_grad() logits model(images) loss criterion(logits, masks) loss.backward() optimizer.step() total_loss loss.item() return total_loss / len(loader)U-Net 的输入通道是 3输出通道 1使用 Sigmoid 激活。这里不展开完整网络结构直接使用 segmentation_models_pytorch 库可以快速搭建。pip install segmentation-models-pytorch# 文件路径create_unet.py import segmentation_models_pytorch as smp model smp.Unet( encoder_nameresnet34, encoder_weightsimagenet, in_channels3, classes1, activationNone, )使用预训练编码器可以大幅提升裂缝分割的收敛速度尤其在精细标注数量有限的情况下。6.5 推理与后处理分割模型输出的是每个像素属于裂缝的概率需要后处理才能得到干净的掩膜。# 文件路径inference.py import torch import cv2 import numpy as np def predict_cracks(model, image_path, device, threshold0.5): image cv2.imread(image_path) image cv2.cvtColor(image, cv2.COLOR_BGR2RGB) image cv2.resize(image, (512, 512)) input_tensor torch.from_numpy(image / 255.0).permute(2, 0, 1).unsqueeze(0).float() input_tensor input_tensor.to(device) model.eval() with torch.no_grad(): logits model(input_tensor) prob torch.sigmoid(logits).squeeze().cpu().numpy() crack_mask (prob threshold).astype(np.uint8) * 255 # 移除小块噪声 kernel np.ones((3, 3), np.uint8) crack_mask cv2.morphologyEx(crack_mask, cv2.MORPH_OPEN, kernel) return crack_mask后处理中形态学开运算非常关键。由于训练数据里的裂缝通常比较细模型容易在背景区域产生细小噪点通过开运算可以明显降低误检。7. 运行结果与效果评估7.1 评估指标裂缝分割的评估不能只看 Accuracy因为背景占绝对主导准确率会虚高。推荐组合指标计算方式说明IoUIntersection over Union预测与真实掩膜交集/并集分割任务核心指标Dice / F12×交集/(预测面积真实面积)适合细线目标Precision / Recall基于像素级二分类观察误检和漏检占比Crack Detection Rate裂缝片段级检测率评估裂缝是否被完整识别裂缝分割的特殊性在于像素级 IoU 高不代表裂缝完整因为裂缝细长少量像素错位就会导致 IoU 大幅变化。因此建议同时计算片段级检测率——把裂缝连通域当作一个目标只要预测结果与真实裂缝的重叠率超过阈值就认为检测成功。7.2 如何判断模型是否有效从工程角度看判断模型是否有效不能只看测试集指标。更实用的做法是随机抽 20 张岩芯图像做人工比对。统计模型漏掉的裂缝有多少是细小微裂缝。统计误检的裂缝是矿物纹理还是真实裂隙。检查不同光照条件下模型表现是否稳定。如果模型在验证集 IoU 达到 0.65 以上同时在人工抽查中裂缝片段检测率超过 80%基本可以作为辅助工具进入生产流程。7.3 失败时的排查顺序训练损失不下降或指标异常先按顺序排查确认裂缝掩膜是否对齐到图像常见问题是 resize 插值方式导致掩膜错位。确认数据增强是否过度尤其是弹性形变会不会把裂缝变形到不真实。确认损失函数是否只用了 BCE没有处理类别不平衡。确认 batch size 是否过小导致 BN 统计不稳定。8. 常见问题与排查方法问题现象可能原因排查方式解决方案弱标签和图像严重错位照片深度映射错误OCR 识别失败抽查照片标签与文件名对比增加人工校验步骤统一命名规则分割模型把矿物纹理误检为裂缝训练数据中背景纹理与裂缝难以区分可视化错误样本统计纹理特征增加难负样本调整损失函数权重裂缝预测断裂不连续模型感受野不足或损失过度偏向局部检查裂缝连通域换用空洞卷积或 Transformer 结构报告解析字段缺失编录表格式不统一打印解析失败样例增加字段别名映射和人工修正入口训练收敛慢预训练权重缺失或学习率不合适查看训练曲线加载预训练 encoder调整初始学习率推理结果出现大量细小噪点后处理缺失或阈值过低查看概率图分布增加形态学开闭运算提高阈值这里需要特别提醒任何自动分析系统都存在误检岩芯分析直接影响地质认识不能完全替代人工复核。系统输出应该定位为“辅助初判”最终编录报告仍然需要工程师确认。9. 最佳实践与工程落地建议9.1 从 30 米岩芯开始不要一开始就试图处理整个矿区的数据。先选一个钻孔、30 米左右的岩芯人工完成拍照、编录表整理、裂缝精细标注跑通端到端流程。这一步的目标不是模型精度而是验证数据链路是否可靠。9.2 弱标签和精细标注的比例从实践角度建议的节奏是第一批100 张弱标签图像 20 张精细标注图像。用弱标签训练粗分类/注意力模型过滤明显无裂缝图像。在粗模型筛选出的“含裂缝”图像中优先精细标注。逐步增加精细标注直到裂缝分割模型达到可接受精度。这样可以把专家的人肉标注时间聚焦在模型最需要的样本上而不是盲目标注全部数据。9.3 数据安全和合规岩芯数据属于地质勘探敏感数据。在工程落地时要注意地质报告和岩芯照片应保存在内网环境。训练数据脱敏后再进入外部算力平台。使用合作方数据前确认数据授权范围。模型导出和推理结果记录日志便于追溯。9.4 人机协同流程设计自动化岩芯分析的目的不是替换地质工程师而是把工程师从重复性的肉眼观察中解放出来。推荐流程是系统按深度输出岩性分段和裂缝掩膜。工程师在标注工具中快速确认或修正。修正结果自动回流到训练集。定期增量训练更新模型。这条闭环的关键是标注工具要支持“快速修正”而不是“从零标注”。9.5 版本管理和复现地质数据项目周期长模型版本和数据版本管理是刚需。建议训练数据固定后打 tag记录弱标签生成脚本版本。模型产物记录训练时间、数据版本、超参数配置。每次模型更新前用固定的验证集做回归测试。10. 总结与后续学习方向“Automated Borehole Core Analysis with Report-Derived Weak Labels and Supervised Crack Segmentation”这套思路对地质勘探 AI 落地的启示比模型本身更值得思考。它没有追求用最先进的网络结构而是从行业现实出发把“报告文本”这种被忽视的存量数据变成弱监督信号把专家有限的时间花在最有价值的精细标注上。它告诉我们在数据昂贵的垂直行业算法工程的核心瓶颈常常不是模型能力而是数据策略。后续可以从几个方向继续深入将弱标签从图像级升级到像素级可以尝试 CAMClass Activation Map或自训练方法。裂缝分割后接裂缝宽度、倾角量化分析。引入三维岩芯扫描数据结合深度信息做更精确的结构面分析。用大型视觉语言模型做报告文本和图像的跨模态对齐。如果你正在做岩芯自动化或类似的工业视觉项目建议先把报告解析和深度映射的可靠链路打通再投入精力调模型。数据链路稳定了模型迭代才有意义。