HarmonyOS鸿蒙Next中想从摄像头里面拿出yuv图像用于面部点位识别,我看到官网说api23才支持,请问下低于23我只能用jpeg格式转吗?这个也太慢了?
HarmonyOS鸿蒙Next中想从摄像头里面拿出yuv图像用于面部点位识别,我看到官网说api23才支持,请问下低于23我只能用jpeg格式转吗?这个也太慢了? 【问题描述】:想从鸿蒙摄像头里面拿出yuv 图像用于面部点位识别,我看到官网说api23才支持,请问下低于23我只能用jpeg 格式转吗?这个也太慢了?
【问题现象】:想从鸿蒙摄像头里面拿出yuv 图像用于面部点位识别,我看到官网说api23才支持,请问下低于23我只能用jpeg 格式转吗?但hpeg转太慢了,很影响用户体验,api23以下还有其他方案吗?能不能请给的简单的demo 双路预览从ImageReceiver 可直接拿到 YUV byteBuffer
【版本信息】:开发工具版本6.0.1、Api语言版本:22
【复现代码】:未涉及
【尝试解决方案】:未涉及
更多关于HarmonyOS鸿蒙Next中想从摄像头里面拿出yuv图像用于面部点位识别,我看到官网说api23才支持,请问下低于23我只能用jpeg格式转吗?这个也太慢了?的实战教程也可以访问 https://www.itying.com/category-93-b0.html
从目前 HarmonyOS NEXT 的能力来看,你的理解基本是对的:
API 23 之前,应用层确实拿不到 Camera 输出的 YUV 原始数据流;API 23 开始才正式开放了 YUV 数据流能力。
API 23 之前的情况
在 API 22 及更早版本中,Camera Framework 对应用开放的主要是:
- PreviewOutput(预览)
- PhotoOutput(拍照)
- VideoOutput(录像)
如果通过:
ImageReceiver
获取图像数据,通常拿到的是:
JPEG
或者编码后的图像格式。
因此很多视觉算法场景会变成:
Camera
↓
JPEG
↓
解码Bitmap/PixelMap
↓
转YUV/RGB
↓
AI推理
这条链路确实比较重。
尤其是:
30fps实时人脸检测
关键点检测
活体检测
场景下性能压力会比较明显。
API 23 为什么新增 YUV
实际上就是为了解决:
CV
AI视觉
AR
OCR
人脸识别
这些场景。
API 23 开始支持:
ImageReceiver
直接输出:
YUV_420_888
开发者可以直接获取:
ArrayBuffer
ByteBuffer
避免:
JPEG编码
JPEG解码
带来的性能损耗。
API 22 有没有其他办法?
目前公开能力里基本没有真正意义上的:
Camera → 原始YUV
方案。
一般能考虑的只有下面几种。
方案1:升级到 API23
这是最推荐的方案。
因为官方已经提供:
YUV数据流
能力。
对于:
人脸关键点
人体关键点
OCR
目标检测
都是最佳方案。
方案2:降低 JPEG 分辨率
如果必须兼容 API22:
例如:
640×480
720P
而不是:
1920×1080
4K
然后:
JPEG
↓
PixelMap
↓
RGB
送入模型。
虽然还是有损耗,但延迟会下降很多。
方案3:降低推理频率
不要:
每帧推理
改为:
30fps预览
5fps推理
10fps推理
很多人脸识别场景其实够用了。
方案4:使用系统视觉服务
如果你的需求只是:
人脸检测
人脸框
关键点
而不是自己训练模型。
可以看看:
Core Vision Kit
或者相关视觉能力。
系统内部本身拿到的是底层图像流,不需要你自己处理 JPEG。
不过能力范围受系统提供的接口限制。
关于双路输出
你提到:
双路预览
Preview + ImageReceiver
这种模式在 API23 以后是支持的。
典型流程:
PreviewOutput
↓
页面显示
ImageReceiver(YUV)
↓
AI推理
但 API22 下没有开放 YUV 输出的话,即使配置双路,通常也拿不到真正的:
YUV ByteBuffer
因此不存在一个官方 Demo 能在 API22 直接通过:
ImageReceiver
拿到:
YUV_420_888
原始数据。
我的建议
如果你的业务核心是:
- 人脸关键点识别
- 活体检测
- 姿态识别
- AI视觉分析
那么:
API22 + JPEG方案
只能作为兼容方案。
真正想达到流畅体验,建议直接以:
HarmonyOS 6.1
API23
作为目标版本,使用 Camera 新增的 YUV 数据流能力。
因为 JPEG → RGB → 模型 的额外开销,不仅影响性能,还会增加功耗和发热,在实时视觉场景下体验差异会非常明显。
更多关于HarmonyOS鸿蒙Next中想从摄像头里面拿出yuv图像用于面部点位识别,我看到官网说api23才支持,请问下低于23我只能用jpeg格式转吗?这个也太慢了?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
是的,从API version 23开始,相机框架提供YUV格式图片拍照能力。
https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/camera-yuv-shooting
如果目标是实时面部点位识别,不建议把“拍照 JPEG 再转 YUV”作为主方案。JPEG 像把视频流先压成一张照片再拆开,压缩、解码、色彩转换都会吃时间,实时性会明显受影响。
从公开能力看,直接拿相机预览 YUV/原始帧这类能力和 API 版本强相关。如果官方文档标注 API23 才支持对应图像格式或帧回调,那么低于 API23 的公开接口里就不要假设可以稳定拿到同等 YUV 数据。低版本可选路线一般是:1. 降低分辨率和帧率,用 JPEG/PixelMap 转换做兜底;2. 使用系统提供的人脸/视觉能力,避免自己处理原始帧;3. 如果业务必须实时识别,优先把最低支持版本提到 API23,并在运行时做版本判断。
建议代码里按版本分支:API23 走原始帧能力,低版本走降级方案,并提示性能差异。参考来源:Camera Kit 图像输出能力、ImageKit/PixelMap、API 版本差异说明。
如果目标是 API 22,建议先按当前公开能力保守处理:官方 FAQ 里的双路预览方案是 XComponent 预览一路,再用 ImageReceiver 另一路接收图像;但 FAQ 也明确说明当前 ImageReceiver 不支持直接获取 YUV 数据,只能通过 JPEG 数据通道拿到图像数据再处理,这条链路确实会有编码/解码开销。
所以 API 23 以下如果没有设备厂商扩展能力,通常不建议把“每帧 JPEG 转 YUV”作为高帧率人脸点位识别主路径。可以考虑:
- 降低送算法的分辨率和帧率,例如预览保持高清,算法只取低分辨率/抽帧数据;
- 把 JPEG 解码、缩放、格式转换放到 worker/native 侧,避免阻塞 UI 线程;
- 如果算法 SDK 支持 RGB/NV21 以外的输入,尽量减少格式来回转换;
- 对 API 23+ 设备走直接 YUV/byteBuffer 能力,API 22 及以下走降级路径。
也就是说,API 22 下并不是你代码写法的问题,而是公开预览数据通道本身受限;如果业务强依赖实时 YUV,建议把 API 23 作为高性能路径的最低版本。
鸿蒙Next中,若API级别低于23,Camera设备默认不提供YUV输出。此时无法直接使用JPEG转换满足实时面部识别性能需求。可尝试通过ImageReader配置ImageFormat.YUV_420_888,部分设备低版本可能通过厂商扩展仍支持;若系统限制严格,则需考虑升级目标设备的API版本或使用支持NV21的旧版Camera API。
HarmonyOS NEXT(API 10+)已经支持通过 ImageReceiver 直接输出 YUV 格式图像,不需要等 API 23,也完全不必走 JPEG 解码。
只需要创建一个 YUV 格式的 ImageReceiver 作为额外的 CaptureOutput,和预览流同时使用,就能实时拿到 YUV ByteBuffer 用于面部点位识别,延迟远低于 JPEG 转换。
import camera from '@ohos.multimedia.camera';
import image from '@ohos.multimedia.image';
// 创建 YUV ImageReceiver
let receiver = image.createImageReceiver(640, 480, image.ImageFormat.YUV_420_888, 8);
receiver.on('imageArrival', () => {
receiver.readNextImage((err, img) => {
if (err || !img) return;
let y = img.getComponent(image.ComponentType.YUV_Y);
// y.byteBuffer 就是 Y 分量数据,可直接送入识别算法
img.release();
});
});
// 将 ImageReceiver 的 Surface 加入 CameraSession
let surfaceId = await receiver.getReceivingSurfaceId();
let yuvOutput = camera.createCaptureOutput(camera.OutputType.IMAGE, { surfaceId });
// 再添加正常的 PreviewOutput 用于画面显示
// 启动会话后即可双路输出
当前 NEXT 版本(API 10–12)对 ImageReceiver 的 YUV 支持已经稳定,不需要在 JPEG 上浪费性能。

