Kornia `VisualPrompter` 无 Prompt 预测修复解析:让 SAM 仅凭图像嵌入完成分割

发布时间:2026/9/24 9:51:42
Kornia `VisualPrompter` 无 Prompt 预测修复解析:让 SAM 仅凭图像嵌入完成分割 计算机视觉深度学习人工智能图像处理【免费下载链接】kornia 空间人工智能的几何计算机视觉库项目地址https://gitcode.com/kornia/kornia点击查看免费下载VisualPrompter是 Kornia 中围绕 Segment Anything ModelSAM封装的高层提示prompt推理 API支持“一次编码图像、多次查询”。本篇文章以 changelog 片段 migration-102.fixed.md 记录的 Bug 修复为切入点剖析其根因、修复方式与底层实现并给出完整可运行的实战示例帮助你理解并正确使用无 Prompt 预测能力。修复背景无 Prompt 预测为何会崩溃官方文档在 Segment Anything 模型页中明确给出了“run the prediction without prompts”无提示词运行预测的示例用法即调用predict()时不传任何 keypoints、boxes 或 masksprediction prompter.predict(multimask_outputTrue)但在本次修复之前这条调用路径会抛出一个令人困惑的异常TypeError: object of type NoneType has no len()该错误并非来自 SAM 模型本身而是来自VisualPrompter内部的 Prompt 预处理流水线。从源码看问题出在preprocess_prompts与_transform_prompts的交互上preprocess_prompts会把收集到的 keypoints、boxes 等组成列表to_transform传给_transform_prompts后者最终调用self.transforms(*prompts, data_keysdata_keys, paramsself._tfs_params)self.transforms是一个AugmentationSequential增强容器见 visual_prompter.py 与 kornia/augmentation/container/augment.py。当没有任何 prompt 时to_transform为空列表增强容器被以一个“什么都没有”的状态调用内部对None参数执行len()操作从而抛出上述 TypeError。修复方案从源头跳过空变换修复的核心思路非常直接没有 prompt 就不调用增强容器。在preprocess_prompts中源码现在这样处理# No prompt at all is a valid query (SAM then predicts from the image embedding alone); the # augmentation container cannot be called with nothing to transform. data self._transform_prompts(*to_transform, data_keysdata_keys) if to_transform else {}对应 visual_prompter.py当to_transform非空存在 keypoints 或 boxes时照常将坐标变换到与输入图像一致的坐标系当to_transform为空没有任何 prompt时直接跳过_transform_prompts令data {}。随后preprocess_prompts中基于data的取值逻辑自然走向else分支得到points None、bbox None最终构造出一个三个字段全为None的Prompts对象见 structures.py交由 SAM 的prompt_encoder处理。同时preprocess_prompts的 docstring 也补充了这段说明明确“没有任何 prompt 也是一种合法的查询”——SAM 会仅基于图像嵌入image embedding进行预测这与官方文档描述的行为完全一致。底层原理Prompt 全为空时 SAM 内部如何工作为什么“没有 prompt”也能预测关键在于 SAM 的prompt_encoder对空输入的容错设计。查看 prompt_encoder.py 的forwardbs self._get_batch_size(points, boxes, masks) sparse_embeddings torch.empty((bs, 0, self.embed_dim), deviceself._get_device()) ... if masks is not None: dense_embeddings self._embed_masks(masks) else: dense_embeddings self.no_mask_embed.weight.reshape(1, -1, 1, 1).expand( bs, -1, self.image_embedding_size[0], self.image_embedding_size[1] )三个关键点批量维度回退_get_batch_sizeprompt_encoder.py在points、boxes、masks全部为None时返回1不会对None执行取长度操作这正是修复后无 Prompt 路径能走通的基础。稀疏嵌入为空sparse_embeddings被初始化为形状(bs, 0, embed_dim)的空张量后续因为没有 points/boxes 而不做任何torch.cat。稠密嵌入回退没有 mask prompt 时使用可学习的no_mask_embed权重填充整个(bs, embed_dim, H_emb, W_emb)网格作为“无掩码提示”的稠密嵌入输入给 mask decoder。VisualPrompter.predict()随后将这些嵌入传给mask_decodervisual_prompter.py得到logits与预测 IoU 分数scores封装成SegmentationResults返回。验证测试用例如何覆盖这一修复仓库中的测试同时覆盖了修复前、后的两类行为无 Prompt 预测的回归测试tests/contrib/test_visual_prompter.py中的test_predict_without_promptstest_visual_prompter.py直接复现本 Bug 场景——set_image后不带任何参数调用predict(multimask_outputTrue)断言logits形状为(1, 3, 256, 256)、scores形状为(1, 3)3 对应multimask_outputTrue时的三候选掩码。错误路径的既有保护tests/models/test_prompter.py的test_exceptiontest_prompter.py仍然验证未调用set_image就调用predict会抛出带 An image must be set withself.set_image(...) 的异常说明“无 Prompt”不等于“无图像”图像编码仍是预测的前置条件。此外tests/contrib/test_visual_prompter.py的test_batching_pipelinetest_visual_prompter.py与tests/models/test_prompter.py的test_cardinalitytest_prompter.py验证了带 prompts 的批量路径输出形状与multimask_output的对应关系C 3 if multimask_output else 1确保修复没有破坏原有功能。实战完整使用无 Prompt 预测下面是一个完整、可直接运行的示例演示修复后的无 Prompt 预测流程import torch from kornia.io import load_image, ImageLoadType from kornia.models.sam import SamConfig from kornia.contrib.visual_prompter import VisualPrompter from kornia.core.utils import get_cuda_or_mps_device_if_available device get_cuda_or_mps_device_if_available() # 加载图像期望 (3, H, W) 的 float32 张量像素值范围 [0, 1] image load_image(./example.jpg, ImageLoadType.RGB32, device) # 默认加载 SAM ViT-H也可换 vit_b / vit_l / mobile_sam prompter VisualPrompter(SamConfig(vit_b, pretrainedTrue), devicedevice) # 一次编码预处理长边缩放 - 归一化 - pad 到 encoder 输入尺寸并缓存图像嵌入 prompter.set_image(image) # 无任何 prompt 的预测SAM 仅凭图像嵌入输出候选掩码 prediction prompter.predict(multimask_outputTrue) # prediction 是 SegmentationResultslogits (K, C, 256, 256)scores (K, C) print(prediction.logits.shape) # (1, 3, 256, 256) print(prediction.scores.shape) # (1, 3) # 取预测 IoU 分数最高的候选掩码已阈值化为 bool best_mask prediction.binary_masks[0, prediction.scores.argmax()]要点说明SamConfig(vit_b, pretrainedTrue)会在checkpointNone时自动使用 Kornia 维护的官方权重 URL见 model.py 的urls注册表传入checkpoint时pretrained会被忽略并给出警告。VisualPrompter()不带参数时默认SamConfig(model_typevit_h, pretrainedTrue)visual_prompter.py。set_image接受(3, H, W)或(B, 3, H, W)两种形状visual_prompter.py内部使用LongestMaxSize将图像长边缩放到image_encoder.img_size默认 1024随后以 SAM 数据集统计量pixel_mean[123.675, 116.28, 103.53] / 255、pixel_std[58.395, 57.12, 57.375] / 255归一化再向右、向下 pad 到(img_size, img_size)。predict()前必须先set_image否则抛出 An image must be set withself.set_image(...)beforepredictbe called!visual_prompter.py。若output_original_sizeTrue默认SegmentationResults.original_res_logits会把 256×256 的 logits 先还原到 encoder 输入尺寸、裁掉 padding再缩放到原始图像分辨率structures.py。小结与影响面本次修复以最小改动消除了VisualPrompter在无 Prompt 场景下的TypeError使官方文档示例与代码行为保持一致同时保留了AugmentationSequential在坐标变换上的既有职责。它不影响带 keypoints、boxes、masks 的常规预测路径也不影响Sam模型本身的能力。相关参考变更记录changelog.d/migration-102.fixed.md核心实现kornia/contrib/visual_prompter.py模型与配置kornia/models/sam/model.py结果数据结构kornia/models/structures.pyPrompt 编码器kornia/models/sam/architecture/prompt_encoder.py回归测试tests/contrib/test_visual_prompter.py、tests/models/test_prompter.py官方文档docs/source/models/segment_anything.rst、docs/source/applications/visual_prompting.rst赞分享计算机视觉深度学习人工智能图像处理【免费下载链接】kornia 空间人工智能的几何计算机视觉库项目地址https://gitcode.com/kornia/kornia点击查看免费下载相关推荐Kornia VisualPrompter 实战指南用 SAM 提示词驱动图像分割Kornia VisualPrompter 实战指南用 SAM 提示词驱动图像分割 导读 本指南围绕 Kornia 的 Visual Prompting视觉计算机视觉深度学习人工智能图像处理Kornia 中 Segment Anything (SAM) 的提示式分割VisualPrompter 与 Sam 模型实战指南Kornia 中 Segment Anything SAM 的提示式分割VisualPrompter 与 Sam 模型实战指南 Segment Anythin计算机视觉深度学习人工智能图像处理Kornia 中的 Segment AnythingSAM实战VisualPrompter 点/框提示分割全指南Kornia 中的 Segment AnythingSAM实战VisualPrompter 点/框提示分割全指南 导读 本文基于 Segment Any计算机视觉人工智能深度学习图像处理创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考