Camera与AI结合:从硬件加速到智能成像
各位同学,今天我们来聊一个非常有意思的话题——Camera与AI的结合。说实话,这几年我最大的感受就是:Camera不再只是“拍清楚”的工具了。它正在变成一个“看懂世界”的传感器。而这一切的背后,离不开AI的加持。
我个人习惯把Camera+AI分成三个层次来理解:
- 底层加速层:NPU、DSP这些硬件怎么跑AI模型
- 中间处理层:AI ISP如何替代传统ISP做去噪、超分、HDR
- 上层应用层:人脸检测、物体识别怎么跟Camera预览流协同
咱们一个一个来看。
一、Camera HAL中的AI集成:NPU与DSP
先问大家一个问题:为什么要在Camera HAL里集成AI?
答案很简单——延迟。如果你把图像数据从Camera送到AP(应用处理器)跑AI,再传回来,这个来回的延迟可能高达几十毫秒。对于实时预览来说,这是不可接受的。
所以,我们得把AI推理放到离Camera最近的地方。也就是HAL层。
在Android Camera HAL中,AI集成通常有两种方式:
| 方式 | 说明 | 适用场景 |
|---|---|---|
| NPU直连 | Camera sensor通过MIPI直接连到NPU,NPU处理完再送给ISP | 高端旗舰机,追求极致低延迟 |
| DSP协同 | ISP处理完raw图后,通过共享内存送给DSP跑AI | 中端机型,平衡功耗与性能 |
我在项目中遇到过一种情况:某款芯片的NPU和ISP共用同一块DDR带宽。结果AI模型一跑,预览帧率直接掉到15fps。后来怎么解决的?我们把AI模型做了量化,从FP16降到INT8,带宽占用降了一半,帧率才回到30fps。
二、AI ISP:去噪、超分、HDR
传统ISP靠的是固定算法——比如用中值滤波去噪,用直方图均衡做HDR。但AI ISP不一样,它是用神经网络来“学习”怎么处理图像。
举个例子,去噪。传统去噪会模糊边缘,AI去噪却能区分“这是噪点”还是“这是纹理”。我做过一个对比测试:在同样ISO 3200的条件下,AI ISP的PSNR比传统ISP高了3.2dB。肉眼一看,差距非常明显。
AI ISP的典型流程是这样的:
Raw图 → AI去噪 → AI超分 → AI HDR → YUV输出
每个环节都可以用一个小型CNN模型。但要注意,模型不能太大。我建议单个模型控制在500KB以内,推理时间不超过5ms。否则预览延迟会爆炸。
三、人脸检测与物体识别:与Camera的协同
人脸检测和物体识别,说白了就是“在预览流里找东西”。但这里有个关键问题:检测是在哪个阶段做的?
我建议分两种情况:
- 预览阶段:用轻量级模型(如MNN、TFLite),跑在DSP或NPU上,只做检测,不做识别。这样延迟可以控制在10ms以内。
- 拍照阶段:用完整模型做识别,跑在GPU上,延迟可以接受。
在Camera HAL中,我通常会在Streaming Pipeline里插入一个AI节点。这个节点从ISP拿到YUV数据,送给NPU做检测,然后把检测结果(比如人脸框坐标)通过metadata传回给上层。
代码大概长这样:
// HAL层AI检测节点
void ai_detection_process(buffer_handle_t input, camera_metadata_t *metadata) {
// 1. 从input buffer获取YUV数据
// 2. 送给NPU推理
npu_run_model(input, &detection_result);
// 3. 把结果写入metadata
update_metadata(metadata, ANDROID_STATISTICS_FACE_RECTANGLES, detection_result);
}
上层App通过Camera2 API的CaptureResult就能拿到人脸框数据。整个过程对App来说是透明的。
四、CameraX与ML Kit集成
如果你不想碰HAL层,Google也给了你一条捷径——CameraX + ML Kit。
CameraX是Jetpack里的Camera库,ML Kit是Google的端侧AI框架。两者结合,你可以在App层直接实现人脸检测、物体识别、文字识别等功能。
集成方式非常简单:
// 1. 创建CameraX的ImageAnalysis
ImageAnalysis analysis = new ImageAnalysis.Builder()
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
.build();
// 2. 绑定ML Kit的人脸检测器
FaceDetector detector = FaceDetection.getClient(
new FaceDetectorOptions.Builder()
.setPerformanceMode(FaceDetectorOptions.PERFORMANCE_MODE_FAST)
.build());
// 3. 在analyzer中处理每一帧
analysis.setAnalyzer(executor, image -> {
InputImage inputImage = InputImage.fromMediaImage(image.getImage(), rotation);
detector.process(inputImage)
.addOnSuccessListener(faces -> {
// 拿到人脸框,绘制到预览上
});
});
这里有个坑:ML Kit默认跑在CPU上,性能一般。我建议在初始化时指定使用GPU或NPU加速:
FaceDetectorOptions options = new FaceDetectorOptions.Builder()
.setAccelerator(FaceDetectorOptions.ACCELERATOR_GPU)
.build();
嗯,这样帧率能提升30%以上。
五、实战:在Camera预览中实现实时人脸检测
最后,咱们来一个完整的实战。目标:在Camera预览中实时检测人脸,并绘制人脸框。
整体流程我用一张SVG图来说明:
具体实现步骤:
- 初始化CameraX:绑定PreviewView和ImageAnalysis
- 配置ML Kit:创建FaceDetector,指定GPU加速
- 处理每一帧:在analyzer中调用detector.process()
- 绘制人脸框:在PreviewView的overlay上绘制矩形
- 优化性能:如果帧率下降,降低ImageAnalysis的分辨率
我在做这个实战时,遇到过一个典型问题:人脸框总是滞后。后来发现是ImageAnalysis的背压策略没设对。用STRATEGY_KEEP_ONLY_LATEST可以保证只处理最新帧,不会积压。
好了,这一章的内容就到这里。Camera与AI的结合,说白了就是“让相机学会思考”。从HAL层的NPU加速,到AI ISP的图像增强,再到上层的实时检测,每一层都有它的挑战和乐趣。希望今天的分享能给你一些启发。
公众号:蓝海资料掘金营,微信deep3321