WWDC Quick Look 💓 By SwiftGGTeam
What's new in Vision

What's new in Vision

观看原视频

Highlight

Vision 是 Apple 的计算机视觉框架,提供人脸检测、图像分类、轮廓检测等算法。所有算法共享统一的 API 模式——学会一个就知道怎么用全部。

核心内容

Vision 的价值在于统一。开发者不用为文字识别、条码检测、人脸检测和光流估计分别学习一套完全不同的调用方式。每个能力都通过 request 暴露,再由 handler 执行,结果以 observation 返回。

这场 session 更新了三类已有请求:文字识别、条码检测和光流估计。它们延续已有框架,通过新 revision 提供能力升级。revision 的意义很实际:同一个请求类型,可以在保持调用模型稳定的前提下,获得新语言、新机器学习模型、更好的准确率或新的输出控制。

这场 session 还做了两件清理工作。第一,Vision 会把老的 face detection 和 face landmarks revision 1 映射到更新的检测器上,旧代码继续工作。第二,Xcode 的 Quick Look Preview 可以直接把 VNObservation 叠到输入图上,调试时不用再自己写可视化工具。

详细内容

1. 文字识别 revision 3:新增语言和自动语言检测(01:57

VNRecognizeTextRequestRevision3 是 Vision 文字识别的第三个 revision,也是 Live Text 背后的文本识别器。session 明确提到,这个 revision 新增了韩语和日语支持。开发者可以通过 supportedRecognitionLanguages 查询当前支持哪些语言。

另一个变化是自动语言识别。过去如果 App 要识别文字,通常需要提前知道用户会拍哪种语言,然后把语言列表写进 recognitionLanguages。现在,在 accurate recognition mode 下,可以把 automaticallyDetectsLanguage 设为 true,让 Vision 自动判断语言。

概念示例:

// Conceptual Swift based on the session transcript.
let request = VNRecognizeTextRequest()
request.revision = VNRecognizeTextRequestRevision3
request.recognitionLevel = .accurate
request.automaticallyDetectsLanguage = true

关键点:

  • VNRecognizeTextRequest() 创建文字识别请求。
  • request.revision = VNRecognizeTextRequestRevision3 明确选择第三版识别模型。
  • request.recognitionLevel = .accurate 对应 session 中提到的 accurate recognition mode 限制。
  • request.automaticallyDetectsLanguage = true 让 Vision 自动识别文本语言。

自动语言检测适合“不知道用户会拍哪种语言”的场景。session 也给出约束:语言检测偶尔会判断错误。如果 App 已经知道目标语言,最好继续设置 recognitionLanguages,并保持自动检测关闭。

概念示例:

// Conceptual Swift based on the session transcript.
let request = VNRecognizeTextRequest()
request.revision = VNRecognizeTextRequestRevision3
request.recognitionLevel = .accurate
request.recognitionLanguages = ["ja-JP", "ko-KR"]
request.automaticallyDetectsLanguage = false

关键点:

  • recognitionLanguages 用于给 Vision 明确的语言提示。
  • "ja-JP""ko-KR" 对应 session 中展示的新日语、韩语能力。
  • automaticallyDetectsLanguage = false 避免在已知语言场景里引入额外判断。

2. 条码检测 revision 3:一次检测多个码(03:34

VNDetectBarcodesRequestRevision3 把条码检测切到现代机器学习模型。session 强调了四个结果:多码图片检测更快、能识别更多码、重复检测更少、边界框更完整。

这对相机扫描类 App 很重要。旧方案在包含多个码的图片里可能逐个处理,或者返回不完整的线性码边界。revision 3 会一次处理多个码。对于 ean13 这类线性码,过去可能只返回一条线,现在边界框会围住完整可见码。

概念示例:

// Conceptual Swift based on the session transcript.
let request = VNDetectBarcodesRequest()
request.revision = VNDetectBarcodesRequestRevision3
let supported = request.supportedSymbologies

关键点:

  • VNDetectBarcodesRequest() 创建条码检测请求。
  • request.revision = VNDetectBarcodesRequestRevision3 使用第三版机器学习模型。
  • supportedSymbologies 查询 Vision 当前支持的码制。

session 还说明,文字识别 revision 3 和条码检测 revision 3 是 VisionKit Data Scanner API 的技术基础。Data Scanner 是一个可直接放进 App 的相机扫描 UI,负责设置相机流,并返回文字和条码结果。

3. 光流 revision 2:用 ML 估计视频中的局部运动(05:19

VNGenerateOpticalFlowRequestRevision2 同样改用现代机器学习模型。光流分析两张按时间顺序排列的图像,通常是视频的连续帧。结果描述第一帧里的内容要朝哪个方向移动多少,才能对应到第二帧。

Vision 返回的是 VNPixelBufferObservation。它表示整张图上的运动场,是一张双通道图像:一个通道存 X 方向位移,另一个通道存 Y 方向位移。两个通道合起来,就是每个像素位置的二维运动向量。

概念示例:

// Conceptual Swift based on the session transcript.
let request = VNGenerateOpticalFlowRequest()
request.revision = VNGenerateOpticalFlowRequestRevision2

// Run the request with two chronological video frames.
// Read the VNPixelBufferObservation result as a two-channel flow image.

关键点:

  • VNGenerateOpticalFlowRequest() 创建光流请求。
  • request.revision = VNGenerateOpticalFlowRequestRevision2 使用第二版 ML 光流模型。
  • 输入应是按时间顺序排列的两帧图像。
  • 输出的 VNPixelBufferObservation 保存每个位置的 X、Y 运动分量。

session 用海边奔跑的狗演示了差异。revision 2 更准确地捕捉水瓶运动,也能表现狗尾巴和耳朵的运动;背景噪声更少,更接近“背景不动”的真实情况。

这类结果适合三种场景。第一,安防视频中定位偏离背景的运动。session 特别说明,光流最适合固定摄像头,比如大多数安防摄像头。第二,在启动 Vision object tracker 前,先用光流找到要跟踪的运动区域。第三,把光流结果交给自己的视频处理流程,例如视频插帧或动作分析。

4. 光流输出分辨率:默认上采样,也可取网络原始输出(09:10

revision 1 总是返回和输入同分辨率的光流场。revision 2 默认也保持这个行为,但底层 ML 模型的原始输出分辨率较低。为了兼容旧行为,Vision 会用 bilinear upsampling 把网络输出放大到输入图像分辨率。

这带来一个选择。如果你已经在用旧版光流,或者需要全分辨率结果,可以接受默认上采样。如果你只想初始化 tracker,或者打算自己做上采样,可以打开 keepNetworkOutput,直接拿模型原始输出。

概念示例:

// Conceptual Swift based on the session transcript.
let request = VNGenerateOpticalFlowRequest()
request.revision = VNGenerateOpticalFlowRequestRevision2
request.keepNetworkOutput = true
request.computationAccuracy = .medium

关键点:

  • keepNetworkOutput = true 跳过 Vision 默认的上采样,返回网络原始输出。
  • computationAccuracy 用于选择可用的输出分辨率。
  • session 建议始终检查 observation 中 pixel buffer 的宽高。
  • 当网络输出和原图宽高比不同,映射回原图时需要处理分辨率和宽高比对应关系。

如果保留默认行为,Vision 会把低分辨率运动场拉伸到输入图大小。这个结果更容易接入已有代码,但会增加内存和延迟。直接使用网络输出更轻量,但开发者要自己处理坐标对应。

5. face detection 和 face landmarks 的 revision 1 被清理(11:44

Vision 最早发布时就有 face detection 和 face landmarks。五年后,Apple 已经有更高效、更准确的 revision 2 和 revision 3。这个版本会移除底层旧 revision 1 检测器,但继续支持指定 revision 1 的代码。

做法是:revision 1 请求会由 revision 2 检测器满足,同时保留 revision 1 的外部行为。session 提到两个兼容点:revision 2 会检测倒置人脸,但在满足 revision 1 请求时不会返回倒置人脸;revision 2 landmark detector 也会返回符合 revision 1 landmark constellation 的结果。

概念示例:

// Conceptual Swift based on the session transcript.
let request = VNDetectFaceLandmarksRequest()
request.revision = VNDetectFaceLandmarksRequestRevision3

关键点:

  • 已有 revision 1 代码会继续工作,不需要为了这次清理立刻改代码。
  • 新代码应显式指定 revision,而不是依赖默认行为。
  • session 建议对这些请求使用 revision 3,获得更好的准确率和性能。

6. Quick Look Preview:调试时直接看 observation 覆盖层(14:34

Vision 的结果常常是坐标、边界框、landmark 点集和 pixel buffer。只看 console 输出,很难判断结果是否落在正确目标上。Xcode 的 Quick Look Preview 现在支持 Vision observation。调试时把鼠标移到 VNObservation 上,点击预览图标,就能在输入图上看到覆盖层。

session 的 demo 用 face landmarks 展示了这个流程。代码检测到三张人脸后,Quick Look 可以分别显示每个 observation 对应的人脸框和 landmark constellation。这样开发者能直接确认“第一个 observation 是哪张脸”。

概念示例:

// Conceptual Swift based on the session transcript.
let request = VNDetectFaceLandmarksRequest()
let handler = makeImageRequestHandler(for: image)
try handler.perform([request])
let results = request.results

// Keep `handler` in scope while inspecting `results` with Quick Look Preview.

关键点:

  • VNDetectFaceLandmarksRequest() 代表 demo 中的人脸关键点请求。
  • handler.perform([request]) 运行 Vision 请求。
  • request.results 保存可在调试器中查看的 observation。
  • image request handler 必须仍在作用域内,Quick Look 才能把 observation 叠到原始输入图上。

如果 image request handler 已经离开作用域,Quick Look 仍能画出覆盖层,但无法显示原始图片。原因很直接:输入图像保存在 handler 中。这个细节适合写进调试代码规范,尤其是在 Playground 里快速试 Vision 参数时。

session 还用条码 Playground 演示 revision 2 和 revision 3 的差异。revision 2 漏掉一个条码、重复检测另一个条码,并且给出一条线;换成 revision 3 后,两个条码都被检测到,并显示完整边界框。Quick Look 的价值在这里很明显:不用写额外绘制工具,就能直接看模型输出差异。

核心启发

  • 做什么:给票据、菜单或商品标签做多语言 OCR。 为什么值得做VNRecognizeTextRequestRevision3 新增日语、韩语和自动语言检测,适合用户语言不可预知的拍摄场景。 怎么开始:用 supportedRecognitionLanguages 判断支持情况;已知语言时设置 recognitionLanguages,未知语言时在 accurate 模式下打开 automaticallyDetectsLanguage

  • 做什么:做一个一次扫描多个 QR 码或条形码的库存工具。 为什么值得做VNDetectBarcodesRequestRevision3 能一次检测多个码,重复检测更少,线性码边界框更完整。 怎么开始:把条码请求 revision 固定到 VNDetectBarcodesRequestRevision3,用 supportedSymbologies 限定 App 需要的码制。

  • 做什么:给固定摄像头视频加运动区域提示。 为什么值得做VNGenerateOpticalFlowRequestRevision2 更能区分局部运动和静止背景,session 明确提到安防摄像头是主要使用场景。 怎么开始:按时间顺序取两帧视频,运行光流请求,读取 VNPixelBufferObservation 中的 X/Y 运动分量,再把运动强度映射成热力图。

  • 做什么:在视频对象跟踪前自动选择 tracker 初始位置。 为什么值得做:session 指出光流可以帮助决定 object tracker 应该从哪里开始。 怎么开始:先用光流找出连续帧中运动最明显的区域,再把该区域作为 tracker 初始化候选。

  • 做什么:建立 Vision 调试 Playground。 为什么值得做:Quick Look Preview 可以直接在输入图上显示 observation,不用为每个请求写一套绘图函数。 怎么开始:保留 image request handler 的作用域,运行文字、条码、人脸或 landmark 请求,然后在 Xcode 或 Playground 里逐个预览 observation。

关联 Session

评论

GitHub Issues · utterances