【HarmonyOS 7新能力|028】Core Vision Kit工程封装:把接入逻辑放进可维护的分层结构
【HarmonyOS 7新能力|028】Core Vision Kit工程封装:把接入逻辑放进可维护的分层结构

端侧视觉 AI 的演示通常只需要“取一张图并显示识别结果”,工程实现却必须处理实时帧、方向旋转、坐标换算、页面生命周期、推理背压和隐私留存。任意一环失控,都可能出现框选错位、页面退出后仍计算、内存持续增长等问题。
本文构建“受控取帧—图像归一化—端侧推理—结构化校验—坐标映射—页面渲染—及时释放”的分层链路。文中的类型、接口和阈值均为应用侧教学封装,不代表 HarmonyOS 7 Core Vision Kit 的官方 API 或模型指标;实际能力、输入格式与支持设备必须以当前 SDK 和华为官方文档为准。封面检测数值属于视觉示意,不是实测准确率。
一、先定义视觉任务与失败边界
“识别画面中的东西”过于宽泛。第一版应固定输入来源、任务类型、输出结构和用户动作,例如“在相机预览中识别有限类别,结果只用于本地叠加,不保存原始图像”。
验收目标包括:没有相机权限时不启动;只保留最新待处理帧;旋转后框选位置正确;低置信结果不展示;页面退出后迟到结果丢弃;异常路径释放图像与推理会话;原始帧默认不落盘。
二、业务层只接收稳定结果模型
页面不应直接解析平台原始对象。视觉适配器把结果映射为归一化矩形和有限标签。
interface NormalizedRect {
left: number
top: number
right: number
bottom: number
}
interface VisionDetection {
id: string
label: string
confidence: number
box: NormalizedRect
frameId: number
}
归一化坐标统一限定在 0 到 1,页面再按预览区域换算像素。这样推理输入尺寸变化不会渗透到 UI。
三、图像帧必须拥有明确所有权
相机回调提供的帧可能绑定原生缓冲区,其生命周期不一定覆盖异步推理。会话层要明确是立即复制必要数据,还是由平台支持的引用机制延长所有权。
interface FrameLease {
frameId: number
width: number
height: number
rotation: 0 | 90 | 180 | 270
timestamp: number
close(): void
}
无论推理成功、失败还是取消,close() 都要执行且可安全重复。不要把帧对象存进全局状态。
四、用会话状态机管理生命周期

页面出现不等于相机已就绪,页面消失也不等于异步任务立即停止。显式状态机能阻止关闭后的新帧进入。
type VisionSessionState =
| 'idle'
| 'requesting-permission'
| 'starting'
| 'running'
| 'stopping'
| 'stopped'
| 'failed'
interface VisionSession {
id: string
revision: number
state: VisionSessionState
latestFrameId: number
}
启动、权限返回、旋转和停止都增加 revision。异步结果提交前检查会话版本与状态。
五、预处理要记录完整几何变换
推理输入可能经过旋转、裁剪、缩放和补边。若只保存最终尺寸,结果无法准确映射回预览。应把每一步变换参数组织成可逆链路。
interface ImageTransform {
sourceWidth: number
sourceHeight: number
rotation: 0 | 90 | 180 | 270
scale: number
padX: number
padY: number
cropLeft: number
cropTop: number
}
方向信息应只应用一次,避免相机层和模型层重复旋转。裁剪区域也必须在源图边界内。
六、通过背压保持实时链路稳定

相机帧率高于推理速度时,不能无限排队。实时预览通常采用“最多一个正在处理、最多一个最新待处理帧”的策略,中间旧帧直接释放。
class LatestFrameQueue {
private pending: FrameLease | null = null
replace(frame: FrameLease): void {
this.pending?.close()
this.pending = frame
}
take(): FrameLease | null {
const frame = this.pending
this.pending = null
return frame
}
}
这不是丢失业务数据,而是用新鲜度换取实时性。离线批处理则应采用不同队列和进度策略。
七、平台能力收口在视觉适配器
图像格式转换、Core Vision 能力调用和原始错误解析都属于适配层。上层只依赖窄接口。
interface VisionInput {
frameId: number
bytes: Uint8Array
width: number
height: number
}
interface VisionPort {
infer(input: VisionInput, signal: AbortSignal): Promise<ReadonlyArray<VisionDetection>>
close(): Promise<void>
}
测试时可注入假实现,稳定复现空结果、慢结果、越界结果和异常,而不依赖真实模型。
八、所有推理结果都按不可信数据校验
即使推理运行在本地,返回值也可能因模型、输入或适配错误而异常。展示前检查有限数值、置信区间、标签白名单和矩形边界。
function validDetection(item: VisionDetection, allowed: ReadonlySet<string>): boolean {
const b = item.box
return allowed.has(item.label) && Number.isFinite(item.confidence) &&
item.confidence >= 0 && item.confidence <= 1 &&
[b.left, b.top, b.right, b.bottom].every((v) => Number.isFinite(v) && v >= 0 && v <= 1) &&
b.left < b.right && b.top < b.bottom
}
阈值是产品策略,不应散落在页面组件中。
九、坐标映射必须覆盖裁剪模式
预览常用等比填充,部分图像会超出视口并被裁剪。简单地把归一化坐标乘以视图宽高会产生偏移。需要结合源宽高、旋转、缩放和裁剪量做反变换。
interface Viewport {
width: number
height: number
contentScale: number
offsetX: number
offsetY: number
}
function toViewX(normalizedX: number, viewport: Viewport): number {
return normalizedX * viewport.width * viewport.contentScale + viewport.offsetX
}
完整实现还要处理 Y 轴、旋转和镜像。使用四角测试图比肉眼拖框更可靠。
十、迟到结果不能覆盖新画面
实时推理可能乱序完成。页面只接受当前会话、当前 revision 且不早于已展示帧号的结果。
function canCommit(session: VisionSession, resultFrameId: number, resultRevision: number): boolean {
return session.state === 'running' && resultRevision === session.revision &&
resultFrameId >= session.latestFrameId
}
页面停止或切换镜头后,旧任务即使无法立即取消,也只能完成清理,不能更新 UI 或持久化。
十一、隐私策略默认不留存原始帧
实时识别不等于需要保存图像。默认只在内存中处理帧,推理后立即释放;日志仅记录帧号、耗时、结果数量和错误码,不记录图像、完整识别文本或可识别个人信息。
interface VisionMetric {
sessionId: string
frameId: number
elapsedMs: number
resultCount: number
outcome: 'ok' | 'empty' | 'cancelled' | 'failed'
}
若业务确实需要保存,必须单独定义用户目的、授权、保存位置、保留期限和删除入口。
十二、用设备故障场景完成验收
测试覆盖:权限拒绝与撤回、空帧、异常方向、前后摄切换、快速进入退出、连续旋转、推理慢于帧率、低内存、结果含 NaN、矩形越界、模型返回空、取消后迟到结果,以及多轮启动停止后的资源基线。
还要分别检查适配填充和裁剪填充下的框选坐标,并确认深浅色模式中覆盖层可读。性能结论只能来自目标设备的可复现实测,不能由示意图或单次调试推断。
端侧视觉 AI 的可靠性来自完整链路,而不只是模型调用。把帧所有权、状态机、背压、几何变换、结果校验、迟到保护和隐私最小化放进分层结构,Core Vision Kit 才能成为可持续演进的应用能力。
更多推荐




所有评论(0)