图像理解方面的新动向
What’s new in image understanding
2026年6月10日
一句话判断
这场 Session 最值得关注的一件事是:Apple 终于把 Vision 框架的“像素级操作”和 Foundation Models 的“语义级理解”通过 Tool Calling 彻底打通了,以后做图像分析不用再在 CV 模型和 LLM 之间手动倒腾数据了。
这场 Session 讲了什么
以前搞图像理解,体验挺割裂的。想抠图用 Vision 框架(Vision framework),想理解图片内容得自己接 API 或者跑 Core ML 模型。今年 Apple 直接把图像输入塞进了 Foundation Models 框架,LLM 现在能直接“看”图了。更绝的是,他们给 LLM 加了基于图像的工具调用(Image-based tool calling),大模型遇到自己搞不定的像素级任务,会自动调用 Vision 的工具去干。
Vision 框架今年新增了轻点分割(Tap-to-segment)API,用户点一下或者画个圈就能抠出任意物体,而且这套 Vision 能力终于下放到 watchOS 了。这对做相册编辑、电商商品提取以及手表端图片预览的开发者来说,是直接能拿来用的现成轮子。
值得深挖的点
Vision 与 Foundation Models 的边界与桥接
Apple 这次的设计非常克制且聪明。他们没有让 LLM 去干所有事,而是明确了边界:Foundation Models 负责“语义理解”(比如看图写菜谱、识别这是啥植物),Vision 负责“像素级精确操作”(比如抠图、读条形码、找显著区域)。
通过 Image-based tool calling,LLM 可以在对话中直接调用 Vision 工具。比如你给 LLM 一张海报,让它提取上面的网址和日期。LLM 自己看不清小字,它会调用内置的条形码读取工具(BarcodeReaderTool),拿到结果后再组织语言返回。这种“大模型做调度,传统 CV 做执行”的架构,比单纯把图片扔给多模态大模型要靠谱得多,不仅省 token,准确率也高出一个量级。坑在于,你需要仔细设计 Tool 的参数(Arguments),确保传给 Vision 的图像引用(ImageReference)在会话历史(Transcript)里能正确解析。
Tap-to-segment 的交互范式与端侧代价
GenerateIterativeSegmentationRequest 这个 API 明显是对标 SAM (Segment Anything Model) 的。Apple 把它做进了 Vision 框架,意味着这是系统级优化的端侧模型。它支持点选、框选、套索甚至涂鸦,而且支持“迭代”——先点一下杯子,再点一下盘子,mask 会自动合并。
爽点在于,开发者不用再自己搞复杂的 UI 逻辑和模型推理,直接拿像素缓冲区(PixelBuffer)就能用。官方强调了首次使用需要下载模型,而且套索的线宽不能小于图像宽度的 1%。这说明端侧模型对输入噪声比较敏感,太细的线它识别不出意图。在做 UI 时,记得把画笔粗细限制住,别让用户画得太细导致分割失败。
代码片段
1. 迭代式轻点分割
场景:用户在图片上点击或框选,逐步完善抠图 mask。
// 生成初始分割 mask
let handler = ImageRequestHandler(image)
let request = GenerateIterativeSegmentationRequest(seed: point)
let observation = try await handler.perform(request)
let mask = observation?.pixelBuffer
// 添加新点,迭代细化 mask
request.addIncludedPoint(newPoint)
let refinedObservation = try await handler.perform(request)
坑:坐标系是左下角原点的归一化坐标 (0~1),别直接传 UIKit 的 CGPoint,记得做转换。
2. 让 LLM 调用自定义 Vision 工具
场景:给大模型一张植物照片,大模型自动调用你写的 Tool 去识别植物种类。
// 定义一个接收图像参数的 Tool
struct PlantIdentifierTool: Tool {
@SessionProperty(\.history) var history
@Generable
struct Arguments {
var image: ImageReference // 图像引用
}
func call(arguments: Arguments) async throws -> String {
let transcript = Transcript(history)
// 从会话历史中解析出真实的图像数据
guard let imageAttachment = arguments.image.resolve(in: transcript) else {
throw AppError.imageNotFound
}
let pixelBuffer = try imageAttachment.pixelBuffer()
return classifyPlant(pixelBuffer) // 调用你自己的分类逻辑
}
}
坑:Tool 的 Arguments 里拿到的只是 ImageReference,必须通过 Transcript 去 resolve 真实的 pixelBuffer,直接拿 reference 是没用的。
最佳实践
- 老项目迁移:如果你之前用 Core ML 跑自定义的分割模型或者 OCR,先评估下 Vision 的新 API 和 Foundation Models 的内置 Tool 能不能平替。端侧内置模型的功耗和内存占用通常比你自己跑的 Core ML 模型好得多。
- 新项目采用:做图像分析时,优先用 Foundation Models 加 Tool Calling 的组合。不要试图让 LLM 直接输出条形码内容或者精确的像素坐标,让它调用 Vision 工具去做。
- 避坑指南:Tap-to-segment 是异步且需要下载模型的,在 UI 上一定要做好 loading 状态和模型下载进度的提示,别让用户点了没反应以为 App 卡死了。可以用
downloadAssetsAPI 提前在后台拉取模型。
还有什么值得关注
- Vision 登陆 watchOS:手表上终于能跑显著性分析(Saliency analysis)了,做手表相册或消息图片预览时,可以用来自动裁剪出图片主体。
- 图像输入的 Prompt 构建:Foundation Models 的 Prompt 构建器现在支持直接塞
Attachment(image),比之前拼多模态数据结构清爽很多。