← 返回博客

玻璃破碎检测:嵌入式离线破窗检测 SDK 与部署实践新增

玻璃破碎检测的价值(场景、流程)

窗户被击碎的声音持续不到一秒——但对安防系统,这一秒决定了响应速度,也决定了用户信任。玻璃是所有受保护资产中最脆弱的入口:无人在家的住宅、商铺橱窗与展柜、仓库采光顶。能"听见"破碎的感知层,恰好补在摄像头最稀疏的地方。

四类典型应用场景
家用摄像头、商铺、报警主机、智能门锁

场景族:家用安防摄像头(无人时段破窗检测)、商铺与仓库防盗、报警主机(声学前端)、智能门锁与门磁——以及"把几十家门店收拢到一个值班台"的连锁运营模式。

玻璃破碎声的特点:两阶段瞬态

玻璃破碎与易混淆声对比
“撞击+碎裂”结构 vs 餐具与金属碰撞

下图为一条真实玻璃破碎音频——上为波形图、下为梅尔频谱图,可以看到瞬时的撞击尖峰与随后宽频的碎裂段:

真实玻璃破碎:波形与频谱
真实玻璃破碎声示例:波形(上)+ 梅尔频谱(下)

试听素材(真实样本,点击播放):

🔊 真实玻璃破碎声样本

🔊 另一段破碎声样本

一次完整的破碎事件包含两个连续阶段:

撞击 — ——短促集中的冲击声,通常仅几毫秒

碎裂 — ——密集、宽频、快速衰减的高频振动,最典型的标志

常见混淆声的本质差异:单次碰撞(钥匙、餐具)只有孤立冲击、没有密集碎裂段;持续声(音乐、说话)没有瞬态结构。

识别方法:预处理 → 特征提取 → 算法

引擎走标准管线——自适应降噪(典型噪声下 SNR 提升 5–10dB)、分帧、时频特征提取——并叠加玻璃破碎专属的三条原则:

1. 先找事件——检测能量爆发、围绕事件分析;对持续性背景噪声天然不敏感

2. 两阶段一致性——真正的破碎必须呈现完整的"撞击 + 碎裂"结构

3. 多特征交叉验证——能量爆发速度、高频占比、衰减模式必须一致

检测流程
从采集到事件输出

告警联动业务流程

告警联动流程
验证、设备响应、通知、用户确认与超时升级

事件 → 多特征验证 → 设备端响应(录像 + 快照)→ 推送用户 → 确认或超时升级(报警主机、物业、紧急联系人)。每个环节可按业务配置。

部署:位置与标定

安装位置要点
推荐与避免模式,以及现场标定

正对玻璃 — ——拾音距离短,直达声占比高

避免死角与机柜 — ——高频碎裂证据在遮挡后衰减最快

现场标定 — ——标准声源走一遍,按环境基线设阈值

供电与防拆 — ——尽量与摄像头共杆共箱;室外注意防水防破坏

系统集成拓扑
摄像头、NVR、报警主机与 APP

SDK 运行在摄像头 SoC 内:事件进入 NVR 时间线、作为报警主机触发源、经 APP 触达用户——CPU 增量 <50MHz,事件协议可映射既有报警类型,无须改造平台。

误报控制

餐具碰撞、音乐电视等相似声,是玻璃破碎检测最大的工程挑战。我们通过多类别负样本训练与现场标定的结合,把真实场景中的误报率控制在 2% 以下。

误报控制效果
误报来源构成与优化前后对比(示意)

集成过程中如遇到新的易混淆声音,可通过反馈通道提报,我们会持续通过 OTA 提供模型更新。

连锁商铺夜间防盗

多店汇聚
门店 A/B/C 本地检测,汇聚到一个值班台

对连锁经营者,夜晚让风险成倍叠加:几十家门店夜间无人。各店本地检测,事件携带点位、时间与片段上传,一个值班台看所有门店。

远程复核流程
事件、弹窗、远程复核与有效/误报分支

先复核,再出动:事件到达后调取就近摄像头。误报 → 终止并标注;有效 → 立即升级(值班经理、就近安保、留存证据)。远程复核通常只需 30–60 秒,能把"出动有效率"大幅拉高。

与传统巡更对比
覆盖、时效、成本与证据留存
连锁运营数据
单店月误报与 30 天事件汇总(示意)

健康目标:单店月误报 ≤3 次(此前普遍 8–15 次);连锁体系内经验共享——一家门店的实战沉淀,直接增强整个体系的能力。

准确率与性能

项目
指标
准确率
96.5%
误报率
<2%
模型大小
0.2–1MB(INT8)
推理延迟
灵活可调(视平台资源)
采样率
16kHz
支持平台
ARM Linux / MIPS / x86_64;SVP / Magik 预适配
更新方式
模型/阈值 OTA,支持灰度

注:文中性能指标基于内部测试环境,实际表现取决于硬件配置与使用场景。

运行平台与硬件要求

摄像头级 SoC;CPU 增量低于 50MHz;与视频编码共享 SoC 资源;室外安装具备环境防护。

C 接口与嵌入式集成

「玻璃破碎」识别库提供简洁的流式 C 接口:调用方只需持续送入 16kHz 单声道 PCM,拼帧、Mel 预处理与模型推理全部在内部完成,帧级概率经报警策略聚合成「玻璃破碎事件」回调输出。

完整接口声明(glass_detect.h):

glass_detect.hc
/**
 * glass_detect.h — 玻璃破碎识别统一接口
 *
 * 封装 Mel 预处理 + 推理引擎 + 报警策略, 内部模型消费线程处理音频。
 * 与录音模块 (audio_capture.h) 相互独立: 调用者自行决定音频来源
 * (录音回调 / wav 文件 / 网络流), 通过 glass_detect_feed 送入, 数据任意大小。
 *
 * 用法 (实时录音模式):
 *   glass_detect_t *d = glass_detect_create(mgk_path, NULL, NULL);
 *   glass_detect_set_listener(d, on_frame, on_onset, on_offset, NULL);
 *   glass_detect_start(d);                          // 启动内部模型消费线程
 *   audio_capture_start(rec, capture_cb, d);        // 录音回调里调 glass_detect_feed
 *   ...
 *   glass_detect_stop(d);                           // 排空缓冲, 停止线程
 *   glass_detect_destroy(d);
 *
 * 用法 (wav 文件模式):
 *   glass_detect_t *d = glass_detect_create(mgk_path, NULL, NULL);
 *   glass_detect_set_listener(d, on_frame, on_onset, on_offset, NULL);
 *   glass_detect_start(d);
 *   循环读文件: glass_detect_feed(d, pcm, n);       // 任意数据大小
 *   glass_detect_stop(d);
 *   glass_detect_destroy(d);
 */

#ifndef GLASS_DETECT_H
#define GLASS_DETECT_H

#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

/* 识别事件 (报警策略输出, 用于事件结束回调) */
typedef struct {
    float start_time;       /* 事件开始时间 (秒) */
    float end_time;         /* 事件结束时间 (秒) */
    float confidence;       /* 事件置信度 */
    float max_confidence;   /* 事件内最大帧置信度 */
    int   frame_count;      /* 事件持续帧数 */
} glass_detect_event_t;

/* 帧级回调: 每帧识别结果 (模型线程内执行) */
typedef void (*glass_detect_frame_cb_t)(float glass_prob, float timestamp,
                                        void *user_data);

/* 事件开始回调: 策略判定玻璃破碎事件开始, 只有开始时间 */
typedef void (*glass_detect_onset_cb_t)(float start_time, void *user_data);

/* 事件结束回调: 策略判定玻璃破碎事件结束 (或停止识别时未结束的事件), 完整事件信息 */
typedef void (*glass_detect_offset_cb_t)(const glass_detect_event_t *event,
                                         void *user_data);

typedef struct glass_detect_s glass_detect_t;

/* 创建/销毁; alarm_name/alarm_params 可传 NULL (用默认策略及参数) */
glass_detect_t *glass_detect_create(const char *mgk_path,      /* 模型文件路径 (必填) */
                                    const char *alarm_name,    /* 报警策略名, NULL=默认 */
                                    const char *alarm_params); /* 策略参数 key=val,key=val, NULL=默认 */
void glass_detect_destroy(glass_detect_t *det);

/* 设置事件回调 (create 后调用, 也可在运行中调整); 不需要的回调传 NULL */
void glass_detect_set_listener(glass_detect_t *det,
                               glass_detect_frame_cb_t  on_frame,
                               glass_detect_onset_cb_t  on_onset,
                               glass_detect_offset_cb_t on_offset,
                               void *user_data);

/* 启动/停止识别: 启动内部模型消费线程 / 排空缓冲后停止线程 */
int  glass_detect_start(glass_detect_t *det);
void glass_detect_stop(glass_detect_t *det);
int  glass_detect_is_running(glass_detect_t *det);

/* 设置事件识别策略 (可在运行中调整) */
int glass_detect_set_alarm(glass_detect_t *det, const char *alarm_name,
                           const char *alarm_params);

/* 送入 PCM 数据 (16bit 单声道 16kHz), 线程安全, 任意数据大小 */
int glass_detect_feed(glass_detect_t *det, const int16_t *pcm, int num_samples);

#ifdef __cplusplus
}
#endif

#endif /* GLASS_DETECT_H */

最简 wav 推理示例(节选,完整文件位于 SDK 的 src/glassDetect/c/glass_demo.c):

glass_demo.cc
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "glass_detect.h"

#define DEFAULT_MGK  "glass_detect_v7.mgk"  /* 模型文件 */
#define DEFAULT_WAV  "test_glass.wav"       /* 16kHz 单声道 16bit PCM */
#define FEED_CHUNK   16000                  /* 每次送入 1 秒音频 */

/* 帧级回调: 每帧输出玻璃破碎概率 (约 1 秒一帧) */
static void on_frame(float glass_prob, float timestamp, void *user_data)
{
    (void)user_data;
    printf("%8.2fs  glass=%.4f\n", timestamp, glass_prob);
}

/* 事件开始回调: 策略判定玻璃破碎事件开始 */
static void on_onset(float start_time, void *user_data)
{
    (void)user_data;
    printf("[EVENT] glass start at %.2fs\n", start_time);
}

/* 事件结束回调: 应用层可据此做后续统计或分级响应 */
static void on_offset(const glass_detect_event_t *ev, void *user_data)
{
    (void)user_data;
    printf("[EVENT] glass end at %.2fs (dur=%.2fs, conf=%.3f, frames=%d)\n",
           ev->end_time, ev->end_time - ev->start_time,
           ev->confidence, ev->frame_count);
}

static int read_wav_pcm(const char *path, int16_t **pcm, int *n, int *sr);  /* 完整实现见源文件 */

int main(void)
{
    glass_detect_t *det;
    int16_t *pcm = NULL;
    int num_samples = 0, sample_rate = 0;
    int pos;

    if (read_wav_pcm(DEFAULT_WAV, &pcm, &num_samples, &sample_rate) != 0)
        return 1;

    /* 1. 创建识别器: 模型文件 + 默认报警策略 (NULL) */
    det = glass_detect_create(DEFAULT_MGK, NULL, NULL);
    if (!det) return 1;

    /* 2. 注册回调 (均为可选) */
    glass_detect_set_listener(det, on_frame, on_onset, on_offset, NULL);

    /* 3. 启动内部模型消费线程 */
    glass_detect_start(det);

    /* 4. 分块送入 PCM; 实时录音时改在录音回调里 feed */
    for (pos = 0; pos < num_samples; pos += FEED_CHUNK) {
        int n = num_samples - pos;
        if (n > FEED_CHUNK) n = FEED_CHUNK;
        glass_detect_feed(det, pcm + pos, n);
    }

    /* 5. 停止并销毁 */
    glass_detect_stop(det);
    glass_detect_destroy(det);
    free(pcm);
    return 0;
}

编译与运行(示例):

buildbash
$(CC) glass_demo.c -I. -L. -lglassdetect -lpthread -lm -o glass_demo
./glass_demo

结语

部署质量决定真实场景中的效果上限。如果你是安防集成商或设备厂,正在落地玻璃破碎检测,我们提供在线试用与完整的技术支持。