如何在基于Google Vision API的Android人脸识别应用中获取实际预览FPS
获取Google Vision FaceTracker示例的实际相机预览FPS
好问题!Google Vision API本身并没有直接提供获取相机预览实际FPS的接口,但我们可以通过自己统计每帧的处理时间来计算出实际帧率——不管是每秒平均FPS还是瞬时FPS都可以实现。结合你基于FaceTracker示例的场景,具体可以这么做:
方法一:计算每秒平均FPS(推荐用于稳定显示)
这种方式会统计每1秒内处理的帧数,得到的是平均帧率,数值更稳定,适合UI展示。
步骤1:在检测处理器类中定义统计变量
找到示例中的FaceDetectionProcessor类(或者你自定义的Detector.Processor<Face>实现类),添加以下成员变量:
// FPS统计相关 private long lastFpsCalculationTime = System.currentTimeMillis(); private int processedFrameCount = 0; private float averageFps = 0.0f;
步骤2:在每帧处理回调中更新统计
在receiveDetections方法里(这个方法会在每帧检测结果返回时被调用,对应每一帧的处理),加入FPS计算逻辑:
@Override public void receiveDetections(Detector.Detections<Face> detections) { // 保留你原有的人脸检测处理代码,比如更新FaceTracker等 // 开始统计FPS processedFrameCount++; long currentTime = System.currentTimeMillis(); long elapsedTime = currentTime - lastFpsCalculationTime; // 每1秒计算一次平均FPS if (elapsedTime >= 1000) { averageFps = (processedFrameCount * 1000.0f) / elapsedTime; // 重置计数器和时间戳 processedFrameCount = 0; lastFpsCalculationTime = currentTime; // 更新UI显示FPS(必须在主线程执行) runOnUiThread(() -> { // 假设你有一个TextView用来显示FPS if (fpsTextView != null) { fpsTextView.setText(String.format("平均FPS: %.1f", averageFps)); } }); } }
方法二:计算瞬时FPS(用于查看实时波动)
如果需要查看每帧的实时帧率变化(数值波动较大),可以通过计算相邻两帧的时间间隔来得到瞬时FPS:
步骤1:添加瞬时FPS统计变量
同样在FaceDetectionProcessor类中添加:
private long lastFrameTimestamp = System.nanoTime(); private float instantaneousFps = 0.0f;
步骤2:在每帧处理时计算瞬时FPS
在receiveDetections方法中加入:
@Override public void receiveDetections(Detector.Detections<Face> detections) { // 原有处理代码... // 计算瞬时FPS long currentFrameTime = System.nanoTime(); long frameIntervalNs = currentFrameTime - lastFrameTimestamp; if (frameIntervalNs > 0) { // 转换为每秒帧数(1秒=1e9纳秒) instantaneousFps = 1_000_000_000.0f / frameIntervalNs; } lastFrameTimestamp = currentFrameTime; // 更新UI runOnUiThread(() -> { if (fpsTextView != null) { fpsTextView.setText(String.format("瞬时FPS: %.1f", instantaneousFps)); } }); }
关键注意事项
- 统计的是实际处理的帧:这里统计的是经过Vision API处理的帧数,而不是相机硬件输出的原始帧数——如果检测逻辑耗时导致丢帧,这个数值会更贴合你的应用实际运行性能。
- UI更新必须在主线程:Android不允许在子线程操作UI,所以一定要用
runOnUiThread或者Handler来更新显示。 - 变量线程安全:如果你的检测处理器是在子线程运行,确保统计变量的访问是线程安全的(比如用
volatile修饰,或者加锁)。
内容的提问来源于stack exchange,提问作者sleexed
相关产品推荐
相关产品推荐

