在 Python DataFrame API 中提供了一组内置的多模态算子,用于在 Flink 作业中处理图像、视频等多模态数据。覆盖图像变换、检测、质量评估、嵌入向量、人脸处理、视频抽帧等场景。
使用限制
仅实时计算引擎VVR 11.8 及以上版本支持。
使用方法
调用方式
每个算子支持两种调用风格:
工厂函数调用
先配置算子参数,再把算子应用到一个或多个列上。适合在多个列或多个步骤中复用同一配置。
from pyflink.dataframe import col
from pyflink.multimodal.operators import image_resize
resize = image_resize(width=512, height=512)
df = df.with_column("resized", resize(col("image")))直接调用
直接把输入列传给算子,并在同一步中设置参数。
from pyflink.dataframe import col
from pyflink.multimodal.operators import image_resize
df = df.with_column(
"resized",
image_resize(col("image"), width=512, height=512),
)展开多行结果
video_split 和 video_explode_frames 会把一行输入展开为多行结果,需要通过 join_lateral 使用。
from pyflink.dataframe import col
from pyflink.multimodal.operators import video_explode_frames, video_split
segments = df.join_lateral(
video_split(segment_duration_ms=1000)(col("uri")).alias("segment")
)
frames = segments.join_lateral(
video_explode_frames(frame_selector="sample", sample_interval_ms=1000)(
col("segment")
).alias("frame", "metadata")
)通用参数
所有算子都可以通过 concurrency 控制并发处理数。部分模型类图像算子还支持批量大小和 GPU 资源参数。
参数 | 类型 | 说明 |
|
| 并发处理数。 |
|
| 每批处理的数据量。仅部分模型类图像算子支持。 |
|
| 每个并发任务申请的 GPU 份额,例如 |
|
| 指定 GPU 型号,例如 |
|
| 模型加载和复用方式。通常无需设置,未设置时使用默认方式。 |
model_sharing 支持以下取值:
取值 | 说明 |
| 不在算子级别指定,使用作业默认配置;如果作业也未配置,则等同于 |
| 默认方式。每个 Python 进程各自独立加载模型,进程内使用相同模型的算子共享权重。 |
| 同一 TaskManager 内的多个 Python 进程尽量共享同一份模型,可减少大模型的内存占用,但会有进程间通信开销。 |
数据类型说明
图像输入输出
场景 | Dataframe 类型 | 说明 |
原始图像 |
| JPEG、PNG、WEBP 等编码后的图像字节,通常来自 |
解码图像 |
| Flink 内置的图像类型,表示解码后的图像类型,用于图像变换、检测、评分和视频抽帧的结果表示。 |
图像张量 |
|
|
图像数组 |
| 对应多张图像,例如 |
视频片段引用
定义:
DataType.struct(
{
"uri": DataType.string(),
"start_time_ms": DataType.int64(),
"end_time_ms": DataType.int64()
}
)字段 | 类型 | 说明 |
|
| 视频文件路径或对象存储 URI。 |
|
| 片段开始时间,单位毫秒。 |
|
| 片段结束时间,单位毫秒。 |
该结构只描述视频片段位置,不复制视频内容。video_split 返回该结构,且它可以作为 video_explode_frames 或 video_extract_frames 的输入。
视频元数据
定义:
DataType.struct(
{
"width": DataType.int32(),
"height": DataType.int32(),
"fps": DataType.float64(),
"duration_ms": DataType.int64(),
"frame_count": DataType.int64(),
"time_base": DataType.float64(),
"codec_name": DataType.string(),
"video_stream_index": DataType.int32()
}
)字段 | 类型 | 说明 |
|
| 视频宽度,单位像素。 |
|
| 视频高度,单位像素。 |
|
| 视频帧率。 |
|
| 视频时长,单位毫秒。 |
|
| 视频帧数。 |
|
| 视频流时间基准,用于计算帧时间。 |
|
| 视频编码格式名称,例如 |
|
| 选中的视频流编号。 |
video_metadata 返回该结构。该结构常用于按分辨率、时长、编码格式过滤视频,也可传给 video_split,避免重复探测视频时长。
视频帧元数据
DataType.struct(
{
"uri": DataType.string(),
"video_stream_index": DataType.int32(),
"frame_index": DataType.int64(),
"pts": DataType.int64(),
"time_ms": DataType.int64(),
"key_frame": DataType.boolean(),
"start_time_ms": DataType.int64(),
"end_time_ms": DataType.int64()
}
)字段 | 类型 | 说明 |
|
| 原始视频文件路径或对象存储 URI。 |
|
| 输出帧所属的视频流编号。 |
|
| 输出帧在当前抽帧结果中的序号。 |
|
| 视频文件中的原始帧时间戳,通常用于和视频处理工具对齐。 |
|
| 帧对应的视频时间,单位毫秒。 |
|
| 是否为关键帧。 |
|
| 当前抽帧输入片段的开始时间,单位毫秒。 |
|
| 当前抽帧输入片段的结束时间,单位毫秒。 |
video_explode_frames 返回 DataType.image 和该元数据结构。保留该结构可以追踪每一帧来自哪个视频、哪个片段、哪个时间点。
算子概览
图像变换与生成
算子 | 说明 |
将图像字节解码为 IMAGE | |
将图像编码为压缩字节 | |
压缩图像至目标大小 | |
转换图像编码格式 | |
转换图像色彩模式 | |
将图像转换为 float32 张量 | |
缩放图像到指定尺寸 | |
按比例缩放图像 | |
裁剪图像区域 | |
裁剪图像黑边 | |
水平或垂直翻转 | |
模糊处理 | |
调整亮度、对比度和饱和度 | |
移除图像背景 |
图像检测与识别
算子 | 说明 |
YOLO 目标检测 | |
FastSAM 语义分割 | |
EasyOCR 文字提取 | |
子图/拼图检测 |
图像向量与相似度
算子 | 说明 |
生成 CLIP 图像嵌入向量 | |
计算图文余弦相似度 |
人脸处理
算子 | 说明 |
检测人脸位置 | |
统计人脸数量 | |
人脸模糊化 |
图像属性与过滤
算子 | 说明 |
检查图像是否可正常解码 | |
提取宽高、通道数、格式 | |
计算宽高比 | |
计算清晰度(拉普拉斯方差) | |
生成感知哈希值 | |
按像素尺寸过滤 | |
按宽高比过滤 | |
按文件大小过滤 |
图像质量评分
算子 | 说明 |
综合质量评分 | |
NSFW 风险评分 | |
美学评分 | |
水印检测评分 |
视频元数据、切分与抽帧
算子 | 说明 |
读取视频基本信息 | |
将视频切分为多个片段引用 | |
抽帧并展开为一帧一行 | |
抽帧并返回帧数组 |
图像变换与生成
编解码、格式转换、色彩模式转换、尺寸变换和图像增强算子。
image_decode
将原始图像字节解码为DataType.image(Decoded image)。
image_decode(*columns, on_error="raise", mode=None, pixel_limit=None, concurrency=None)参数 | 类型 | 默认值 | 说明 |
|
|
| 错误处理策略: |
|
|
| 目标色彩模式(如 |
|
|
| 超过此像素数的图像将被拒绝。 |
输入类型:DataType.binary
返回类型:DataType.image
df = df.with_column("img", image_decode(col("raw_bytes")))image_encode
将图像编码为压缩字节。
image_encode(*columns, format=None, quality=85, output="bytes", concurrency=None)参数 | 类型 | 默认值 | 说明 |
|
|
| 目标格式( |
|
|
| 压缩质量(1–100,仅 JPEG/WebP 有效)。 |
|
|
| 输出表示: |
输入类型:DataType.image
返回类型:DataType.binary 或 DataType.string
df = df.with_column("jpeg", image_encode(col("image"), format="JPEG", quality=90))image_compress
将编码图像压缩为编码字节。
image_compress(*columns, quality=85, format="JPEG", concurrency=None)参数 | 类型 | 默认值 | 说明 |
|
|
| 压缩质量(1–100)。 |
|
|
| 输出格式。 |
输入类型:DataType.binary
返回类型:DataType.binary
df = df.with_column("compressed", image_compress(col("img"), quality=60))image_convert_format
转换编码图像格式。
image_convert_format(*columns, format, concurrency=None)参数 | 类型 | 默认值 | 说明 |
|
| (必填) | 目标格式: |
输入类型:DataType.binary
返回类型:DataType.binary
df = df.with_column("png", image_convert_format(col("img"), format="PNG"))image_convert_mode
将图像转换为目标色彩模式。
image_convert_mode(*columns, mode, concurrency=None)参数 | 类型 | 默认值 | 说明 |
|
| (必填) | 目标色彩模式。 |
支持的模式:
模式 | 通道数 | 数据类型 | 说明 |
| 1 | uint8 | 灰度 |
| 2 | uint8 | 灰度 + 透明度 |
| 3 | uint8 | 彩色 |
| 4 | uint8 | 彩色 + 透明度 |
| 1 | uint16 | 灰度(16 位) |
输入类型:DataType.image
返回类型:DataType.image
df = df.with_column("gray", image_convert_mode(col("img"), mode="L"))image_to_tensor
将图像转换为固定形状的 float32 张量(缩放 + 归一化到 [0, 1])。
image_to_tensor(*columns, width, height, mode="RGB", layout="CHW", concurrency=None)参数 | 类型 | 默认值 | 说明 |
|
| (必填) | 目标宽度。 |
|
| (必填) | 目标高度。 |
|
|
| 目标色彩模式。 |
|
|
| 张量轴序: |
输入类型:DataType.image
返回类型: DataType.tensor
df = df.with_column("tensor", image_to_tensor(col("img"), width=224, height=224))image_resize
将图像缩放到指定尺寸。
image_resize(*columns, width, height, method="lanczos", concurrency=None)参数 | 类型 | 默认值 | 说明 |
|
| (必填) | 目标宽度(像素)。 |
|
| (必填) | 目标高度(像素)。 |
|
|
| 重采样方法: |
输入类型:DataType.image
返回类型:DataType.image
df = df.with_column("thumb", image_resize(col("img"), width=256, height=256))image_rescale
按比例缩放图像。
image_rescale(*columns, scale, method="lanczos", concurrency=None)参数 | 类型 | 默认值 | 说明 |
|
| (必填) | 缩放比例(如 |
|
|
| 重采样方法: |
输入类型: DataType.image
返回类型: DataType.image
df = df.with_column("half", image_rescale(col("img"), scale=0.5))image_crop
裁剪图像区域。
image_crop(*columns, crop_coords=None, crop_type="center", crop_ratio=(0.8, 0.8),
crop_size=None, concurrency=None)参数 | 类型 | 默认值 | 说明 |
|
|
| 裁剪绝对像素坐标 |
|
|
| 裁剪方式,支持 |
|
|
| 中心比例裁剪时保留的宽高比例。与 |
|
|
| 中心尺寸裁剪时的输出尺寸 |
输入类型:DataType.image
返回类型:DataType.image
df = df.with_column("cropped", image_crop(col("img"), crop_ratio=(0.9, 0.9)))
df = df.with_column("roi", image_crop(col("img"), crop_coords=(10, 10, 200, 200)))image_crop_black_border
检测并裁剪图像黑边。
image_crop_black_border(*columns, threshold=None, detect_algorithm="auto",
black_threshold=10, edge_sensitivity=1.0,
min_border_size=1, concurrency=None)参数 | 类型 | 默认值 | 说明 |
|
|
| 旧版阈值参数,用于控制黑边检测阈值。,建议使用 |
|
|
| 检测算法: |
|
|
| 像素值低于此值视为黑色。 |
|
|
| 边缘检测灵敏度。 |
|
|
| 触发裁剪的最小黑边宽度(像素)。 |
输入类型:DataType.image
返回类型:DataType.image
df = df.with_column("clean", image_crop_black_border(col("img")))image_flip
水平或垂直翻转图像。
image_flip(*columns, mode="horizontal", concurrency=None)参数 | 类型 | 默认值 | 说明 |
|
|
| 翻转方向: |
输入类型:DataType.image
返回类型:DataType.image
df = df.with_column("flipped", image_flip(col("img"), mode="vertical"))image_blur
对图像应用模糊处理。
image_blur(*columns, radius=2, blur_type="gaussian", concurrency=None)参数 | 类型 | 默认值 | 说明 |
|
|
| 模糊核半径。 |
|
|
| 模糊算法: |
输入类型:DataType.image
返回类型:DataType.image
df = df.with_column("blurred", image_blur(col("img"), radius=5))image_adjust_color
调整亮度、对比度和饱和度。
image_adjust_color(*columns, brightness=1.0, contrast=1.0,saturation=1.0, concurrency=None)参数 | 类型 | 默认值 | 说明 |
|
|
| 亮度因子。 |
|
|
| 对比度因子。 |
|
|
| 饱和度因子。 |
输入类型:DataType.image
返回类型:DataType.image
df = df.with_column("bright", image_adjust_color(col("img"), brightness=1.5))image_remove_background
移除图像背景
依赖: pip install rembg
image_remove_background(*columns, alpha_matting=False,
alpha_matting_foreground_threshold=240,
alpha_matting_background_threshold=10,
alpha_matting_erode_size=10,
bgcolor=None, model_sharing=None,
concurrency=None, batch_size=None,
num_gpus=None, gpu_type=None)参数 | 类型 | 默认值 | 说明 |
|
|
| 启用 alpha matting 以获得更平滑的边缘。 |
|
|
| Alpha matting 前景阈值。 |
|
|
| Alpha matting 背景阈值。 |
|
|
| Alpha matting 腐蚀核大小。 |
|
|
| 背景颜色,格式为 |
输入类型:DataType.image
返回类型:DataType.image
df = df.with_column("fg", image_remove_background(col("image")))图像检测与识别
目标检测、文字识别、语义分割和子图检测算子。
image_detect_objects
使用 YOLO 检测目标物体。
依赖: pip install ultralytics
image_detect_objects(*columns, model="yolov8n", confidence=0.05, imgsz=640,
iou=0.5, model_sharing=None, concurrency=None,
batch_size=None, num_gpus=None, gpu_type=None)参数 | 类型 | 默认值 | 说明 |
|
|
| YOLO 模型名称或路径。 |
|
|
| 最小检测置信度,范围 |
|
|
| 模型推理分辨率。值越大对小目标检测越准,但延迟和显存消耗也越高。 |
|
|
| NMS 的 IoU 阈值,范围 |
输入类型:DataType.image
返回类型:
DataType.list(
DataType.struct(
{
"label": DataType.string(),
"x": DataType.float64(),
"y": DataType.float64(),
"w": DataType.float64(),
"h": DataType.float64(),
"confidence": DataType.float64(),
}
)字段说明:
字段 | 类型 | 说明 |
|
| 检测到的目标类别。 |
|
| 边界框左上角 x 坐标。 |
|
| 边界框左上角 y 坐标。 |
|
| 边界框宽度。 |
|
| 边界框高度。 |
|
| 检测置信度。 |
objs = image_detect_objects(confidence=0.25)
df = df.with_column("objects", objs(col("img")))image_segment
使用 FastSAM 生成语义分割掩码。
依赖: pip install ultralytics
image_segment(*columns, model="FastSAM-x.pt", imgsz=1024, confidence=0.05,
iou=0.5, model_sharing=None, concurrency=None,
batch_size=None, num_gpus=None, gpu_type=None)参数 | 类型 | 默认值 | 说明 |
|
|
| FastSAM 模型名称或路径。 |
|
|
| 模型推理分辨率。值越大掩码精度越高,但延迟和显存消耗也越高。 |
|
|
| 最小置信度,范围 |
|
|
| NMS 的 IoU 阈值,范围 |
输入类型:DataType.image
返回类型:DataType.binary(PNG 编码的分割掩码,每个唯一像素值代表一个分割区域 ID)
df = df.with_column("mask", image_segment(col("img")))image_ocr
使用 EasyOCR 从图像中提取文字。
依赖: pip install easyocr
image_ocr(*columns, lang=None, model_sharing=None, concurrency=None,
batch_size=None, num_gpus=None, gpu_type=None)参数 | 类型 | 默认值 | 说明 |
|
|
| 语言代码列表,如 |
lang支持以下语言代码:
语言组 | 代码 |
拉丁字符 |
|
阿拉伯字符 |
|
西里尔字符 |
|
天城文 |
|
孟加拉文 |
|
其他 |
|
多语言识别需要使用同一组兼容语言。en可以和多数语言一起使用;不要在同一个 lang中混用多个非英文语言组,例如不要同时设置中文和日文。
输入类型:DataType.image
返回类型:
DataType.list(
DataType.struct(
{
"text": DataType.string(),
"confidence": DataType.float64(),
"bbox": DataType.list(DataType.list(DataType.float64())),
}
)
)字段说明:
字段 | 类型 | 说明 |
|
| 识别出的文本内容。 |
|
| OCR 置信度。 |
|
| 文本区域四个角点坐标,格式为 |
每个元素代表一个检测到的文字区域。
ocr = image_ocr(lang=["en", "ch_sim"])
df = df.with_column("text", ocr(col("img")))image_detect_subplot
判断图像是否为拼接图、宫格图或 subplot,并返回估计子图数量。
依赖: pip install opencv-python
image_detect_subplot(*columns, threshold=0.5, concurrency=None)参数 | 类型 | 默认值 | 说明 |
|
|
| 边缘检测灵敏度,范围 |
任意边小于 20 像素的图像始终返回 (False, 1)。
输入类型:DataType.image
返回类型:
DataType.struct(
{
"is_subplot": DataType.boolean(),
"count": DataType.int32(),
}
)字段说明:
字段 | 类型 | 说明 |
|
| 是否检测到拼图或子图结构。 |
|
| 估计的子图数量。非拼图时为 |
df = df.with_column("subplot", image_detect_subplot(col("img")))
df = df.filter(image_detect_subplot(col("img"))["is_subplot"])图像向量与相似度
基于 CLIP 的嵌入向量生成与图文相似度计算算子。
image_embedding
从图像生成 CLIP 嵌入向量。
依赖: pip install open_clip_torch torch
image_embedding(*columns, model="ViT-B/32", pretrained="openai",
model_sharing=None, concurrency=None, batch_size=None,
num_gpus=None, gpu_type=None)参数 | 类型 | 默认值 | 说明 |
|
|
| CLIP 模型架构。 |
|
|
| 可选指定预训练权重 |
输入类型:DataType.image
返回类型:DataType.list(DataType.float32())(维度取决于模型,ViT-B/32 为 512 维)
df = df.with_column("vector", image_embedding(col("img")))image_text_similarity
计算图像与文本之间的 CLIP 余弦相似度。支持两种模式:
固定文本模式(
text="..."):所有图像与同一文本比较(单列 UDF)。逐行文本模式(
text=None):每行图像与对应文本列配对(双列 UDF)。
依赖: pip install open_clip_torch torch
image_text_similarity(*columns, text=None, model="ViT-B/32", pretrained="openai",
model_sharing=None, concurrency=None, batch_size=None,
num_gpus=None, gpu_type=None)参数 | 类型 | 默认值 | 说明 |
|
|
| 固定文本提示。 |
|
|
| CLIP 模型架构。 |
|
|
| 指定预训练权重。 |
输入类型:DataType.image
返回类型:DataType.float64(余弦相似度分数)
# 固定文本模式
sim = image_text_similarity(text="一张猫的照片")
df = df.with_column("score", sim(col("img")))
# 逐行文本模式
sim = image_text_similarity()
df = df.with_column("score", sim(col("img"), col("caption")))人脸处理
人脸检测、计数和模糊处理算子。
image_face_detect
检测图像中的人脸边界框。
依赖: pip install opencv-python
image_face_detect(*columns, cv_classifier="haarcascade_frontalface_alt.xml",
confidence=0.5, scale_factor=1.1, min_size=None,
max_size=None, concurrency=None)参数 | 类型 | 默认值 | 说明 |
|
|
| OpenCV 级联分类器 XML 文件。 |
|
|
| 最小检测置信度,范围 |
|
|
| 多尺度检测的图像金字塔缩放因子。 |
|
|
| 最小人脸尺寸 |
|
|
| 最大人脸尺寸 |
输入类型:DataType.image
返回类型:
DataType.list(
DataType.struct(
{
"x": DataType.int32(),
"y": DataType.int32(),
"w": DataType.int32(),
"h": DataType.int32(),
"confidence": DataType.float64(),
}
)
)字段说明:
字段 | 类型 | 说明 |
|
| 人脸边界框左上角 x 坐标。 |
|
| 人脸边界框左上角 y 坐标。 |
|
| 人脸边界框宽度。 |
|
| 人脸边界框高度。 |
|
| 检测置信度。当前检测方式不提供概率时,该字段为空值。 |
df = df.with_column("faces", image_face_detect(confidence=0.6)(col("img")))image_face_count
统计图像中的人脸数量。
image_face_count(*columns, cv_classifier="haarcascade_frontalface_alt.xml",
confidence=0.5, scale_factor=1.1, min_size=None,
max_size=None, concurrency=None)参数:与 image_face_detect 相同。
输入类型:DataType.image
返回类型:DataType.int64(表示检测到的人脸数量)
df = df.with_column("n_faces", image_face_count()(col("img")))
df = df.filter(image_face_count(col("img")) > 0)image_face_blur
检测人脸并对其进行模糊处理。
依赖: pip install opencv-python
image_face_blur(*columns, cv_classifier="haarcascade_frontalface_alt.xml",
blur_type="gaussian", radius=2,
scale_factor=1.1, min_size=None, max_size=None,
concurrency=None)参数 | 类型 | 默认值 | 说明 |
|
|
| 模糊算法: |
|
|
| 模糊核半径。 |
其余参数与 image_face_detect 相同。
输入类型:DataType.image(原始图像)
返回类型:(检测到的人脸区域被模糊处理后的原始图像)DataType.image
df = df.with_column("safe", image_face_blur(col("img"), radius=15))图像属性与过滤
图像元数据提取与规则过滤算子。
is_valid_image
检查图像是否可以成功解码。
is_valid_image(*columns, mode=None, pixel_limit=None, concurrency=None)参数 | 类型 | 默认值 | 说明 |
|
|
| 验证是否可转换到的目标色彩模式(如 |
|
|
| 超过此总像素数的图像将被判定为无效。 |
输入类型:DataType.binary(原始图像字节)或 DataType.image
返回类型:DataType.bool
df = df.with_column("ok", is_valid_image()(col("img")))
df = df.filter(is_valid_image(col("img"), pixel_limit=4096*4096))image_metadata
提取图像的宽度、高度、通道数和编码格式等元数据。
image_metadata(*columns, concurrency=None)输入类型:DataType.image 或 DataType.binary
返回类型:
DataType.struct(
{
"width": DataType.int32(),
"height": DataType.int32(),
"channels": DataType.int32(),
"mode": DataType.string(),
"format": DataType.string(),
}
)字段说明:
字段 | 类型 | 说明 |
|
| 图像宽度,单位像素。 |
|
| 图像高度,单位像素。 |
|
| 图像通道数。 |
|
| 图像色彩模式,例如 |
|
| 编码格式,例如 |
df = df.with_column("meta", image_metadata(col("img")))image_aspect_ratio
计算宽高比(width / height)。
image_aspect_ratio(*columns, concurrency=None)输入类型:DataType.image 或 DataType.binary
返回类型:DataType.float64
df = df.with_column("ratio", image_aspect_ratio(col("img")))image_sharpness
使用拉普拉斯方差计算图像清晰度。值越高表示图像越清晰,值越低表示图像越模糊。常用于数据清洗中过滤模糊图片。
与 image_quality_score 的区别:image_quality_score 返回归一化的 [0, 1] 综合评分(清晰度 50% + 对比度 30% + 色彩丰富度 20%),而 image_sharpness 返回原始拉普拉斯方差(无上界),数值大小取决于图像内容。
image_sharpness(*columns, max_edge=None, allow_upscale=False, concurrency=None)参数 | 类型 | 默认值 | 说明 |
|
|
| 计算前将最长边缩放到此值。大图缩小后再计算可大幅降低开销。 |
|
|
| 当 |
输入类型:DataType.image
返回类型:DataType.float64(拉普拉斯方差,无上界,值越高越清晰)
df = df.filter(image_sharpness(col("img"), max_edge=512) > 100)image_hash
计算图像的哈希值。
image_hash(*columns, method="phash", concurrency=None)参数 | 类型 | 默认值 | 说明 |
|
|
| 哈希算法: |
输入类型:DataType.image
返回类型:DataType.string(十六进制编码的哈希值)
df = df.with_column("hash", image_hash(col("image"), method="phash"))image_size_filter
按像素尺寸过滤图像。
image_size_filter(*columns, min_w=None, min_h=None, max_w=None, max_h=None, concurrency=None)参数 | 类型 | 默认值 | 说明 |
|
|
| 最小宽度(像素) |
|
|
| 最小高度(像素) |
|
|
| 最大宽度(像素) |
|
|
| 最大高度(像素) |
输入类型:DataType.image 或 DataType.binary
返回类型:DataType.boolean(图像满足所有约束时返回 True)
df = df.filter(image_size_filter(col("img"), min_w=256, min_h=256))image_shape_filter
按宽高比(width / height)过滤图像。
image_shape_filter(*columns, min_ratio=None, max_ratio=None, concurrency=None)参数 | 类型 | 默认值 | 说明 |
|
|
| 最小宽高比 |
|
|
| 最大宽高比 |
输入类型:DataType.image 或 DataType.binary
返回类型:DataType.boolean
df = df.filter(image_shape_filter(col("img"), min_ratio=0.5, max_ratio=2.0))image_file_size_filter
按编码文件大小(字节)过滤图像。
image_file_size_filter(*columns, min_bytes=None, max_bytes=None, concurrency=None)参数 | 类型 | 默认值 | 说明 |
|
|
| 最小编码大小 |
|
|
| 最大编码大小 |
输入类型:DataType.binary
返回类型:DataType.boolean
df = df.filter(image_file_size_filter(col("img"), max_bytes=5*1024*1024))图像质量评分
图像质量、安全性和水印评估算子。
image_quality_score
计算综合质量评分,融合清晰度、对比度和色彩丰富度。
算法:拉普拉斯方差(清晰度,权重 50%)+ 灰度标准差(对比度,权重 30%)+ 通道标准差(色彩丰富度,权重 20%)的加权组合。
image_quality_score(*columns, concurrency=None)输入类型:DataType.image
返回类型:DataType.float64(分数范围 [0, 1],值越高质量越好)
df = df.with_column("quality", image_quality_score(col("img")))
df = df.filter(image_quality_score(col("img")) > 0.3)image_nsfw_score
使用图像分类模型评估 NSFW 风险。
依赖: pip install transformers torch
image_nsfw_score(*columns, hf_nsfw_model="Falconsai/nsfw_image_detection",
model_sharing=None, concurrency=None, batch_size=None,
num_gpus=None, gpu_type=None)参数 | 类型 | 默认值 | 说明 |
|
|
| HuggingFace NSFW 分类模型 ID。 |
输入类型:DataType.image
返回类型:DataType.float64(概率范围 [0, 1],值越高 NSFW 可能性越大)
df = df.with_column("nsfw", image_nsfw_score(col("img")))
df = df.filter(image_nsfw_score(col("img")) < 0.5)image_aesthetic_score
使用美学评分模型评估图像美学质量。
依赖: pip install transformers torch
image_aesthetic_score(*columns,
hf_scorer_model="shunk031/aesthetics-predictor-v2-sac-logos-ava1-l14-linearMSE",
model_sharing=None, concurrency=None, batch_size=None,
num_gpus=None, gpu_type=None)参数 | 类型 | 默认值 | 说明 |
|
|
| HuggingFace 美学评分模型 ID。 |
输入类型:DataType.image
返回类型:DataType.float64
df = df.with_column("aesthetic", image_aesthetic_score(col("img")))image_watermark_score
使用图像分类模型评估水印风险。
依赖: pip install transformers torch
image_watermark_score(*columns, hf_watermark_model="amrul-hzz/watermark_detector",
model_sharing=None, concurrency=None, batch_size=None,
num_gpus=None, gpu_type=None)参数 | 类型 | 默认值 | 说明 |
|
|
| HuggingFace 水印检测模型 ID。 |
输入类型:DataType.image
返回类型:DataType.float64(概率范围 [0, 1],值越高越可能含水印)
df = df.with_column("wm", image_watermark_score()(col("img")))
df = df.filter(image_watermark_score(col("img")) < 0.8)视频元数据、切分与抽帧
视频算子以视频 URI 或视频片段引用作为输入。video_split 只生成片段引用,不复制视频文件;只有在调用 video_explode_frames 或 video_extract_frames 时才会读取视频帧。抽帧结果使用 Flink 内置 IMAGE 类型。
video_metadata
读取视频基本信息,例如分辨率、帧率、时长和编码格式。
video_metadata(*columns, on_error="raise", container_options=None)参数 | 类型 | 默认值 | 说明 |
|
|
| 错误处理策略,支持 |
|
|
| 打开视频文件时使用的额外参数。通常无需设置。 |
输入类型:DataType.string(视频 URI)
返回类型:
DataType.struct(
{
"width": DataType.int32(),
"height": DataType.int32(),
"fps": DataType.float64(),
"duration_ms": DataType.int64(),
"frame_count": DataType.int64(),
"time_base": DataType.float64(),
"codec_name": DataType.string(),
"video_stream_index": DataType.int32()
}
)字段含义见:视频元数据
df = df.with_column("video_meta", video_metadata(col("uri"), on_error="null"))video_split
将完整视频或已有视频片段切分为多个片段引用,展开为一行一个片段引用(UDTF)。该算子本身不实际读取视频帧,只计算时间窗口。
video_split(*columns, segment_duration_ms=None, num_segments=None,
video_duration_ms=None, max_segments=1024, on_error="raise",
container_options=None, read_chunk_size=None,
max_cached_blocks=None, read_ahead_blocks=None,
concurrency=None)参数 | 类型 | 默认值 | 说明 |
|
|
| 固定片段长度,单位毫秒。与 |
|
|
| 切分成近似等长的片段数量。与 |
|
|
| 显式视频时长,单位毫秒。 |
|
|
| 单行最多输出片段数。 |
|
|
| 错误处理策略,支持 |
|
|
| 用于 pyav conatiner 附加参数传递 |
|
|
| 单次读取视频文件 chunk 大小,单位 bytes(调优参数用户无需调整)。 |
|
|
| 文件块缓存块数量,优化 Remote FS 读开销(调优参数用户无需调整) |
|
|
| 文件块预读块数量,优化 Remote FS 读开销(调优参数用户无需调整) |
segment_duration_ms 和 num_segments 二选一,表示两种不同的切分方式:按时间区间切分、按数量切分。
输入类型:DataType.string(视频 URI)/ 视频片段引用
返回类型:视频片段引用
DataType.struct(
{
"uri": DataType.string(),
"start_time_ms": DataType.int64(),
"end_time_ms": DataType.int64()
}
)字段含义见:视频片段引用
算子会自动探测视频时长。如果已经通过 video_metadata 获取到了元数据,为了避免额外探测,可以把 video_metadata 的结果作为第二列传入。
segments = df.join_lateral(
video_split(segment_duration_ms=1000)(
col("uri"),
col("video_meta"), # 可选列
).alias("segment")
)video_explode_frames
从完整视频或视频片段中抽帧,并将结果展开为一帧一行(UDTF)。
video_explode_frames(*columns, frame_selector="all_frames",
sample_interval_ms=None, max_frames=None,
image_height=None, image_width=None, on_error="raise",
container_options=None, read_chunk_size=None,
max_cached_blocks=None, read_ahead_blocks=None,
concurrency=None)参数 | 类型 | 默认值 | 说明 |
|
|
| 抽帧策略,支持 |
|
|
| 当 |
|
|
| 每个输入最多输出多少帧。 |
|
|
| 输出帧高度,单位像素;必须和 |
|
|
| 输出帧宽度,单位像素;必须和 |
|
|
| 错误处理策略,支持 |
|
|
| 用于 pyav conatiner 附加参数传递 |
|
|
| 单次读取视频文件 chunk 大小,单位 bytes(调优参数用户无需调整)。 |
|
|
| 文件块缓存块数量,优化 Remote FS 读开销(调优参数用户无需调整) |
|
|
| 文件块预读块数量,优化 Remote FS 读开销(调优参数用户无需调整) |
输入类型:DataType.string或视频片段引用
返回两列: 第一列DataType.image(解码后的 RGB 视频帧),第二列视频帧元数据如下
DataType.struct(
{
"uri": DataType.string(),
"video_stream_index": DataType.int32(),
"frame_index": DataType.int64(),
"pts": DataType.int64(),
"time_ms": DataType.int64(),
"key_frame": DataType.boolean(),
"start_time_ms": DataType.int64(),
"end_time_ms": DataType.int64()
}
)字段含义见:视频帧元数据
frames = segments.join_lateral(
video_explode_frames(
frame_selector="sample",
sample_interval_ms=1000,
max_frames=1,
image_width=512,
image_height=512,
)(col("segment")).alias("frame", "metadata")
)video_extract_frames
从完整视频或视频片段中抽帧,并把同一个输入视频的结果收集到同一行的数组中。
video_extract_frames(*columns, frame_selector="all_frames",
sample_interval_ms=None, max_frames=None,
image_height=None, image_width=None, on_error="raise",
container_options=None, read_chunk_size=None,
max_cached_blocks=None, read_ahead_blocks=None,
concurrency=None)参数含义与 video_explode_frames 相同。
输入类型:DataType.string / 视频片段引用
返回类型:DataType.array(DataType.image())
适合下游逻辑需要一次性拿到同一视频的多个帧。若视频较长或抽帧数量较多,推荐使用 video_explode_frames,避免单行持有过多图像。
df = df.with_column(
"frames",
video_extract_frames(
col("uri"),
frame_selector="sample",
sample_interval_ms=1000,
max_frames=8,
image_width=512,
image_height=512,
)
)完整 Pipeline 示例
以下示例演示一个典型的图像数据清洗流水线,组合多个算子完成过滤、解码、评分和重新编码:
from pyflink.dataframe import col
from pyflink.multimodal.operators import (
is_valid_image, image_file_size_filter,
image_quality_score, image_nsfw_score,
image_watermark_score,
image_decode, image_resize, image_encode,
)
# 1. 过滤:仅保留有效图像,丢弃小于 1KB 或大于 10MB 的文件
df = df.filter(is_valid_image(col("raw_bytes")))
df = df.filter(image_file_size_filter(col("raw_bytes"), min_bytes=1024, max_bytes=10*1024*1024))
# 2. 解码 + 缩放(先解码一次,避免下游算子重复解码)
df = df.with_column("img", image_decode(col("raw_bytes")))
df = df.with_column("img", image_resize(col("img"), width=512, height=512))
# 3. 评分:质量、NSFW、水印
df = df.with_column("quality", image_quality_score(col("img")))
df = df.with_column("nsfw", image_nsfw_score(col("img")))
df = df.with_column("watermark", image_watermark_score(col("img"), num_gpus=0.5))
# 4. 按评分过滤
df = df.filter(col("quality") > 0.3)
df = df.filter(col("nsfw") < 0.5)
df = df.filter(col("watermark") < 0.8)
# 5. 重新编码为字节用于存储
df = df.with_column("img", image_encode(col("img"), format="JPEG"))视频切分与抽帧 Pipeline
以下示例演示从完整视频到逐帧图像处理的典型流水线:先获取元数据,再切分视频,最后对每个片段逐帧抽取:
from pyflink.dataframe import col
from pyflink.multimodal.operators import (
video_metadata, video_split, video_explode_frames,
)
# 1. 获取视频元数据
df = df.with_column("video_meta", video_metadata(col("uri"), on_error="null"))
# 2. 将视频切分为 1 秒片段(传入元数据避免重复探测时长)
segments = df.join_lateral(
video_split(segment_duration_ms=1000)(
col("uri"),
col("video_meta"),
).alias("segment")
)
segments.repartition()
# 3. 对每个片段采样抽帧
frames = segments.join_lateral(
video_explode_frames(
col("segment"),
frame_selector="sample",
sample_interval_ms=1000,
max_frames=1,
).alias("frame", "metadata")
)依赖说明
多模态算子依赖以下 Python 包。平台已预装对应版本,无需手动安装。如需在本地开发环境调试,可参照下表安装。
包名 | 版本范围 | 说明 |
pillow | >=11.3,<12.3 | 图像处理 |
numpy | >=1.24,<1.25 | 数组计算 |
opencv-python-headless | >=4.10,<4.11 | 图像处理 |
imagehash | >=4.3,<4.4 | 感知哈希 |
av | >=14.2,<15.0 | 视频解码(FFmpeg 绑定) |
torch | >=2.5,<2.6 | 深度学习推理 |
torchvision | >=0.20,<0.21 | 视觉模型工具 |
transformers | >=4.53,<4.58 | HuggingFace 模型加载 |
safetensors | >=0.7,<0.9 | 安全权重格式 |
open_clip_torch | >=2.32,<2.33 | CLIP 向量提取 |
ultralytics | >=8.3,<8.5 | YOLO 目标检测 |
easyocr | >=1.7,<1.8 | OCR 文字识别 |
rembg | >=2.0,<2.1 | 背景移除 |
onnxruntime | >=1.16,<1.17 | ONNX 推理引擎 |