全部文章

【TECH】如何判断手指真的覆盖了摄像头

MonoPump 如何用颜色比例、亮度边界、红色占优和连续帧平滑判断什么时候可以开始测量。

计算机视觉PPG摄像头信号质量
【TECH】如何判断手指真的覆盖了摄像头

手指检测的第一个朴素版本很诱人:画面变红,就说明手指在。这个判断在桌面上测试五分钟没问题,但手机角度一变就露馅。红色物体、暗房间、边缘漏光,都可能骗过单一阈值。

手指覆盖手机摄像头,画面上叠加半透明采样网格
在计算 BPM 之前,先用低成本图像指标确认覆盖状态。

所以问题要收窄:一帧可用于测量的指尖画面到底长什么样?我们怎样拒绝那些只是看起来有点红的画面?

不再相信单个数字

真正的手指覆盖画面不是只有红这一个特征。它应该有合适亮度,不能过暗也不能过曝;红色通道要领先绿色和蓝色;而且要有足够比例的像素呈现红色占优。MonoPump 把这些线索合起来判断。

Flow diagram Preparing diagram
View diagram source
flowchart TD
    A[采样画面中心区域] --> B[计算平均 RGB]
    B --> C[亮度是否在可用范围内]
    C -- 否 --> D[太暗或太亮]
    C -- 是 --> E[红色比例是否足够]
    E -- 否 --> F[没有手指]
    E -- 是 --> G[红色占优是否稳定]
    G -- 较弱 --> H[覆盖较弱]
    G -- 较强 --> I[覆盖良好]

只采样中心区域是有意为之。预览边缘更容易受到漏光、手指弧度和移动影响。采中心区域,更像是在模拟一个小型接触式传感器。

真正有用的几个指标

MonoPump 直接从 BGRA 像素缓冲区计算几个低成本指标,因为这件事每一帧都要做。

brightness = (avgRed + avgGreen + avgBlue) / 3
redRatio = avgRed / max((avgGreen + avgBlue) / 2, 1)
redDominance = avgRed / max(avgGreen, avgBlue)
dominantRedPixelFraction = redDominantPixels / sampledPixels

亮度负责拦截明显失败。红色比例用来确认指尖带来的颜色偏移。红色占优像素比例则防止少数亮红点欺骗检测器。

良好、较弱、没有,比是和否更有用

界面需要的不只是布尔值。如果 App 只说未检测到,用户不知道该按紧一点、放松一点、遮住闪光灯,还是等一等。MonoPump 把覆盖分成几个可解释状态:没有手指、太暗、太亮、覆盖较弱、覆盖良好。

State diagram Preparing diagram
View diagram source
stateDiagram-v2
    [*] --> none
    none --> weakCoverage: 出现红色但信号弱
    weakCoverage --> good: 红色占优稳定
    good --> weakCoverage: 指压或位置变化
    weakCoverage --> none: 红色比例下降
    none --> tooDark: 亮度低于下限
    none --> tooBright: 亮度高于上限

最后还要做连续帧平滑。一帧坏数据不应该让整个测量重置,一帧好数据也不应该立刻开始。阈值放松会提高成功率,但坏信号也更容易混进来;阈值严格会提高置信度,但真实用户更容易失败。更好的边界,是只有当接下来的几秒大概率能产出可用波形时才开始。

来自 MonoWare

MonoPump 背后还有更多上下文。

打开产品网站,或继续阅读按 MonoPump 筛选的笔记。

通讯

隐私与产品工程笔记,偶尔发送。