Multimodal Operators

Updated at:

The Python DataFrame API provides a set of built-in multimodal operators for processing images, videos, and other multimodal data in Flink jobs. These operators cover image transformation, detection, quality assessment, embedding, face processing, and video frame extraction.

Limits

Available only in Realtime Compute Engine VVR 11.8 and later.

Usage

Invocation Methods

Each operator supports two invocation styles:

Factory Function Call

Configure operator parameters first, then apply the operator to one or more columns. Suitable for reusing the same configuration across multiple columns or steps.

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")))

Direct Call

Pass input columns directly to the operator and set parameters in the same step.

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),
)

Expanding Multi-Row Results

video_split and video_explode_frames expand a single input row into multiple output rows. Use join_lateral to invoke them.

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")
)

Common Parameters

All operators support concurrency to control parallel processing. Some model-based image operators also support batch size and GPU resource parameters.

Parameter

Type

Description

concurrency

Optional[int]

Number of concurrent processing threads. None uses the system default.

batch_size

Optional[int]

Number of items per processing batch. Only supported by some model-based image operators.

num_gpus

Optional[float]

GPU share requested per concurrent task, e.g., 0.5.None means using CPU.

gpu_type

Optional[str]

Specifies the GPU model, e.g., "A10".None accepts any available GPU.

model_sharing

Optional[str]

Model loading and reuse mode. Usually does not need to be set; uses the default mode when unset.

model_sharing supports the following values:

Value

Description

None

Not specified at the operator level; uses the job default configuration. If not configured at the job level either, equivalent to process.

process

Default mode. Each Python process loads the model independently; operators using the same model within a process share weights.

shared

Multiple Python processes within the same TaskManager share a single model copy when possible, reducing memory usage for large models, but introducing inter-process communication overhead.

Data Type Description

Image Input/Output

Scenario

DataFrame Type

Description

Raw image

DataType.binary

JPEG, PNG, WEBP, and other encoded image bytes, typically from the result of the FETCH_CONTENT function.

Decoded image

DataType.image

Flink built-in image type representing a decoded image, used for image transformation, detection, scoring, and video frame extraction results.

Image tensor

DataType.tensor

image_to_tensor output, typically used as model input.

Image array

DataType.arraylist(DataType.image)

Corresponds to multiple images, e.g., frame extraction results from video_extract_frames .

Video Segment Reference

Definition:

DataType.struct(
   {
     "uri": DataType.string(), 
     "start_time_ms": DataType.int64(), 
     "end_time_ms": DataType.int64()
   }
)

Field

Type

Description

uri

DataType.string

Video file path or object storage URI.

start_time_ms

DataType.int64

Segment start time in milliseconds.

end_time_ms

DataType.int64

Segment end time in milliseconds.

This struct only describes the video segment position without copying video content. video_split returns this struct, and it can be used as input to video_explode_frames or video_extract_frames .

Video Metadata

Definition:

DataType.struct(
  {
    "width": DataType.int32(),
    "height": DataType.int32(),
    "fps": DataType.float64(),
    "duration_ms": DataType.int64(),
    "frame_count": DataType.int64(),

    "codec_name": DataType.string(),
    "video_stream_index": DataType.int32()
  }
)

Field

Type

Description

width

DataType.int32

Video width in pixels.

height

DataType.int32

Video height in pixels.

fps

DataType.float64

Video frame rate.

duration_ms

DataType.int64

Video duration in milliseconds.

frame_count

DataType.int64

Total number of video frames.

time_base

DataType.float64

Video stream time base, used for calculating frame timestamps.

codec_name

DataType.string

Video encoding format name, e.g., h264, hevc.

video_stream_index

DataType.int32

Selected video stream index.

video_metadata returns this struct. It is commonly used to filter videos by resolution, duration, or encoding format, and can also be passed to video_split to avoid repeated duration probing.

Video Frame Metadata

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()
  }
)

Field

Type

Description

uri

DataType.string

Video file path or object storage URI.

video_stream_index

DataType.int32

Video stream index of the output frame.

frame_index

DataType.int64

Index of the output frame in the current extraction result.

pts

DataType.int64

Original frame timestamp in the video file, typically used for alignment with video processing tools.

time_ms

DataType.int64

Video time corresponding to the frame in milliseconds.

key_frame

DataType.boolean

Whether this is a keyframe.

start_time_ms

DataType.int64

Start time of the current frame extraction input segment in milliseconds.

end_time_ms

DataType.int64

End time of the current frame extraction input segment in milliseconds.

video_explode_frames returns DataType.image and this metadata struct. Retaining this struct enables tracking which video, segment, and timestamp each frame originates from.

Operator Overview

Image Transformation and Generation

Operator

Description

image_decode

Decode image bytes to IMAGE

image_encode

Encode an image to compressed bytes

image_compress

Compress an image to a target size

image_convert_format

Convert image encoding format

image_convert_mode

Convert image color mode

image_to_tensor

Convert an image to a float32 tensor

image_resize

Resize an image to specified dimensions

image_rescale

Rescale an image proportionally

image_crop

Crop an image region

image_crop_black_border

Crop black borders from an image

image_flip

Flip horizontally or vertically

image_blur

Blur processing

image_adjust_color

Adjust brightness, contrast, and saturation

image_remove_background

Remove image background

Image Detection and Recognition

Operator

Description

image_detect_objects

YOLO object detection

image_segment

FastSAM semantic segmentation

image_ocr

EasyOCR text extraction

image_detect_subplot

Sub-image/collage detection

Image Embedding and Similarity

Operator

Description

image_embedding

Generate CLIP image embeddings

image_text_similarity

Compute image-text cosine similarity

Face Processing

Operator

Description

image_face_detect

Detect face positions

image_face_count

Count faces

image_face_blur

Face blurring

Image Attributes and Filtering

Operator

Description

is_valid_image

Check whether an image can be decoded

image_metadata

Extract width, height, channels, and format

image_aspect_ratio

Compute aspect ratio

image_sharpness

Compute sharpness (Laplacian variance)

image_hash

Generate perceptual hash

image_size_filter

Filter by pixel dimensions

image_shape_filter

Filter by aspect ratio

image_file_size_filter

Filter by file size

Image Quality Scoring

Operator

Description

image_quality_score

Composite quality scoring

image_nsfw_score

NSFW risk scoring

image_aesthetic_score

Aesthetic scoring

image_watermark_score

Watermark detection scoring

Video Metadata, Splitting, and Frame Extraction

Operator

Description

video_metadata

Read basic video information

video_split

Split video into multiple segment references

video_explode_frames

Extract frames and expand to one frame per row

video_extract_frames

Extract frames and return frame array

Image Transformation and Generation

Operators for encoding/decoding, format conversion, color mode conversion, resizing, and image enhancement.

image_decode

Decode raw image bytes to DataType.image (decoded image).

image_decode(*columns, on_error="raise", mode=None, pixel_limit=None, concurrency=None)

Parameter

Type

Default

Description

on_error

str

"raise"

Error handling strategy: "raise" throws an exception, or "null" returns null.

mode

Optional[str]

None

The target color mode, for example, "RGB" or "L". None retains the original mode.

pixel_limit

Optional[int]

None

Images exceeding this pixel count will be rejected.

Input type: DataType.binary

Return type: DataType.image

df = df.with_column("img", image_decode(col("raw_bytes")))

image_encode

Encode an image to compressed bytes.

image_encode(*columns, format=None, quality=85, output="bytes", concurrency=None)

Parameter

Type

Default

Description

format

Optional[str]

None

Target format ("JPEG", "PNG" , etc.).None means auto-inferred from the source mode.

quality

int

85

Compression quality (1-100, effective only for JPEG/WebP).

output

str

"bytes"

Output representation: "bytes" or "data_url" (for downstream AI function consumption).

Input type: DataType.image

Return type: DataType.binary or DataType.string

df = df.with_column("jpeg", image_encode(col("image"), format="JPEG", quality=90))

image_compress

Compress an encoded image to encoded bytes.

image_compress(*columns, quality=85, format="JPEG", concurrency=None)

Parameter

Type

Default

Description

quality

int

85

Compression quality (1-100).

format

str

"JPEG"

Output format.

Input type: DataType.binary

Return type: DataType.binary

df = df.with_column("compressed", image_compress(col("img"), quality=60))

image_convert_format

Convert the encoded image format.

image_convert_format(*columns, format, concurrency=None)

Parameter

Type

Default

Description

format

str

(Required)

Target format:"JPEG", "PNG", "WEBP" , etc.

Input type: DataType.binary

Return type: DataType.binary

df = df.with_column("png", image_convert_format(col("img"), format="PNG"))

image_convert_mode

Convert an image to the target color mode.

image_convert_mode(*columns, mode, concurrency=None)

Parameter

Type

Default

Description

mode

str

(Required)

Target color mode.

Supported modes:

Mode

Channels

Data Type

Description

"L"

1

uint8

Grayscale

"LA"

2

uint8

Grayscale + alpha

"RGB"

3

uint8

Color

"RGBA"

4

uint8

Color + alpha

"L16"

1

uint16

Grayscale (16-bit)

Input type: DataType.image

Return type: DataType.image

df = df.with_column("gray", image_convert_mode(col("img"), mode="L"))

image_to_tensor

Convert an image to a fixed-shape float32 tensor (resizing + normalization to [0, 1]).

image_to_tensor(*columns, width, height, mode="RGB", layout="CHW", concurrency=None)

Parameter

Type

Default

Description

width

int

(Required)

Target width.

height

int

(Required)

Target height.

mode

str

"RGB"

Target color mode.

layout

str

"CHW"

Tensor axis order:"CHW" or "HWC".

Input type: DataType.image

Return type: DataType.tensor

df = df.with_column("tensor", image_to_tensor(col("img"), width=224, height=224))

image_resize

Resize an image to specified dimensions.

image_resize(*columns, width, height, method="lanczos", concurrency=None)

Parameter

Type

Default

Description

width

int

(Required)

Target width (pixels).

height

int

(Required)

Target height (pixels).

method

str

"lanczos"

Resampling method:"lanczos", "bilinear", "nearest", "bicubic".

Input type: DataType.image

Return type: DataType.image

df = df.with_column("thumb", image_resize(col("img"), width=256, height=256))

image_rescale

Rescale an image proportionally.

image_rescale(*columns, scale, method="lanczos", concurrency=None)

Parameter

Type

Default

Description

scale

float

(Required)

Scale factor (e.g., 0.5 halves the size, 2.0 doubles it).

method

str

"lanczos"

Resampling method:"lanczos", "bilinear", "nearest", "bicubic".

Input type: DataType.image

Return type: DataType.image

df = df.with_column("half", image_rescale(col("img"), scale=0.5))

image_crop

Crop an image region.

image_crop(*columns, crop_coords=None, crop_type="center", crop_ratio=(0.8, 0.8),
           crop_size=None, concurrency=None)

Parameter

Type

Default

Description

crop_coords

Optional[tuple]

None

Absolute pixel coordinates for cropping (left, top, right, bottom).

crop_type

str

"center"

Crop mode: "coordinate", "ratio", "center".

crop_ratio

tuple

(0.8, 0.8)

Width/height ratio to retain during center ratio cropping. Used with the center crop_type .

crop_size

Optional[tuple]

None

Output dimensions (width, height). Overrides crop_ratio.

Input type: DataType.image

Return type: 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

Detect and crop black borders from an image.

image_crop_black_border(*columns, threshold=None, detect_algorithm="auto",
                        black_threshold=None, edge_sensitivity=1.0,
                        min_border_size=1, concurrency=None)

Parameter

Type

Default

Description

threshold

Optional[int]

None

Legacy threshold parameter for controlling the black border detection threshold. We recommend using detect_algorithm. Pixel values below this threshold are treated as black.

detect_algorithm

str

"auto"

Detection algorithm:auto, threshold, histogram, edge.

black_threshold

Optional[int]

None

Compatibility parameter, equivalent to threshold. The two parameters cannot be specified at the same time.

edge_sensitivity

float

1.0

Edge detection sensitivity.

min_border_size

int

1

Minimum black border width (pixels) to trigger cropping.

Input type: DataType.image

Return type: DataType.image

df = df.with_column("clean", image_crop_black_border(col("img")))

image_flip

Flip an image horizontally or vertically.

image_flip(*columns, mode="horizontal", concurrency=None)

Parameter

Type

Default

Description

mode

str

"horizontal"

Flip direction: "horizontal" or "vertical" or "rotate180".

Input type: DataType.image

Return type: DataType.image

df = df.with_column("flipped", image_flip(col("img"), mode="vertical"))

image_blur

Apply blur processing to an image.

image_blur(*columns, radius=2, blur_type="gaussian", concurrency=None)

Parameter

Type

Default

Description

radius

int

2

Blur kernel radius.

blur_type

str

"gaussian"

Blur algorithm:"gaussian", "box" or "mean".

Input type: DataType.image

Return type: DataType.image

df = df.with_column("blurred", image_blur(col("img"), radius=5))

image_adjust_color

Adjust brightness, contrast, and saturation.

image_adjust_color(*columns, brightness=1.0, contrast=1.0,saturation=1.0, concurrency=None)

Parameter

Type

Default

Description

brightness

float

1.0

Brightness factor.1.0 = no change.

contrast

float

1.0

Contrast factor.1.0 = no change.

saturation

float

1.0

Saturation factor.1.0 = no change.

Input type: DataType.image

Return type: DataType.image

df = df.with_column("bright", image_adjust_color(col("img"), brightness=1.5))

image_remove_background

Remove image background

Dependency: 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)

Parameter

Type

Default

Description

alpha_matting

bool

False

Enable alpha matting for smoother edges.

alpha_matting_foreground_threshold

int

240

Alpha matting foreground threshold.

alpha_matting_background_threshold

int

10

Alpha matting background threshold.

alpha_matting_erode_size

int

10

Alpha matting erosion kernel size.

bgcolor

Optional[tuple]

None

The background color, in the format of (R, G, B) .None produces a transparent background.

Input type: DataType.image

Return type: DataType.image

df = df.with_column("fg", image_remove_background(col("image")))

Image Detection and Recognition

Operators for object detection, text recognition, semantic segmentation, and sub-image detection.

image_detect_objects

Detect objects using YOLO.

Dependency: 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)

Parameter

Type

Default

Description

model

str

"yolov8n"

YOLO model name or path.

confidence

float

0.05

Minimum detection confidence, range [0, 1].

imgsz

int

640

Model inference resolution. Larger values improve small object detection but increase latency and GPU memory consumption.

iou

float

0.5

NMS IoU threshold, range [0, 1].

Input type: DataType.image

Return type:

DataType.list(
    DataType.struct(
    {
        "label": DataType.string(),
        "x": DataType.float64(),
        "y": DataType.float64(),
        "w": DataType.float64(),
        "h": DataType.float64(),
        "confidence": DataType.float64(),
    }
)

Field description:

Field

Type

Description

label

DataType.string

Detected object category.

x

DataType.float64

Bounding box top-left x coordinate.

y

DataType.float64

Bounding box top-left y coordinate.

w

DataType.float64

Bounding box width.

h

DataType.float64

Bounding box height.

confidence

DataType.float64

Detection confidence.

objs = image_detect_objects(confidence=0.25)
df = df.with_column("objects", objs(col("img")))

image_segment

Generate semantic segmentation masks using FastSAM.

Dependency: 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)

Parameter

Type

Default

Description

model

str

"FastSAM-x.pt"

FastSAM model name or path.

imgsz

int

1024

Model inference resolution. Larger values improve mask precision but increase latency and GPU memory consumption.

confidence

float

0.05

Minimum confidence, range [0, 1].

iou

float

0.5

NMS IoU threshold, range [0, 1].

Input type: DataType.image

Return type: DataType.binary (PNG-encoded segmentation mask where each unique pixel value represents a segment ID)

df = df.with_column("mask", image_segment(col("img")))

image_ocr

Extract text from images using EasyOCR.

Dependency: pip install easyocr

image_ocr(*columns, lang=None, model_sharing=None, concurrency=None,
          batch_size=None, num_gpus=None, gpu_type=None)

Parameter

Type

Default

Description

lang

Optional[list[str]]

["en"]

Language code list, e.g., ["en"], ["en", "ch_sim"].

lang supports the following language codes:

Language Group

Code

Latin

af, az, bs, cs, cy, da, de, en, es, et, fr, ga, hr, hu, id, is, it, ku, la, lt, lv, mi, ms, mt, nl, no, oc, pi, pl, pt, ro, rs_latin, sk, sl, sq, sv, sw, tl, tr, uz, vi

Arabic

ar, fa, ug, ur

Cyrillic

ru, rs_cyrillic, be, bg, uk, mn, abq, ady, kbd, ava, dar, inh, che, lbe, lez, tab, tjk

Devanagari

hi, mr, ne, bh, mai, ang, bho, mah, sck, new, gom, sa, bgc

Bengali

bn, as, mni

Other

th, ch_sim, ch_tra, ja, ko, ta, te, kn

Multilingual recognition requires compatible languages from the same group. en can be used with most languages. Do not mix multiple non-English language groups in the same lang, e.g., do not set both Chinese and Japanese simultaneously.

Input type: DataType.image

Return type:

DataType.list(
  DataType.struct(
    {
      "text": DataType.string(),
      "confidence": DataType.float64(),
      "bbox": DataType.list(DataType.list(DataType.float64())),
    }
  )
)

Field description:

Field

Type

Description

text

DataType.string

Recognized text content.

confidence

DataType.float64

OCR confidence.

bbox

DataType.list(DataType.list(DataType.float64()))

The four corner coordinates of the text region, in the format of [[x1,y1], [x2,y2], [x3,y3], [x4,y4]].

Each element represents a detected text region.

ocr = image_ocr(lang=["en", "ch_sim"])
df = df.with_column("text", ocr(col("img")))

image_detect_subplot

Determine whether an image is a collage, grid, or subplot, and return the estimated number of sub-images.

Dependency: pip install opencv-python

image_detect_subplot(*columns, threshold=0.5, concurrency=None)

Parameter

Type

Default

Description

threshold

float

0.5

Edge detection sensitivity, range [0, 1]. Higher values are more strict.

Images with any side smaller than 20 pixels always return (False, 1).

Input type: DataType.image

Return type:

DataType.struct(
  {
    "is_subplot": DataType.boolean(),
    "count": DataType.int32(),
  }
)

Field description:

Field

Type

Description

is_subplot

DataType.boolean

Whether a collage or sub-image structure was detected.

count

DataType.int32

Estimated number of sub-images. Returns 1 for non-collage images.

df = df.with_column("subplot", image_detect_subplot(col("img")))
df = df.filter(image_detect_subplot(col("img"))["is_subplot"])

Image Embedding and Similarity

Operators for CLIP-based embedding generation and image-text similarity computation.

image_embedding

Generate CLIP embeddings from images.

Dependency: 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)

Parameter

Type

Default

Description

model

str

"ViT-B/32"

CLIP model architecture.

pretrained

str

"openai"

Optionally specify pretrained weights

Input type: DataType.image

Return type: DataType.list(DataType.float32()) (dimensions depend on the model;ViT-B/32 produces 512 dimensions)

df = df.with_column("vector", image_embedding(col("img")))

image_text_similarity

Compute CLIP cosine similarity between images and text. Supports two modes:

  • Fixed text mode (text="..."): All images are compared against the same text (single-column UDF).

  • Per-row text mode (text=None): Each image is paired with the corresponding text column (two-column UDF).

Dependency: 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)

Parameter

Type

Default

Description

text

Optional[str]

None

Fixed text prompt.None enables per-row mode.

model

str

"ViT-B/32"

CLIP model architecture.

pretrained

str

"openai"

Specify pretrained weights.

Input type: DataType.image

Return type: DataType.float64 (cosine similarity score)

# Fixed text mode
sim = image_text_similarity(text="a photo of a cat")
df = df.with_column("score", sim(col("img")))

# Per-row text mode
sim = image_text_similarity()
df = df.with_column("score", sim(col("img"), col("caption")))

Face Processing

Operators for face detection, counting, and blurring.

image_face_detect

Detect face bounding boxes in an image.

Dependency: 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)

Parameter

Type

Default

Description

cv_classifier

str

"haarcascade_frontalface_alt.xml"

OpenCV cascade classifier XML file.

confidence

float

0.5

Minimum detection confidence, range [0, 1].

scale_factor

float

1.1

Image pyramid scale factor for multi-scale detection.

min_size

Optional[tuple]

None

Minimum face size (w, h) in pixels.

max_size

Optional[tuple]

None

Maximum face size (w, h) in pixels.

Input type: DataType.image

Return type:

DataType.list(
  DataType.struct(
    {
      "x": DataType.int32(),
      "y": DataType.int32(),
      "w": DataType.int32(),
      "h": DataType.int32(),
      "confidence": DataType.float64(),
    }
  )
)

Field description:

Field

Type

Description

x

DataType.int32

Face bounding box top-left x coordinate.

y

DataType.int32

Face bounding box top-left y coordinate.

w

DataType.int32

Face bounding box width.

h

DataType.int32

Face bounding box height.

confidence

DataType.float64

Detection confidence. This field is null when the current detection method does not provide probability.

df = df.with_column("faces", image_face_detect(confidence=0.6)(col("img")))

image_face_count

Count the number of faces in an image.

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)

Parameters: Same as image_face_detect.

Input type: DataType.image

Return type: DataType.int64 (number of detected faces)

df = df.with_column("n_faces", image_face_count()(col("img")))
df = df.filter(image_face_count(col("img")) > 0)

image_face_blur

Detect faces and apply blur processing to them.

Dependency: 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)

Parameter

Type

Default

Description

blur_type

str

"gaussian"

Blur algorithm:"gaussian" or "box".

radius

int

2

Blur kernel radius.

Remaining parameters are the same as image_face_detect .

Input type: DataType.image (raw image)

Return type: DataType.image (raw image with detected face regions blurred)

df = df.with_column("safe", image_face_blur(col("img"), radius=15))

Image Attributes and Filtering

Operators for image metadata extraction and rule-based filtering.

is_valid_image

Check whether an image can be successfully decoded.

is_valid_image(*columns, mode=None, pixel_limit=None, concurrency=None)

Parameter

Type

Default

Description

mode

Optional[str]

None

The target color mode to validate conversion to, for example, "RGB".

pixel_limit

Optional[int]

None

Images exceeding this total pixel count are considered invalid.

Input type: DataType.binary(raw image bytes) or DataType.image

Return type: 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

Extract image metadata such as width, height, channels, and encoding format.

image_metadata(*columns, concurrency=None)

Input type: DataType.image or DataType.binary

Return type:

DataType.struct(
  {
    "width": DataType.int32(),
    "height": DataType.int32(),
    "channels": DataType.int32(),
    "mode": DataType.string(),
    "format": DataType.string(),
  }
)

Field description:

Field

Type

Description

width

DataType.int32

Image width in pixels.

height

DataType.int32

Image height in pixels.

channels

DataType.int32

Number of image channels.

mode

DataType.string

Image color mode, e.g., RGB, RGBA, L, L16.

format

DataType.string

Encoding format, e.g., JPEG, PNG. For decoded DataType.image input, returns UNKNOWN.

df = df.with_column("meta", image_metadata(col("img")))

image_aspect_ratio

Compute aspect ratio (width / height).

image_aspect_ratio(*columns, concurrency=None)

Input type: DataType.image or DataType.binary

Return type: DataType.float64

df = df.with_column("ratio", image_aspect_ratio(col("img")))

image_sharpness

Compute image sharpness using Laplacian variance. Higher values indicate sharper images, lower values indicate blurrier images. Commonly used in data cleaning to filter blurry images.

Difference from image_quality_score: image_quality_score returns a normalized [0, 1] composite score (sharpness 50% + contrast 30% + color richness 20%), while image_sharpness returns the raw Laplacian variance (unbounded) whose magnitude depends on image content.

image_sharpness(*columns, max_edge=None, allow_upscale=False, concurrency=None)

Parameter

Type

Default

Description

max_edge

Optional[int]

None

Scales the longest edge to this value before computation. Resizing large images significantly reduces overhead. None computes at original resolution.

allow_upscale

bool

False

Whether to allow upscaling when max_edge exceeds the image dimensions. Defaults to False to prevent interpolation artifacts from enlarging small images.

Input type: DataType.image

Return type: DataType.float64 (Laplacian variance, unbounded, higher values indicate sharper images)

df = df.filter(image_sharpness(col("img"), max_edge=512) > 100)

image_hash

Compute the hash value of an image.

image_hash(*columns, method="phash", concurrency=None)

Parameter

Type

Default

Description

method

str

"phash"

Hash algorithm: "phash", "dhash", "ahash".

Input type: DataType.image

Return type: DataType.string (hex-encoded hash value)

df = df.with_column("hash", image_hash(col("image"), method="phash"))

image_size_filter

Filter images by pixel dimensions.

image_size_filter(*columns, min_w=None, min_h=None, max_w=None, max_h=None, concurrency=None)

Parameter

Type

Default

Description

min_w

Optional[int]

None

Minimum width (pixels)

min_h

Optional[int]

None

Minimum height (pixels)

max_w

Optional[int]

None

Maximum width (pixels)

max_h

Optional[int]

None

Maximum height (pixels)

Input type: DataType.image or DataType.binary

Return type: DataType.boolean (returns True when the image satisfies all constraints)

df = df.filter(image_size_filter(col("img"), min_w=256, min_h=256))

image_shape_filter

Filter images by aspect ratio (width / height).

image_shape_filter(*columns, min_ratio=None, max_ratio=None, concurrency=None)

Parameter

Type

Default

Description

min_ratio

Optional[float]

None

Minimum aspect ratio

max_ratio

Optional[float]

None

Maximum aspect ratio

Input type: DataType.image or DataType.binary

Return type: DataType.boolean

df = df.filter(image_shape_filter(col("img"), min_ratio=0.5, max_ratio=2.0))

image_file_size_filter

Filter images by encoded file size (bytes).

image_file_size_filter(*columns, min_bytes=None, max_bytes=None, concurrency=None)

Parameter

Type

Default

Description

min_bytes

Optional[int]

None

Minimum encoded size

max_bytes

Optional[int]

None

Maximum encoded size

Input type: DataType.binary

Return type: DataType.boolean

df = df.filter(image_file_size_filter(col("img"), max_bytes=5*1024*1024))

Image Quality Scoring

Operators for image quality, safety, and watermark assessment.

image_quality_score

Compute a composite quality score combining sharpness, contrast, and color richness.

Algorithm: weighted combination of Laplacian variance (sharpness, weight 50%) + grayscale standard deviation (contrast, weight 30%) + channel standard deviation (color richness, weight 20%).

image_quality_score(*columns, concurrency=None)

Input type: DataType.image

Return type: DataType.float64 (score range [0, 1], higher values indicate better quality)

df = df.with_column("quality", image_quality_score(col("img")))
df = df.filter(image_quality_score(col("img")) > 0.3)

image_nsfw_score

Assess NSFW risk using an image classification model.

Dependency: 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)

Parameter

Type

Default

Description

hf_nsfw_model

str

"Falconsai/nsfw_image_detection"

HuggingFace NSFW classification model ID.

Input type: DataType.image

Return type: DataType.float64 (probability range [0, 1], higher values indicate higher NSFW likelihood)

df = df.with_column("nsfw", image_nsfw_score(col("img")))
df = df.filter(image_nsfw_score(col("img")) < 0.5)

image_aesthetic_score

Assess image aesthetic quality using an aesthetic scoring model.

Dependency: 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)

Parameter

Type

Default

Description

hf_scorer_model

str

"shunk031/aesthetics-predictor-v2-sac-logos-ava1-l14-linearMSE"

HuggingFace aesthetic scoring model ID.

Input type: DataType.image

Return type: DataType.float64

df = df.with_column("aesthetic", image_aesthetic_score(col("img")))

image_watermark_score

Assess watermark risk using an image classification model.

Dependency: 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)

Parameter

Type

Default

Description

hf_watermark_model

str

"amrul-hzz/watermark_detector"

HuggingFace watermark detection model ID.

Input type: DataType.image

Return type: DataType.float64 (probability range [0, 1], higher values indicate higher watermark likelihood)

df = df.with_column("wm", image_watermark_score()(col("img")))
df = df.filter(image_watermark_score(col("img")) < 0.8)

Video Metadata, Splitting, and Frame Extraction

Video operators accept video URIs or video segment references as input. video_split only generates segment references without copying video files. Actual decoding occurs only when video_explode_frames or video_extract_frames is called. Frame extraction results use the Flink built-in IMAGE type.

video_metadata

Read basic video information such as resolution, frame rate, duration, and encoding format.

video_metadata(*columns, on_error="raise", container_options=None)

Parameter

Type

Default

Description

on_error

str

"raise"

Error handling strategy: "raise" or "null". "raise" throws an exception on error; "null" returns null for unreadable input.

container_options

Optional[dict]

None

Additional parameters used when opening video files. Usually does not need to be set.

Input type: DataType.string(video URI)

Return type:

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()
  }
)

For field definitions, see Video Metadata

df = df.with_column("video_meta", video_metadata(col("uri"), on_error="null"))

video_split

Split a complete video or existing video segment into multiple segment references, expanding to one segment reference per row (UDTF). This operator does not actually read video frames; it only computes time windows.

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)

Parameter

Type

Default

Description

segment_duration_ms

Optional[int]

None

Fixed segment duration in milliseconds. Mutually exclusive with num_segments.

num_segments

Optional[int]

None

Number of approximately equal segments. Mutually exclusive with segment_duration_ms.

video_duration_ms

Optional[int]

None

Explicit video duration in milliseconds.

max_segments

int

1024

Maximum number of output segments per row.

on_error

str

"raise"

Error handling strategy: "raise" or "null".

container_options

Optional[dict]

None

Additional parameters passed to the pyav container

read_chunk_size

Optional[int]

None

Chunk size for reading video files in bytes (tuning parameter; no user adjustment needed).

max_cached_blocks

Optional[int]

None

Number of cached file blocks to optimize Remote FS read overhead (tuning parameter; no user adjustment needed)

read_ahead_blocks

Optional[int]

None

Number of prefetch file blocks to optimize Remote FS read overhead (tuning parameter; no user adjustment needed)

segment_duration_ms and num_segments are mutually exclusive, representing two splitting strategies: split by time interval, or split by equal segment count.

Input type: DataType.string(video URI) / video segment reference

Return type: Video segment reference

DataType.struct(
  {
    "uri": DataType.string(),
    "start_time_ms": DataType.int64(),
    "end_time_ms": DataType.int64()
  }
)

For field definitions, see Video Segment Reference

The operator automatically probes video duration. If metadata has already been obtained via video_metadata, pass the video_metadata result as a second column to avoid redundant probing.

segments = df.join_lateral(
    video_split(segment_duration_ms=1000)(
        col("uri"),
        col("video_meta"), # optional column
    ).alias("segment")
)

video_explode_frames

Extract frames from a complete video or video segment, expanding results to one frame per row (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)

Parameter

Type

Default

Description

frame_selector

str

"all_frames"

Frame extraction strategy: "all_frames", "keyframe", "sample".

sample_interval_ms

Optional[int]

None

Sampling interval in milliseconds when frame_selector="sample".

max_frames

Optional[int]

None

Maximum number of output frames per input.

image_height

Optional[int]

None

Output frame height in pixels. Must be set together with image_width.

image_width

Optional[int]

None

Output frame width in pixels. Must be set together with image_height.

on_error

str

"raise"

Error handling strategy: "raise" or "null".

container_options

Optional[dict]

None

Additional parameters passed to the pyav container

read_chunk_size

Optional[int]

None

Chunk size for reading video files in bytes (tuning parameter; no user adjustment needed).

max_cached_blocks

Optional[int]

None

Number of cached file blocks to optimize Remote FS read overhead (tuning parameter; no user adjustment needed)

read_ahead_blocks

Optional[int]

None

Number of prefetch file blocks to optimize Remote FS read overhead (tuning parameter; no user adjustment needed)

Input type: DataType.string or video segment reference

Returns two columns: The first column is DataType.image (decoded RGB video frame); the second column contains video frame metadata as follows

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()
  }
)

For field definitions, see Video Frame Metadata

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

Extract frames from a complete video or video segment, collecting results from the same input video into arrays within a single row.

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)

Parameters are the same as video_explode_frames.

Input type: DataType.string / video segment reference

Return type: DataType.arraylist(DataType.image())

Suitable when downstream logic requires all frames from the same video at once. For long videos or large frame counts, use video_explode_frames to avoid holding too many images in a single row.

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,
    )
)

Complete Pipeline Example

The following example demonstrates a typical image data cleaning pipeline that combines multiple operators for filtering, decoding, scoring, and re-encoding:

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. Filter: keep only valid images, discard files smaller than 1KB or larger than 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. Decode + resize (decode once to avoid repeated decoding by downstream operators)
df = df.with_column("img", image_decode(col("raw_bytes")))
df = df.with_column("img", image_resize(col("img"), width=512, height=512))

# 3. Score: quality, NSFW, watermark
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. Filter by score
df = df.filter(col("quality") > 0.3)
df = df.filter(col("nsfw") < 0.5)
df = df.filter(col("watermark") < 0.8)

# 5. Re-encode to bytes for storage
df = df.with_column("img", image_encode(col("img"), format="JPEG"))

Video Splitting and Frame Extraction Pipeline

The following example demonstrates a typical pipeline from full video to per-frame image processing: first retrieve metadata, then split the video, and finally extract frames from each segment:

from pyflink.dataframe import col
from pyflink.multimodal.operators import (
    video_metadata, video_split, video_explode_frames,
)

# 1. Retrieve video metadata
df = df.with_column("video_meta", video_metadata(col("uri"), on_error="null"))

# 2. Split video into 1-second segments (pass metadata to avoid repeated duration probing)
segments = df.join_lateral(
    video_split(segment_duration_ms=1000)(
        col("uri"),
        col("video_meta"),
    ).alias("segment")
)

segments.balance()

# 3. Sample and extract frames from each segment
frames = segments.join_lateral(
    video_explode_frames(
 col("segment"),
        frame_selector="sample",
        sample_interval_ms=1000,
        max_frames=1,
    ).alias("frame", "metadata")
)

Dependencies

Multimodal operators depend on the following Python packages. The platform has pre-installed the corresponding versions, so manual installation is not required. If you need to debug in a local development environment, install the packages according to the table below.

Package

Version

Description

pillow

>=11.3,<12.3

Image processing

numpy

>=1.24,<1.25

Array computation

opencv-python-headless

>=4.10,<4.11

Image processing

imagehash

>=4.3,<4.4

Perceptual hashing

av

>=14.2,<15.0

Video decoding (FFmpeg bindings)

torch

>=2.5,<2.6

Deep learning inference

torchvision

>=0.20,<0.21

Vision model utilities

transformers

>=4.53,<4.58

HuggingFace model loading

safetensors

>=0.7,<0.9

Safe tensor format

open_clip_torch

>=2.32,<2.33

CLIP embedding extraction

ultralytics

>=8.3,<8.5

YOLO object detection

easyocr

>=1.7,<1.8

OCR text recognition

rembg

>=2.0,<2.1

Background removal

onnxruntime

>=1.16,<1.17

ONNX inference engine