Anomalib 高分辨率图像处理Tiler 切片平铺工具的原理、参数与源码级实战【免费下载链接】anomalibAn anomaly detection library comprising state-of-the-art algorithms and features such as experiment management, hyper-parameter optimization, and edge inference.项目地址: https://gitcode.com/GitHub_Trending/an/anomalib在工业场景中高分辨率缺陷检测图像常常大于一张 GPU 显存所能容纳的尺寸直接整图推理往往面临内存溢出或精度损失。Anomalib 为此提供了anomalib.data.utils.tiler模块见 src/anomalib/data/utils/tiler.py核心类Tiler负责把大图切成可重叠的瓦片tile、在切块上执行特征提取、再把结果无损折叠回原图。读完本文你将掌握Tiler的完整参数体系、tile()/untile()的调用链、ImageUpscaleMode两种缩放模式的取舍、TilerConfigurationCallback的模型接入方式以及测试用例对切片—还原正确性的验证方法。一、模块定位Tiler 解决什么问题tiler.py的模块 docstring 明确了四项能力将大图切分为小块以便高效处理支持重叠与非重叠两种切分策略通过stride控制支持从切块重建原始图像处理缩放过程中的 padding 或插值。在 Anomalib 中Tiler不是独立使用的工具而是被模型内部的self.tiler属性消费。以 PatchCore 为例src/anomalib/models/image/patchcore/torch_model.py 中初始化为self.tiler: Tiler | None None前向传播时执行切片 → 提特征 → 折叠的闭环# 来源src/anomalib/models/image/patchcore/torch_model.py input_tensor input_tensor.type(self.memory_bank.dtype) output_size input_tensor.shape[-2:] if self.tiler: input_tensor self.tiler.tile(input_tensor) with torch.no_grad(): features self.feature_extractor(input_tensor) # ... 生成 embedding ... if self.tiler: embedding self.tiler.untile(embedding)同样的模式也出现在 STFPM、PADIM、Reverse Distillation 等模型中如 src/anomalib/models/image/stfpm/torch_model.py 中对教师/学生双分支特征分别tile/untile。也就是说切片只发生在进入 backbone 之前模型权重本身对图像尺寸无感知这是 tiling 能无侵入扩展模型处理分辨率上限的关键设计。二、Tiler 构造函数四个参数与校验规则Tiler的完整签名见 src/anomalib/data/utils/tiler.py#L207-L231from anomalib.data.utils.tiler import Tiler, ImageUpscaleMode tiler Tiler( tile_size512, # 瓦片尺寸int 或 (h, w) stride256, # 瓦片步长int 或 (h, w)None 时等于 tile_size非重叠 remove_border_count0, # 折叠前从每个瓦片四边裁去的像素数 modeImageUpscaleMode.PADDING, # 尺寸对齐时的缩放模式 )参数类型默认值说明tile_sizeint \| Sequence必填瓦片尺寸。int 表示正方形瓦片Sequence需为长度 2 的(h, w)strideint \| Sequence \| NoneNone步长。为None时回退为tile_size非重叠切分小于tile_size时产生重叠remove_border_countint0重建前从每个瓦片四边裁掉的像素数用于消除边缘伪影modeImageUpscaleModePADDING尺寸对齐策略零填充或插值从源码看构造函数中还有三条硬性校验规则stride 不得超过 tile_size。stride_h tile_size_h or stride_w tile_size_w时抛出StrideSizeError源码注释为Stride size larger than tile size produces unreliable resultstiler.py#L224-L226。直觉上步长大于瓦片会造成切块之间的空洞untile时出现无法填充的零值区域。mode 必须属于枚举。PADDING与INTERPOLATION之外的取值抛出ValueErrortiler.py#L228-L230。尺寸参数经过统一归一化。validate_size_type()把 int 展开为(n, n)、把Sequence取前两项并校验长度为 2非法类型抛TypeError长度不符抛ValueErrortiler.py#L247-L273。测试 tests/unit/data/utils/test_tiler.py#L40-L48 还验证了 OmegaConf 的ListConfig也可作为输入类型因此该模块可以直接接收 Hydra/配置系统解析出的对象。此外构造函数内部记录了self.random_tile_count 4随机切片时固定裁 4 块以及self.overlapping标志stride ! tile_size时为True后续unfold/fold依赖这些状态。三、尺寸对齐compute_new_image_size 与两种缩放模式原图尺寸往往不能被tile_size和stride整除。Tiler 的解法是先放大到可整除的尺寸切块处理后再缩回原尺寸三个函数构成这条流水线3.1 compute_new_image_size向上取整到可整除尺寸# 来源src/anomalib/data/utils/tiler.py compute_new_image_size((512, 512), (256, 256), (128, 128)) # - (512, 512) 已整除 compute_new_image_size((512, 512), (222, 222), (111, 111)) # - (555, 555) 上取整核心公式tiler.py#L85-L88当(edge - tile) % stride ! 0时edge ceil((edge - tile) / stride) * stride tile即保证最后一个瓦片的起点 瓦片尺寸不超出画布同时与步长网格对齐。3.2 ImageUpscaleMode 枚举class ImageUpscaleMode(str, Enum): PADDING padding # 零填充放大 INTERPOLATION interpolation # 插值放大upscale_image()tiler.py#L96-L135PADDING走F.pad在右/下补零INTERPOLATION走F.interpolate双线性放大。downscale_image()tiler.py#L138-L166PADDING模式直接裁切[:, :, :input_h, :input_w]INTERPOLATION模式反向插值缩小。两种模式的取舍PADDING默认原图像素原样保留多出的区域补零。docstring 中的往返示例torch.allclose(x, z)为True说明填充放大 裁切缩回是无损的INTERPOLATION原图像素被重采样改变适合对填充区域零值敏感的特征提取场景但存在数值漂移。测试 test_tiler.py#L143-L165 用 5 组非整除的(tile_size, stride)组合如(211, 213) (128, 111)交叉验证两种模式两种模式下往返后尺寸必须一致且PADDING模式下要求torch.allclose(image, reconstructed_image)。四、tile() 与 untile()切块与折叠的实现细节4.1 tile() 的执行路径tile()tiler.py#L412-L450依次完成兼容 3D 输入image.dim() 3时自动unsqueeze(0)补 batch 维测试 test_tiler.py#L51-L63 验证(3, 1024, 1024)与(1, 3, 1024, 1024)产生相同切块越界检查瓦片尺寸大于图像尺寸时抛ValueErrorTile size ... exceeds image size尺寸对齐调用compute_new_image_sizeupscale_image两种切法use_random_tilingFalse默认走__unfold()按(h, w, batch, c, tile_h, tile_w)预分配零张量双层product网格遍历所有起点切片填充后 permute 展平为(N_tiles, C, tile_h, tile_w)其中N_tiles num_patches_h * num_patches_w * batch_sizeuse_random_tilingTrue走__random_tile()用T.RandomCrop随机裁random_tile_count4块tiler.py#L275-L286。测试test_random_tiling_respects_non_square_tile_sizetest_tiler.py#L66-L71确认非正方形瓦片(128, 256)下随机裁切尺寸正确。瓦片数量公式为num_patches int((image - tile) / stride) 1每个方向各算一次例如 512×512 图像、256 瓦片、128 步长 →3×39块与模块 docstring 中tiles.shape (9, 3, 256, 256)一致。4.2 untile()重叠区平均折叠untile()tiler.py#L452-L474调用__fold()tiler.py#L333-L410关键逻辑若输入瓦片尺寸与tile_size不同例如特征图分辨率变化按比例scale tile_size / self.tile_size折算目标画布尺寸裁边沿四个方向去掉remove_border_count像素后再参与叠加避免边缘瓦片引入伪影累加 计数维护img瓦片累加和与lookup覆盖计数两张画布逐瓦片叠加平均化img img / lookup重叠像素自然取得多瓦片均值除零防护img[img ! img] 0把 NaN0/0 区域清零最后downscale_image缩回原始输入尺寸。由于折叠是求和后取平均untile(tile(x))在无处理修改的情况下可精确还原原图测试test_untile_non_overlapping_patches与test_untile_overlapping_patchestest_tiler.py#L90-L140分别在重叠/非重叠、remove_border_count ∈ {0, 5}、两种 mode 的交叉组合下断言torch.equal(image, reconstructed_image)裁掉边缘带后比较。五、接入训练流程TilerConfigurationCallback手工实例化Tiler只适合脚本实验。在 Lightning 训练/推理流水线中推荐通过TilerConfigurationCallbacksrc/anomalib/callbacks/tiler_configuration.py注入配置它与Tiler参数一一对应from anomalib.callbacks import TilerConfigurationCallback from anomalib.data.utils.tiler import ImageUpscaleMode from lightning.pytorch import Trainer callback TilerConfigurationCallback( enableTrue, # 是否启用切片默认 False tile_size512, # 默认 256 stride256, # 默认 None等于 tile_size非重叠 remove_border_count0, modeImageUpscaleMode.PADDING, ) trainer Trainer(callbacks[callback])其setup()钩子tiler_configuration.py#L107-L135在 Lightning 生命周期中被调用执行一次性的能力检测 注入if self.enable: if isinstance(pl_module, AnomalibModule) and hasattr(pl_module.model, tiler): pl_module.model.tiler Tiler( tile_sizeself.tile_size, strideself.stride, remove_border_countself.remove_border_count, modeself.mode, ) else: raise ValueError(Model does not support tiling.)两点实现事实值得注意能力契约是鸭子类型式的判定条件为isinstance(pl_module, AnomalibModule) and hasattr(pl_module.model, tiler)即模型内部类必须暴露tiler属性初始为None才被认为支持切片。从源码结构看当前具备该属性的是 PatchCore、STFPM、PADIM、Reverse Distillation 等内存库/特征蒸馏类模型回调是幂等的一次性注入setup只负责把参数物化为Tiler实例挂载到模型上之后所有tile/untile调用都发生在模型forward内部回调本身不介入数据流。注意TilerConfigurationCallback的 docstring 示例中出现的ImageUpscaleMode.AVERAGE属于文档笔误——枚举实际只定义了PADDING与INTERPOLATION两个成员tiler.py#L40-L49传入其他值会被构造函数拒绝。六、衍生应用tiled_ensemble 流水线中的 EnsembleTiler仓库中的 tiled ensemble 流水线src/anomalib/pipelines/tiled_ensemble/是Tiler的规模化应用ensemble_tiling.py 中定义了EnsembleTiler(Tiler)直接继承Tiler并额外接收image_size等参数配合helper_functions.py与prediction_merging.py实现瓦片级多模型预测 结果融合。如果你需要处理超大工业图像如整卷板材、卫星影像可以先阅读 tools/tiled_ensemble/ 下的train.py/eval.py与 ens_config.yaml它们展示了一条不依赖单个 GPU 大显存的完整训练—评测链路。七、参数选型建议基于源码行为的归纳场景建议配置依据显存紧张、可接受少量重叠tile_size512, stride256重叠瓦片让边界区域的特征获得邻域信息untile自动取均值代价是约 4 倍瓦片数追求严格无损往返modeImageUpscaleMode.PADDINGpadding 模式往返无损test_divisible_tile_size_and_stride断言allclose图像尺寸与步长网格严重错位保持 PADDING 较大tile_size插值模式会重采样全部像素异常分数分布可能漂移切块边缘存在明显伪影增大remove_border_count如 5折叠时四边裁掉对应像素测试已验证裁边后重叠还原仍精确训练期数据增广tiler.tile(image, use_random_tilingTrue)每次随机裁 4 块等价于裁剪增广但不参与untile重建八、总结anomalib.data.utils.tiler用不到 500 行代码实现了切片—处理—折叠的完整闭环compute_new_image_size/upscale_image/downscale_image处理尺寸对齐tile()/untile()完成网格化切分与重叠区平均重建TilerConfigurationCallback则把这套能力以 Lightning 回调形式无侵入地注入支持切片的 Anomalib 模型。理解其参数约束stride ≤ tile_size、tile ≤ image、mode 双枚举与校验异常StrideSizeError/ValueError后即可在高分辨率异常检测任务中按需切换重叠/非重叠、填充/插值策略或基于EnsembleTiler构建瓦片级集成流水线。关键文件索引核心实现 src/anomalib/data/utils/tiler.py回调接入 src/anomalib/callbacks/tiler_configuration.py单元测试 tests/unit/data/utils/test_tiler.py模型侧消费示例 src/anomalib/models/image/patchcore/torch_model.py瓦片集成流水线 src/anomalib/pipelines/tiled_ensemble/components/utils/ensemble_tiling.py。【免费下载链接】anomalibAn anomaly detection library comprising state-of-the-art algorithms and features such as experiment management, hyper-parameter optimization, and edge inference.项目地址: https://gitcode.com/GitHub_Trending/an/anomalib创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
