跳转到内容

视频检测设计文档

视频检测插件用于处理工地监控视频,完成抽帧、图片生成和图片筛选,并将处理结果交付后续环节。

整体处理链路如下:

flowchart TD
    input["选取视频,配置抽帧参数和图片存储位置"] --> task["校验参数并创建后台任务"]
    task --> probe["读取视频信息,确定抽帧计划"]
    probe --> extract["FFmpeg 生成图片,写入任务临时目录"]
    extract --> filter["校验图片,按启用的策略筛选"]
    filter --> storage["将保留图片存入选定的正式存储位置"]
    storage --> record["关联图片附件与抽帧记录"]
    record --> delivery["交付图片,记录逐张处理结果"]
    delivery --> result["汇总任务状态,提供图片预览和失败明细"]
    result --> cleanup["按保留策略清理临时文件"]

本插件需要保证每张图片能够追溯到源视频和原视频时间点,同时控制图片数量、图片体积和重复图片比例。

  • 接收视频文件或视频附件引用;
  • 校验视频权限、格式、大小和时长;
  • 读取视频流、时长、帧率、分辨率和时间戳信息;
  • 根据抽帧策略调用 FFmpeg 生成图片;
  • 保存图片、帧序号、原视频时间戳和任务状态;
  • 将保留图片存入文件管理器配置的存储位置,并关联图片附件;
  • 按设计策略执行图片文件级去重和视觉近重复处理;
  • 将筛选后的图片及元数据交付后续环节;
  • 支持任务失败重试、避免任务重复处理、处理超时终止,以及任务完成后的临时文件清理。

任务入口提供视频选择、抽帧参数和图片存储位置配置;任务详情展示执行进度、生成图片和失败原因。具体处理步骤如下:

步骤处理内容处理结果
1. 提交视频与配置上传视频或选择已有视频附件,设置抽帧间隔、最大图片数量、图片尺寸和正式存储位置;未单独选择存储位置时使用插件默认配置确定源视频、抽帧规则和图片保存位置
2. 校验并创建任务检查视频读取权限、文件大小、参数范围和存储配置是否可用;保存本次任务使用的配置返回任务 ID,任务进入等待状态,用户可以离开页面
3. 准备输入视频后台读取视频附件;需要本地文件时,将远程视频下载到任务专属临时目录,不移动或覆盖原视频FFmpeg 获得可读取的输入文件
4. 读取信息与制定计划读取视频时长、可解码视频流、分辨率和时间信息,估算图片数量;预计图片数量超过上限时,停止执行并提示调整参数,避免只处理部分视频而遗漏后面的画面得到本次抽帧计划,或记录无法处理的原因
5. 抽帧并生成记录FFmpeg 将图片写入临时目录;确认单张图片写入完成后,再检查文件并保存帧序号、原视频时间点、尺寸和校验值生成临时图片及对应抽帧记录
6. 校验与筛选跳过损坏、无法读取的图片;后续启用视觉去重时,再比较相邻图片并选出代表帧,记录跳过原因和替代关系得到待保存的有效图片;MVP 不进行视觉近重复筛选
7. 保存正式图片通过文件管理器将有效图片保存到任务选定的存储位置,创建附件记录,并与抽帧记录关联;单张图片保存失败时记录原因,不进入交付步骤每张成功保存的图片具有附件 ID 和可追溯的存储信息
8. 交付图片按约定提交已保存的图片及源视频、帧序号和截取时间等信息,逐张记录成功或失败结果已确认成功的图片不重复交付,失败图片进入重试或人工处理
9. 汇总并查看结果展示生成数量、保存数量、交付数量、失败明细和后续去重的跳过数量;按截取时间查看、预览或下载有权限访问的图片任务标记为完成、部分失败或失败,用户可以定位问题帧
10. 清理临时文件正式图片保存完成后,按临时文件保留规则清理本地副本;未保存成功的图片保留到重试结束或排查期限届满释放临时空间,正式图片按独立的留存规则管理

视频处理采用异步任务方式,创建任务的请求不等待整段视频处理完成。任务完成表示本插件已完成抽帧、图片保存和约定的图片交付,不代表后续识别已经完成。具体 MVP 和后续建设范围见文末。

  • 抽帧中断:保留已完成帧的记录。MVP 可以重新执行抽帧,并按同一任务的帧标识核对,避免为已处理的图片重复建立附件;缺失图片重新生成。直接从中断时间点续抽作为后续能力。
  • 图片保存失败:保留该图片的临时文件,在有效保留期内重试保存;已经保存成功的图片不重复上传。存储空间不足或没有写入权限时,显示具体原因,不自动删除历史图片腾空间。
  • 图片交付失败:从已经保存的正式图片继续交付,不重新抽帧。请求超时、无法确认是否接收成功时,需要使用同一请求标识核对结果;仅靠本地状态不能保证接收端不重复处理。
  • 任务取消或应用重启:取消时终止本任务的 FFmpeg 进程,并停止继续保存和交付;重启后先核对未完成任务和已保存附件,再安排重试。只有确认没有任务仍在使用文件时,才能清理对应临时目录。

正式抽帧前,需要读取并保存以下媒体信息:

信息用途
视频时长估算图片数量、计算任务进度和判断超时
视频流索引明确处理哪个视频流,避免误处理音频流
原始宽高确定图片输出尺寸和识别输入尺寸
帧率辅助抽帧计算,识别恒定帧率或变帧率视频
时间基准将输出图片准确映射回原视频时间
旋转信息正确处理横屏、竖屏和旋转元数据
编解码器提前识别无法解码或需要特殊处理的视频

每张图片都要记录它是从视频的哪个时间点截取的。例如,“第 10 张”只表示它在本次任务中排第 10 位;“视频开始后 3.5 秒”才能说明它在原视频中的位置。因此,除了图片序号,还要保存截取时间,方便之后准确找到对应画面。

按照固定时间间隔抽取图片,例如每隔一段时间输出一张图片。该方式可以使用 FFmpeg 的 fps 滤镜实现。

Terminal window
ffmpeg -i input.mp4 -vf "fps=1/2" -q:v 3 frames/%08d.jpg

**优点:**实现简单、抽帧结果稳定、图片数量容易估算,适合第一阶段。
**缺点:**可能错过两个抽帧时刻之间持续时间很短的行为,固定摄像机画面也可能生成较多重复图片。

先读取视频时长,再根据目标图片数量计算抽帧间隔,使不同长度的视频生成相近数量的图片。

**优点:**便于限制单个任务的图片数量和后续处理量。
**缺点:**依赖视频时长读取;当视频时长异常、时长读取失败或视频使用变帧率时,需要额外的降级处理。

该方式适合作为固定时间间隔抽帧的数量上限控制,不建议在第一阶段作为唯一策略。

只抽取视频编码中的关键帧或 I 帧。

**优点:**处理速度快、图片数量少、适合预览和快速初筛。
**缺点:**关键帧由编码过程决定,不一定对应施工现场的隐患变化,可能漏掉关键行为。

关键帧抽取不适合作为安全隐患识别的唯一抽帧方式。

使用 FFmpeg 的 select 等滤镜,根据相邻画面的变化程度选择图片。

**优点:**在镜头切换或画面发生明显变化时,可以减少无效图片并增加变化画面的覆盖。
**缺点:**局部目标变化不一定引起全画面明显变化,摄像机抖动、光照变化、雨雪和遮挡也可能产生误触发。

该方式适合作为固定间隔抽帧的补充,不宜单独承担局部隐患的召回。

后续可以采用固定间隔和场景变化结合的方式:

  1. 先按固定时间间隔生成基础图片;
  2. 对变化明显的时间区间追加抽帧;
  3. 对追加图片进行视觉近重复判断;
  4. 将变化帧和代表帧纳入输出结果。

混合抽帧能够兼顾基础覆盖率和变化响应速度,但实现复杂度、计算量和参数标定成本较高,适合后续阶段。

方案实现复杂度图片数量控制对短暂行为的覆盖适用阶段
固定时间间隔低高中MVP
按目标数量中很高中MVP 增强
关键帧低高低预览/初筛
场景变化中中中后续增强
固定间隔加场景变化高中高后续增强
  • 图片数量控制:能不能提前估算并限制一个视频最终生成多少张图片。比如设置“每 2 秒抽 1 张”,通常可以估算图片数量;设置“最多生成 1000 张”,可以防止长视频生成过多图片。这个指标越高,图片数量越容易控制。
  • 对短暂行为的覆盖:视频中某个动作或状态只出现很短时间时,抽帧方式能不能及时截取到对应画面。比如人员快速进入画面、短暂遮挡或某个状态只持续几秒,如果抽帧间隔太长,就可能刚好错过。这个指标越高,越不容易漏掉短时间出现的画面。

这两个指标通常需要平衡:抽帧越频繁,越容易捕捉短暂行为,但生成的图片也越多;抽帧越稀疏,图片数量更容易控制,但可能漏掉短暂行为。

第一阶段采用固定时间间隔抽帧,同时设置最大图片数量、单任务超时和输出尺寸上限。抽帧间隔不在设计阶段固定为唯一值,应使用现场视频样本验证后确定默认配置。

FFmpeg 调用应由独立适配器封装,业务层传递结构化参数,不直接拼接用户输入的命令字符串。适配器负责:

  • 创建任务专属临时目录;
  • 选择输入视频和视频流;
  • 设置抽帧滤镜、输出格式、质量和尺寸;
  • 设置最大处理时长和进程超时;
  • 收集退出码、错误输出和生成文件列表;
  • 处理中断、进程异常、输出目录异常和部分文件生成等情况。

输入路径、输出路径和 FFmpeg 参数必须由服务端生成并校验,禁止将用户输入直接作为命令片段执行。

默认输出 JPG 图片。施工监控场景通常不需要透明通道,JPG 在图片体积和图像清晰度之间更容易控制。对于需要无损保存的场景,再开放 PNG 配置,不默认同时生成两种格式。

图片生成参数建议包含:

参数说明
outputFormatJPG 或 PNG
quality图片质量参数
maxWidth图片允许的最大宽度,超过后按比例缩小
maxHeight图片允许的最大高度,超过后按比例缩小
keepOriginalSize是否保留视频原始分辨率;开启后不主动缩小图片,关闭后按照最大宽度和最大高度缩小图片
maxFrames单个视频允许生成的最大图片数量

输出图片不应无条件保留 4K 原尺寸。应根据业务使用要求设置最大长边,避免图片过大导致存储和网络传输成本增加。

图片文件名应包含任务标识和帧序号,避免不同任务之间发生覆盖。图片不能只依赖文件名传递业务信息,必须通过抽帧记录保存结构化元数据。

每张图片至少保存以下信息:

字段说明
taskId视频检测任务 ID
frameId抽帧记录 ID
frameIndex当前任务内的图片序号
timestampMs图片对应的原视频时间戳
attachmentId正式图片保存成功后关联的文件附件 ID,用于查找和访问图片
imageUrl图片访问地址(采用 URL 交付时按需生成;临时地址过期后重新生成)
relativePath任务临时目录中的相对路径
width / height图片输出尺寸
fileSize图片字节数
sha256文件级校验值
status图片处理和投递状态

图片先由 FFmpeg 写入处理服务器的临时目录,再由本插件通过 NocoBase 文件管理器保存到选定的正式存储位置。用户查看和交付的是正式图片,不能将临时目录当作长期图片库。

数据存储位置说明
原视频原有视频附件的存储位置本插件读取原视频,不改变其归属或随任务清理原附件
抽帧临时文件执行 FFmpeg 的服务器上,为本任务创建的临时目录保存抽帧图片和按需下载的视频副本;不对外提供访问地址
正式抽帧图片任务选择的文件管理器存储位置选择本地存储时,文件保存到该存储配置的服务器目录;选择已启用的对象存储时,保存到对应存储桶及路径前缀
任务与图片记录应用数据库保存任务状态、附件关联、视频时间点等信息;图片文件通过附件管理,不直接写入业务字段

正式存储位置从文件管理器已有且可用的配置中选择,采用与本项目抓拍/延时摄影文档一致的配置方式。插件设置指定默认存储位置,创建任务时允许按权限另选;既没有选择也没有有效默认配置时,提示先配置存储。

以上是存储设计方案,具体服务器目录、存储桶名称以及已启用的存储类型,以部署环境的文件管理器配置为准。

临时目录根位置由部署配置指定,正式存储根位置由文件管理器配置决定。建议按任务分别组织文件,下面是命名规则示意,不是当前环境的实际路径:

临时目录根 / 应用标识 / 任务ID / 本次执行ID / frames / 帧序号.jpg
正式存储根或对象前缀 / video-inspection / 应用标识 / 年月日 / 任务ID / 帧ID.jpg

如部署环境区分租户,路径还应包含租户标识,访问时仍需执行权限校验。临时目录加入本次执行 ID,避免失败重试时混入旧文件;正式图片使用稳定的帧 ID,重试时先核对已有附件,避免重复保存。实际路径规则需通过现有存储引擎支持的方式实现,页面只显示存储位置名称、任务和图片,不暴露服务器绝对路径。

任务创建时记录选定的存储位置,之后修改插件默认配置只影响新任务。每张正式图片通过附件记录保留实际存储信息,不能在重试时直接按新的默认位置查找旧图片。

一张图片只有同时满足以下条件,才算正式保存成功:文件完整写入选定存储、附件记录创建成功、附件与抽帧记录关联成功。图片交付必须使用已完成这三个步骤的图片。

如果文件已写入但数据库关联失败,不能直接再生成一份文件。应依据任务和帧标识核对已写入文件,补齐附件关联;无法补齐的文件记入待清理列表,确认没有有效引用后再删除。数据库记录中保留附件 ID 作为长期关联,临时访问 URL 在预览或交付时生成。

文件类型保留与清理规则
已保存成功的临时图片正式附件和抽帧记录关联完成、且没有处理步骤继续使用本地文件后,可以清理本地副本;交付重试使用正式图片
未保存成功的临时图片在重试或排查期限内保留;期限届满且任务不再使用文件时清理,同时保留失败记录。后续重新处理可能需要从原视频重新抽帧
被去重跳过的临时图片在筛选结果和代表帧关系保存完成后清理,保留图片记录及跳过原因
正式图片按配置的图片保留期管理;尚待交付或重试、仍被业务引用或要求保留为证据的图片,不因临时文件清理或任务完成而删除
下载的源视频临时副本任务结束且没有抽帧或重试过程使用时清理,不删除原视频附件

采用图片 URL 交付时,接口已接收请求不一定表示图片已被读取。正式图片及其访问方式应覆盖约定的读取和重试时间,不能在收到提交成功响应后立即删除。未配置正式图片保留期时,不自动删除正式图片,由有权限的用户管理。

视频抽帧后,相邻图片可能存在大量重复画面。去重的目标不是尽可能删除图片,而是在减少重复投递的同时保留有效的隐患证据。

去重分为以下层级:

层级判断内容推荐实现方
文件级去重文件内容是否完全相同本插件
视觉近重复图片整体或局部是否高度相似本插件
目标/事件语义去重是否为同一目标或同一隐患事件不属于本插件处理范围

本插件仅根据图片文件和视觉特征进行去重,不能仅凭图片相似度判断目标身份或隐患事件是否相同。

图片生成后计算 SHA-256:

  • 文件内容完全一致时,直接标记为重复文件;
  • 重试任务时使用哈希和幂等键避免重复上传;
  • 文件级去重成本低、结果确定,可以在 MVP 阶段启用;
  • 文件内容不同但画面相似时,不能依赖 SHA-256 判断重复。

后续可采用由低成本到高成本的处理链:

  1. 对图片进行统一尺寸和颜色空间处理;
  2. 使用 pHash 或 dHash 计算感知哈希,筛选近似图片候选;
  3. 对候选图片计算 SSIM、颜色直方图或像素差异;
  4. 对相似图片进行局部区域差异分析;
  5. 在时间窗口内建立相似组并选择代表帧;
  6. 保存被跳过图片与代表帧的关联关系。

感知哈希阈值不能直接使用通用默认值。摄像头视角、图片分辨率、压缩质量、光照和天气都会影响距离分布,应使用真实工地视频样本标定阈值,并将阈值和算法版本记录在任务配置中。

全图相似度无法充分识别局部区域变化。例如,人员状态、手部动作或头部区域发生变化时,整幅画面仍可能保持高度相似;反过来,光照变化或摄像机抖动也可能导致整图差异较大。

建议采用以下处理方案:

在计算差异前对相邻图片进行缩放、裁剪和必要的几何对齐,降低摄像机轻微抖动对差异结果的影响。对于固定摄像机,可以进一步保存画面稳定区域或配置固定 ROI。

  • 使用全局感知哈希判断图片是否属于同一场景;
  • 将图片划分为多个网格或区域,分别计算局部差异;
  • 对局部差异明显的图片提高保留优先级;
  • 对只存在轻微整体位移、局部区域没有明显变化的图片,归入相似组;
  • 对差异区域较小但连续出现的图片,保留变化开始帧和清晰度最高帧。

对图片中的重点区域单独进行比较,可以减少因为整张图片相似而误删有效图片的问题。但这种方法只能发现“局部画面发生了变化”,不能判断变化具体代表哪一种安全隐患。

通过亮度归一化、颜色空间转换、局部结构相似度和时间窗口约束,降低日照变化、曝光变化和轻微抖动造成的误判。对于镜头大幅移动或画面切换,应结束当前相似组并创建新的相似组。

相似组内不应简单保留第一张图片,可以按照以下优先级选择代表帧:

  1. 清晰度更高的图片;
  2. 目标区域更完整的图片;
  3. 遮挡更少、曝光更正常的图片;
  4. 时间窗口开始和结束位置的图片;
  5. 对持续时间较长的相似组,按最小重发间隔保留周期性图片。

5.5 局部变化与持续状态的处理原则

Section titled “5.5 局部变化与持续状态的处理原则”
  • 局部区域发生明显变化时,即使全图相似度较高,也应保留变化帧;
  • 对疑似短暂出现的目标或行为,应采用保守策略,避免去重导致有效证据丢失;
  • 对状态持续稳定且只有轻微位移的连续帧,可以合并为一个视觉相似组,减少重复图片;
  • 相似组中至少保留一张清晰代表帧,必要时保留开始帧、结束帧和状态变化帧;
  • 目标身份和隐患事件的语义判断需要专门的识别与跟踪能力,不由本插件基于图片相似度推断。

抽帧和本插件范围内的图片筛选完成后,将图片及 sourceVideoId、frameId、timestampMs 等元数据按约定交付给既有的 NocoBase 识别插件;该插件的模型推理、接口内部实现和识别结果处理不在本文范围。

建议任务状态至少包含:

状态含义
pending已创建,等待处理
probing正在读取视频媒体信息
extracting正在调用 FFmpeg 抽帧
deduplicating正在执行图片校验和去重
storing正在保存正式图片并关联附件记录
sending正在交付筛选后的图片
completed抽帧和图片交付完成
partial_failed部分图片成功,部分图片失败
failed任务无法继续或全部失败
cancelled用户或系统取消
场景处理方案
视频不存在或无权限创建任务失败并返回明确错误
视频格式不支持任务失败并提示允许的格式
FFmpeg 不可用任务失败并记录运行环境信息
视频无法解码任务失败并保存脱敏后的错误摘要
单张图片生成失败记录时间戳,跳过该帧并继续处理
图片存储空间不足或无写入权限记录具体原因,保留未保存图片用于重试,不自动覆盖或删除历史图片
文件保存成功但附件关联失败核对已保存文件后补齐关联,未关联完成前不交付图片
图片交付暂时失败使用指数退避重试
图片交付被永久拒绝不重复重试,记录失败原因
处理超时终止本任务的 FFmpeg 进程并记录失败,按第 4.4 节规则保留或清理临时文件
应用重启根据任务状态恢复未完成任务

任务重试必须只处理未成功的图片,不能重复提交已经确认成功的图片。任务状态和图片状态都必须支持幂等更新。

单独维护视频检测任务记录,不将大量抽帧状态直接写入视频附件记录。

字段说明
sourceVideo源视频附件或视频记录
status任务状态
extractionMode抽帧模式,如 fixed_interval
intervalMs抽帧时间间隔
maxFrames最大图片数量
outputFormat图片输出格式
outputQuality图片质量参数
storageLocation本次任务选择的文件管理器存储位置,创建任务时确定
durationMs视频时长
frameCount生成图片数量
storedCount正式文件与附件关联均保存成功的图片数量
sentCount已提交图片数量
failedCount失败图片数量
profileVersion本次任务使用的抽帧和去重规则版本,用于区分不同处理方案
errorMessage脱敏后的失败摘要

抽帧记录用于保存每张图片的生命周期和去重关系,支持按任务、时间戳和状态查询。

后续增加视觉去重后,可扩展以下字段:

  • perceptualHash:感知哈希;
  • similarityScore:与代表帧的相似度;
  • dedupGroupId:相似组标识;
  • dedupStatus:去重处理状态,kept 表示保留,skipped_duplicate 表示因重复跳过,skipped_invalid 表示因图片无效跳过;
  • representativeFrameId:代表帧 ID;
  • deliveryRequestId:图片交付请求 ID。
  • 使用异步队列执行视频处理;
  • 限制 FFmpeg 并发数和单任务资源配额;
  • 对视频时长、图片数量、输出尺寸和总处理时长设置上限;
  • 对图片生成和图片交付分别统计耗时;
  • 按接收端约定控制单次交付的图片数量和数据大小;
  • 对长视频提供降采样、分段处理或任务拆分策略。
  • 视频和图片访问复用 NocoBase 文件权限;
  • 不向前端暴露本地绝对路径;
  • 临时 URL 限制有效期和访问范围;
  • FFmpeg 输入路径和输出路径由服务端生成;
  • 临时文件清理范围限制在任务专属目录;
  • 日志只记录任务 ID、帧 ID、时间戳和脱敏错误摘要。

MVP 阶段以完成“视频抽帧—图片生成—图片交付”的闭环为目标,具体包括:

  • 接收视频文件或视频附件引用;
  • 校验视频权限、格式、文件大小和时长;
  • 读取视频媒体信息;
  • 使用 FFmpeg 按固定时间间隔抽帧;
  • 生成 JPG 图片,并支持配置输出质量和最大尺寸;
  • 支持选择文件管理器已有的存储位置,未单独选择时使用插件默认配置;
  • 将有效图片保存为正式附件,关联源视频、帧序号、原视频时间戳和任务状态;
  • 在任务详情中查看处理结果、图片预览和失败原因;
  • 计算 SHA-256,用于文件校验和任务幂等;
  • 支持任务状态查询、失败重试、超时处理和临时文件清理;
  • 完成基础的视频、图片生成、图片交付和异常场景测试。

MVP 阶段不实现以下内容:

  • pHash、dHash、SSIM 等视觉近重复算法;
  • 基于局部区域的细微差异识别;
  • 跨帧目标跟踪和隐患事件合并;
  • 自适应抽帧、场景变化抽帧和实时视频处理。
  • 增加 pHash/dHash 候选筛选;
  • 增加 SSIM、颜色直方图和局部区域差异分析;
  • 引入图像对齐、光照归一化和摄像机抖动处理;
  • 建立时间窗口和相似组;
  • 按清晰度、目标完整度和状态变化选择代表帧;
  • 保存被跳过图片与代表帧的关联关系;
  • 使用真实工地视频标定阈值并记录算法版本。
  • 对局部区域变化明显的图片提高保留优先级;
  • 对疑似短暂行为增加临时加密抽帧;
  • 根据场景变化动态调整抽帧频率;
  • 对长时间静态画面降低抽帧频率;
  • 对镜头切换、人员快速进入和目标状态变化增加补充图片;
  • 通过回放测试验证增加召回率后带来的图片数量和资源成本。
  • 支持视频分段处理和断点续处理;
  • 支持批量任务、并发控制和优先级调度;
  • 增加任务监控、失败告警和处理耗时统计;
  • 增加不同摄像头的抽帧配置模板;
  • 形成抽帧参数、去重算法和图片交付配置的版本化管理。