视频 OCR 文字面积占比
更新时间:2026-09-14
简介
视频文字面积占比算子:抽帧 → EasyOCR 的 CRAFT 检测器找文本框 → 计算文字面积占帧面积的比例 → 多帧聚合成一个视频级数值。只产出占比,过滤交给下游表达式。
功能描述
- 抽帧复用存量
VideoFrameSampler(output_frames=True、output_base64=False),抽帧参数(模式、时间窗、上限等)由本算子透传,默认by_count_uniform+count_k=3 - 只加载 EasyOCR 的检测器(
recognizer=False),不加载识别模型,因此不产出文字内容;download_enabled=False,权重必须离线预置 - 单帧占比按文本框并集面积 / 帧面积计算:把所有框画进一张布尔掩码再数像素,取值恒在 [0, 1],框重叠不会重复计数
- 水平框直接用
[x_min, x_max, y_min, y_max](会先裁到画面内并纠正大小颠倒);自由四边形框用外接矩形近似 - 多帧聚合:
reduce_mode取 avg / max / min,结果保留 6 位小数 - 整列抽帧失败时该列全部按空帧处理;单帧 OCR 异常只记日志并跳过该帧,不影响同视频其它帧
- 一个视频没有任何有效帧(或全部帧检测失败)时返回 None,不是 0
- 支持三种输入形式:
video_url(本地/BOS 路径)、video_base64、video_binary;后两种会先解码成字节再连同video_format交给抽帧算子
算子参数
输入
| 输入 | 含义 |
|---|---|
| videos | 视频输入数组,内容类型由 video_src_type 决定(路径 / Base64 字符串 / bytes) |
输出
| 输出 | 含义 |
|---|---|
| ocr_area_ratio | float64,文字面积占比,取值 [0, 1];无有效帧时为 None |
参数
| 参数名称 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| video_src_type | str | "video_url" | 输入形式:video_url / video_base64 / video_binary |
| model_path | str | "/opt/aihc/model" | 权重根目录 |
| model_name | str | "EasyOCR" | 相对 model_path 的 EasyOCR 权重目录 |
| lang_list | list[str] 或 None | None | 检测语言列表,None 时取 ["ch_sim", "en"] |
| sample_mode | str | "by_count_uniform" | 抽帧模式,透传 VideoFrameSampler:by_count_uniform / by_interval_time / by_interval_frames / by_fps / by_timestamps |
| start_time_sec | float | 0.0 | 抽帧起始秒 |
| end_time_sec | float 或 None | None | 抽帧结束秒,None 表示到视频末尾 |
| count_k | int 或 None | 3 | by_count_uniform 模式的抽帧数 |
| interval_sec | float 或 None | None | by_interval_time 模式的间隔秒 |
| interval_frames | int 或 None | None | by_interval_frames 模式的间隔帧 |
| target_fps | float 或 None | None | by_fps 模式的目标帧率 |
| timestamps_sec | list[float] 或 None | None | by_timestamps 模式的时间戳列表 |
| max_frames | int 或 None | None | 抽帧数上限 |
| reduce_mode | str | "avg" | 多帧聚合方式:avg / max / min |
| video_format | str | "mp4" | 二进制 / Base64 输入的容器格式 |
| rank | int | 0 | 多卡场景 worker 序号,当前只记录不参与设备选择 |
注意事项
- 面积口径是设计如此:按文本框并集面积统计,重叠框不重复计数;自由四边形按外接矩形近似,斜排文字的占比会偏大。
- 抽帧策略:走
VideoFrameSampler的by_count_uniform,在 [start, end] 上按时间均匀取点(count_k=1取起始位置),视频时长拿不到时退化为固定随机种子的蓄水池采样。 - 送检的帧是 OpenCV 的 BGR 通道序。
- EasyOCR 权重目录缺失或 Reader 初始化失败时
__init__直接抛错,不会退化成联网下载。 - 是否用 GPU 由
aihc_udf的num_gpus推导(基类按num_gpus > 0置use_gpu),传给 EasyOCR 的gpu=参数;rank不参与选卡。
调用示例
Python
1from __future__ import annotations
2
3import os
4
5import daft
6from daft import col
7
8from daft.aihc.common.udf import aihc_udf
9from daft.aihc.functions.video.video_ocr_area_ratio import VideoOcrAreaRatio
10
11os.environ.setdefault("BOS_ENDPOINT", "http://bj.bcebos.com")
12os.environ.setdefault("BOS_REGION", "bj")
13
14if __name__ == "__main__":
15 if os.getenv("DAFT_RUNNER", "native") == "ray":
16 import ray
17 ray.init(dashboard_host="0.0.0.0", ignore_reinit_error=True)
18 daft.set_runner_ray()
19 daft.set_execution_config(actor_udf_ready_timeout=6000, min_cpu_per_task=0)
20
21ds = daft.from_pydict({"video": ["bos://your-bucket/sample.mp4"]})
22 ds = ds.with_column(
23 "ocr_area_ratio",
24 aihc_udf(
25 VideoOcrAreaRatio,
26 construct_args={
27 "video_src_type": "video_url",
28 "model_path": "/path/to/models",
29 "model_name": "EasyOCR",
30 "count_k": 3,
31 "reduce_mode": "avg",
32 },
33 num_cpus=1,
34 num_gpus=1,
35 concurrency=1,
36 batch_size=1,
37 )(col("video")),
38 )
39 # 只保留文字面积占比低于 0.3 的视频
40 ds = ds.where(col("ocr_area_ratio") < 0.3)
41 ds.show()
评价此篇文章
