Skip to content

LazyPipelineExpr

The LazyPipelineExpr class enables composable, lazy pipeline expressions.

Overview

import polars as pl
from polars_cv import Pipeline

# Create lazy expression
expr = pl.col("image").cv.pipe(Pipeline().source("image_bytes"))

# Chain operations
gray = expr.pipe(Pipeline().grayscale())

# Materialize with sink
result = df.with_columns(output=gray.sink("png"))

API Reference

LazyPipelineExpr

Lazy pipeline expression for composed operations.

This class represents a deferred computation that can be composed with other expressions. The entire graph is fused and executed when .sink() is called.

Example

preprocess = Pipeline().source("image_bytes").resize(height=100, width=200) img = pl.col("image").cv.pipe(preprocess) expr = img.sink("numpy")

node_id property

node_id: str

Get the unique node ID for this expression.

column property

column: Expr

Get the underlying column expression.

pipeline property

pipeline: 'Pipeline'

Get the pipeline specification.

alias_name property

alias_name: str | None

Get the user-defined alias for this node, if any.

__init__

__init__(
    column: Expr,
    pipeline: "Pipeline",
    node_id: str | None = None,
    upstream: list["LazyPipelineExpr"] | None = None,
    alias: str | None = None,
) -> None

Initialize a LazyPipelineExpr.

Parameters:

Name Type Description Default
column Expr

The Polars column expression this pipeline reads from.

required
pipeline 'Pipeline'

The Pipeline instance defining operations.

required
node_id str | None

Unique identifier for this node in the graph.

None
upstream list['LazyPipelineExpr'] | None

List of upstream LazyPipelineExpr dependencies.

None
alias str | None

Optional user-defined name for this node (for multi-output).

None

alias

alias(name: str) -> 'LazyPipelineExpr'

Name this checkpoint for multi-output extraction.

Example

base = pl.col("img").cv.pipe(pipe).alias("base") gray = base.pipe(Pipeline().grayscale()).alias("gray") expr = gray.sink({"base": "numpy", "gray": "png"})

pipe

pipe(pipeline: 'Pipeline') -> 'LazyPipelineExpr'

Chain a Pipeline onto this expression.

Parameters:

Name Type Description Default
pipeline 'Pipeline'

Operations to apply. If no source(), it continues from here.

required

sink

sink(
    format: str | dict[str, str] = "native",
    return_expr: bool = True,
    **kwargs: Any,
) -> "pl.Expr | PipelineGraph"

Finalize the pipeline graph and return a Polars expression.

Parameters:

Name Type Description Default
format str | dict[str, str]

Output format string (e.g., "numpy", "png") or a dict mapping aliases to formats for multi-output.

'native'
return_expr bool

If True (default), return a pl.Expr. If False, return the PipelineGraph.

True
kwargs Any

Parameters for the sink (e.g., quality for jpeg).

{}

Returns:

Type Description
'pl.Expr | PipelineGraph'

A Polars expression (or PipelineGraph if return_expr=False).

apply_mask

apply_mask(
    mask: "LazyPipelineExpr", *, invert: bool = False
) -> "LazyPipelineExpr"

Apply a binary mask to this image.

The mask can be from another image pipeline or a contour pipeline (which will be auto-rasterized to match dimensions).

Parameters:

Name Type Description Default
mask 'LazyPipelineExpr'

LazyPipelineExpr producing the mask.

required
invert bool

If True, invert the mask (keep exterior, zero interior).

False

Returns:

Type Description
'LazyPipelineExpr'

New LazyPipelineExpr with the mask operation composed.

label_reduce

label_reduce(
    *,
    contours: Expr,
    reduction: str = "max",
    region_mode: str = "interior",
) -> "LazyPipelineExpr"

Score contour regions from this buffer expression.

Parameters:

Name Type Description Default
contours Expr

Contour-set expression (List[Contour]) aligned by row.

required
reduction str

Aggregation over region values ("max", "mean", "sum").

'max'
region_mode str

Region selector ("interior" or "bbox").

'interior'

Returns:

Type Description
'LazyPipelineExpr'

New lazy expression in vector domain (list of scores).

add

add(other: 'LazyPipelineExpr') -> 'LazyPipelineExpr'

Element-wise addition with another array.

For u8/u16: Saturating addition (clamps to max value, e.g., 255 for u8). For f32/f64: Standard addition.

Parameters:

Name Type Description Default
other 'LazyPipelineExpr'

LazyPipelineExpr to add.

required

Returns:

Type Description
'LazyPipelineExpr'

New LazyPipelineExpr with the add operation composed.

Example
>>> img1 = pl.col("image1").cv.pipe(pipe1)
>>> img2 = pl.col("image2").cv.pipe(pipe2)
>>> result = img1.add(img2).sink("numpy")  # 200 + 100 = 255 (saturated)

subtract

subtract(other: 'LazyPipelineExpr') -> 'LazyPipelineExpr'

Element-wise subtraction.

For u8/u16: Saturating subtraction (clamps to 0). For f32/f64: Standard subtraction.

Parameters:

Name Type Description Default
other 'LazyPipelineExpr'

LazyPipelineExpr to subtract.

required

Returns:

Type Description
'LazyPipelineExpr'

New LazyPipelineExpr with the subtract operation composed.

Example
>>> img1 = pl.col("image1").cv.pipe(pipe1)
>>> img2 = pl.col("image2").cv.pipe(pipe2)
>>> result = img1.subtract(img2).sink("numpy")  # 50 - 100 = 0 (saturated)

multiply

multiply(other: 'LazyPipelineExpr') -> 'LazyPipelineExpr'

Element-wise multiplication.

For u8/u16: Saturating multiplication (clamps to max value). For f32/f64: Standard multiplication.

For normalized image blending (treating values as [0,1] range), use blend() instead.

Parameters:

Name Type Description Default
other 'LazyPipelineExpr'

LazyPipelineExpr to multiply by.

required

Returns:

Type Description
'LazyPipelineExpr'

New LazyPipelineExpr with the multiply operation composed.

Example
>>> img1 = pl.col("image1").cv.pipe(pipe1)
>>> img2 = pl.col("image2").cv.pipe(pipe2)
>>> result = img1.multiply(img2).sink("numpy")  # 16 * 16 = 255 (saturated)
See Also

blend: For normalized multiplication ((a/255) * (b/255) * 255)

divide

divide(other: 'LazyPipelineExpr') -> 'LazyPipelineExpr'

Element-wise division.

For u8/u16: Integer division with zero protection (returns 0 for divide by 0). For f32/f64: Standard division.

Parameters:

Name Type Description Default
other 'LazyPipelineExpr'

LazyPipelineExpr to divide by.

required

Returns:

Type Description
'LazyPipelineExpr'

New LazyPipelineExpr with the divide operation composed.

blend

blend(other: 'LazyPipelineExpr') -> 'LazyPipelineExpr'

Normalized blend (element-wise).

Performs normalized multiplication useful for image blending/compositing.

For u8: (a/255) * (b/255) * 255 For u16: (a/65535) * (b/65535) * 65535 For f32/f64: Standard multiplication.

Parameters:

Name Type Description Default
other 'LazyPipelineExpr'

LazyPipelineExpr to blend with.

required

Returns:

Type Description
'LazyPipelineExpr'

New LazyPipelineExpr with the blend operation composed.

Example

Blend two images together with proper normalization:

img1 = pl.col("image1").cv.pipe(pipe1) img2 = pl.col("image2").cv.pipe(pipe2) blended = img1.blend(img2).sink("numpy")

ratio

ratio(other: 'LazyPipelineExpr') -> 'LazyPipelineExpr'

Scaled ratio division.

Computes a/b scaled to the full range of the data type.

For u8: (a/b) * 255, clamped to [0, 255] For u16: (a/b) * 65535, clamped to [0, 65535] For f32/f64: Standard division.

Parameters:

Name Type Description Default
other 'LazyPipelineExpr'

LazyPipelineExpr to divide by.

required

Returns:

Type Description
'LazyPipelineExpr'

New LazyPipelineExpr with the ratio operation composed.

Example

Compute normalized ratio between two images:

img1 = pl.col("image1").cv.pipe(pipe1) img2 = pl.col("image2").cv.pipe(pipe2) result = img1.ratio(img2).sink("numpy")

bitwise_and

bitwise_and(
    other: "LazyPipelineExpr",
) -> "LazyPipelineExpr"

Element-wise bitwise AND.

For binary masks (0/255 values), this computes the intersection.

Parameters:

Name Type Description Default
other 'LazyPipelineExpr'

LazyPipelineExpr to AND with.

required

Returns:

Type Description
'LazyPipelineExpr'

New LazyPipelineExpr with the bitwise AND operation composed.

Example

Compute intersection of two binary masks:

mask1 = pl.col("pred_mask").cv.pipe(mask_pipe) mask2 = pl.col("gt_mask").cv.pipe(mask_pipe) intersection = mask1.bitwise_and(mask2).sink("list")

bitwise_or

bitwise_or(other: 'LazyPipelineExpr') -> 'LazyPipelineExpr'

Element-wise bitwise OR.

For binary masks (0/255 values), this computes the union.

Parameters:

Name Type Description Default
other 'LazyPipelineExpr'

LazyPipelineExpr to OR with.

required

Returns:

Type Description
'LazyPipelineExpr'

New LazyPipelineExpr with the bitwise OR operation composed.

Example

Compute union of two binary masks:

mask1 = pl.col("pred_mask").cv.pipe(mask_pipe) mask2 = pl.col("gt_mask").cv.pipe(mask_pipe) union = mask1.bitwise_or(mask2).sink("list")

bitwise_xor

bitwise_xor(
    other: "LazyPipelineExpr",
) -> "LazyPipelineExpr"

Element-wise bitwise XOR.

For binary masks (0/255 values), this computes the symmetric difference.

Parameters:

Name Type Description Default
other 'LazyPipelineExpr'

LazyPipelineExpr to XOR with.

required

Returns:

Type Description
'LazyPipelineExpr'

New LazyPipelineExpr with the bitwise XOR operation composed.

Example

Compute symmetric difference of two binary masks:

mask1 = pl.col("pred_mask").cv.pipe(mask_pipe) mask2 = pl.col("gt_mask").cv.pipe(mask_pipe) diff = mask1.bitwise_xor(mask2).sink("list")

maximum

maximum(other: 'LazyPipelineExpr') -> 'LazyPipelineExpr'

Element-wise maximum of two arrays.

Returns the maximum value at each position between this and another array. Useful for operations like image compositing, clamping, and non-linear image processing.

Parameters:

Name Type Description Default
other 'LazyPipelineExpr'

LazyPipelineExpr to compare with.

required

Returns:

Type Description
'LazyPipelineExpr'

New LazyPipelineExpr with the maximum operation composed.

Example

Compute element-wise maximum of two images:

img1 = pl.col("image1").cv.pipe(pipe1) img2 = pl.col("image2").cv.pipe(pipe2) result = img1.maximum(img2).sink("numpy")

minimum

minimum(other: 'LazyPipelineExpr') -> 'LazyPipelineExpr'

Element-wise minimum of two arrays.

Returns the minimum value at each position between this and another array. Useful for operations like image compositing, clamping, and non-linear image processing.

Parameters:

Name Type Description Default
other 'LazyPipelineExpr'

LazyPipelineExpr to compare with.

required

Returns:

Type Description
'LazyPipelineExpr'

New LazyPipelineExpr with the minimum operation composed.

Example

Compute element-wise minimum of two images:

img1 = pl.col("image1").cv.pipe(pipe1) img2 = pl.col("image2").cv.pipe(pipe2) result = img1.minimum(img2).sink("numpy")

apply_contour_mask

apply_contour_mask(
    contour: "LazyPipelineExpr", *, invert: bool = False
) -> "LazyPipelineExpr"

Apply a contour as a mask to this image.

The contour will be auto-rasterized to match the current image dimensions. This is a convenience for: mask_pipe = Pipeline().source("contour", shape=img_expr) mask = pl.col("contour").cv.pipe(mask_pipe) img.apply_mask(mask)

Parameters:

Name Type Description Default
contour 'LazyPipelineExpr'

LazyPipelineExpr from a contour source (dimensions will be inferred from this image's output shape).

required
invert bool

If True, mask exterior instead of interior.

False

Returns:

Type Description
'LazyPipelineExpr'

New LazyPipelineExpr with the contour mask applied.

merge_pipe

merge_pipe(
    *others: "LazyPipelineExpr",
) -> "LazyPipelineExpr"

Merge multiple pipeline branches into a single terminal node.

This creates a node that depends on self and all others, making them all reachable for multi-output sinking. The merged node outputs the same as self (the first/primary branch).

Use this when you have branching pipelines that share a backbone and want to sink multiple branches in a single expression.

Parameters:

Name Type Description Default
others 'LazyPipelineExpr'

Other LazyPipelineExpr nodes to include in the graph.

()

Returns:

Type Description
'LazyPipelineExpr'

New LazyPipelineExpr with all branches as upstream dependencies.

Example
>>> gray = pl.col("image").cv.pipe(gray_pipe).alias("gray")
>>> contours = gray.extract_contours().alias("contours")
>>> blurred = gray.blur(5).alias("blurred")
>>>
>>> # Merge branches for multi-output
>>> result = contours.merge_pipe(blurred)
>>> expr = result.sink({
...     "gray": "png",
...     "contours": "native",
...     "blurred": "numpy"
... })

Note: - Safe to merge nodes that are already upstream (deduplication handled) - Can merge pipelines from different source columns (multi-source graph) - The merged node's output is the same as self (first argument)

statistics

statistics(include: list[str] | None = None) -> pl.Expr

Compute multiple statistics from the buffer in a single pass.

Returns a Struct column with named fields for each statistic. By default includes: mean, std, min, max.

This is a convenience method that creates branching reduction pipelines and merges them into a single multi-output expression.

Parameters:

Name Type Description Default
include list[str] | None

List of statistics to compute. Valid options: - "mean": Arithmetic mean - "std": Standard deviation - "min": Minimum value - "max": Maximum value - "sum": Sum of all values If None, defaults to ["mean", "std", "min", "max"].

None

Returns:

Type Description
Expr

A Polars expression that returns a Struct column with the

Expr

requested statistics as fields.

Example
>>> # Get statistics for processed images
>>> pipe = Pipeline().source("image_bytes").grayscale()
>>> img = pl.col("image").cv.pipe(pipe)
>>> stats_expr = img.statistics()
>>> df.with_columns(stats=stats_expr)
>>> # Access: df["stats"].struct.field("mean")
>>>
>>> # Only compute specific stats
>>> stats_expr = img.statistics(include=["min", "max"])

statistics_lazy

statistics_lazy(
    include: list[str] | None = None,
) -> "LazyPipelineExpr"

Create a lazy pipeline for computing multiple statistics.

Unlike statistics() which returns a finalized pl.Expr, this method returns a LazyPipelineExpr that can be merged with other pipelines for multi-output composition.

When sunk, each statistic becomes a separate field in the output struct. The stat nodes are aliased with prefixed names: "stat_mean", "stat_std", etc.

Parameters:

Name Type Description Default
include list[str] | None

List of statistics to compute. Valid options: - "mean": Arithmetic mean - "std": Standard deviation - "min": Minimum value - "max": Maximum value - "sum": Sum of all values If None, defaults to ["mean", "std", "min", "max"].

None

Returns:

Type Description
'LazyPipelineExpr'

A LazyPipelineExpr representing the merged statistics pipelines.

'LazyPipelineExpr'

Can be composed with other pipelines using merge_pipe().

Example
>>> # Compose stats with other outputs
>>> pipe = Pipeline().source("image_bytes")
>>> img = pl.col("image").cv.pipe(pipe).alias("img")
>>> gray = img.pipe(Pipeline().grayscale()).alias("gray")
>>> stats = gray.statistics_lazy()  # Creates stat_mean, stat_std, etc.
>>>
>>> # Merge and sink together
>>> result = img.merge_pipe(gray, stats)
>>> expr = result.sink({
...     "img": "numpy",
...     "gray": "numpy",
...     "stat_mean": "native",
...     "stat_std": "native",
...     "stat_min": "native",
...     "stat_max": "native",
... })

channel_select

channel_select(*, index: 'IntOrExpr') -> 'LazyPipelineExpr'

Extract a single channel from a multi-channel image.

Parameters:

Name Type Description Default
index 'IntOrExpr'

Channel index to extract (0-based). Accepts a Polars expression for per-row dynamic selection.

required

Returns:

Type Description
'LazyPipelineExpr'

New LazyPipelineExpr with the selected channel.

channel_swap

channel_swap(*, order: list[int]) -> 'LazyPipelineExpr'

Reorder channels in a multi-channel image.

Parameters:

Name Type Description Default
order list[int]

New channel ordering, e.g. [2, 1, 0] for RGB-to-BGR.

required

Returns:

Type Description
'LazyPipelineExpr'

New LazyPipelineExpr with reordered channels.

adjust_contrast

adjust_contrast(
    *, factor: "FloatOrExpr"
) -> "LazyPipelineExpr"

Adjust image contrast.

Parameters:

Name Type Description Default
factor 'FloatOrExpr'

Contrast factor. 1.0 = no change, >1 = more contrast.

required

Returns:

Type Description
'LazyPipelineExpr'

New LazyPipelineExpr with adjusted contrast.

adjust_gamma

adjust_gamma(*, gamma: 'FloatOrExpr') -> 'LazyPipelineExpr'

Apply gamma (power-law) correction.

Parameters:

Name Type Description Default
gamma 'FloatOrExpr'

Gamma value. <1 = brighter, >1 = darker.

required

Returns:

Type Description
'LazyPipelineExpr'

New LazyPipelineExpr with gamma correction applied.

adjust_brightness

adjust_brightness(
    *, factor: "FloatOrExpr"
) -> "LazyPipelineExpr"

Adjust image brightness by scaling pixel values.

Parameters:

Name Type Description Default
factor 'FloatOrExpr'

Brightness factor. 1.0 = no change, >1 = brighter.

required

Returns:

Type Description
'LazyPipelineExpr'

New LazyPipelineExpr with adjusted brightness.

invert

invert() -> 'LazyPipelineExpr'

Invert pixel values.

Returns:

Type Description
'LazyPipelineExpr'

New LazyPipelineExpr with inverted pixels.

cvt_color

cvt_color(
    from_space: str, to_space: str
) -> "LazyPipelineExpr"

Convert between color spaces.

Parameters:

Name Type Description Default
from_space str

Source color space (rgb, bgr, hsv, lab, ycbcr, gray).

required
to_space str

Target color space (rgb, bgr, hsv, lab, ycbcr, gray).

required

Returns:

Type Description
'LazyPipelineExpr'

New LazyPipelineExpr with converted color space.

to_hsv

to_hsv() -> 'LazyPipelineExpr'

Convert from RGB to HSV color space.

Returns:

Type Description
'LazyPipelineExpr'

New LazyPipelineExpr in HSV color space.

to_lab

to_lab() -> 'LazyPipelineExpr'

Convert from RGB to CIE LAB color space.

Returns:

Type Description
'LazyPipelineExpr'

New LazyPipelineExpr in LAB color space (f32).

to_bgr

to_bgr() -> 'LazyPipelineExpr'

Convert from RGB to BGR channel order.

Returns:

Type Description
'LazyPipelineExpr'

New LazyPipelineExpr in BGR order.

to_ycbcr

to_ycbcr() -> 'LazyPipelineExpr'

Convert from RGB to YCbCr color space.

Returns:

Type Description
'LazyPipelineExpr'

New LazyPipelineExpr in YCbCr color space.

convolve2d

convolve2d(
    kernel: list[float],
    ksize: "IntOrExpr",
    *,
    normalize: bool = False,
    border: str = "replicate",
) -> "LazyPipelineExpr"

Apply generic 2D convolution with an arbitrary kernel.

Parameters:

Name Type Description Default
kernel list[float]

Flattened kernel values (row-major, ksize x ksize).

required
ksize 'IntOrExpr'

Kernel dimension (must be odd). Accepts a Polars expression for per-row dynamic values.

required
normalize bool

If True, divide output by the sum of absolute kernel values.

False
border str

Border handling mode ("replicate", "zero", "reflect").

'replicate'

Returns:

Type Description
'LazyPipelineExpr'

New LazyPipelineExpr with convolution applied.

sobel

sobel(
    *, axis: str = "x", ksize: int = 3
) -> "LazyPipelineExpr"

Sobel gradient operator.

Parameters:

Name Type Description Default
axis str

Gradient direction — "x" or "y".

'x'
ksize int

Kernel size (currently only 3).

3

Returns:

Type Description
'LazyPipelineExpr'

New LazyPipelineExpr with Sobel gradient applied.

laplacian

laplacian(*, ksize: int = 3) -> 'LazyPipelineExpr'

Laplacian second-derivative operator.

Parameters:

Name Type Description Default
ksize int

Kernel size (currently only 3).

3

Returns:

Type Description
'LazyPipelineExpr'

New LazyPipelineExpr with Laplacian applied.

sharpen

sharpen(*, strength: float = 1.0) -> 'LazyPipelineExpr'

Sharpen using an unsharp-mask-style kernel.

Parameters:

Name Type Description Default
strength float

Sharpening strength (default 1.0).

1.0

Returns:

Type Description
'LazyPipelineExpr'

New LazyPipelineExpr with sharpening applied.

canny

canny(
    *,
    low_threshold: "FloatOrExpr" = 50.0,
    high_threshold: "FloatOrExpr" = 150.0,
) -> "LazyPipelineExpr"

Canny edge detection.

Parameters:

Name Type Description Default
low_threshold 'FloatOrExpr'

Lower hysteresis threshold.

50.0
high_threshold 'FloatOrExpr'

Upper hysteresis threshold.

150.0

Returns:

Type Description
'LazyPipelineExpr'

New LazyPipelineExpr with edge detection applied.

erode

erode(
    *, ksize: "IntOrExpr" = 3, iterations: "IntOrExpr" = 1
) -> "LazyPipelineExpr"

Morphological erosion (local minimum filter).

Parameters:

Name Type Description Default
ksize 'IntOrExpr'

Size of the square structuring element. Accepts a Polars expression for per-row dynamic values.

3
iterations 'IntOrExpr'

Number of times the erosion is applied. Accepts a Polars expression for per-row dynamic values.

1

Returns:

Type Description
'LazyPipelineExpr'

New LazyPipelineExpr with erosion applied.

dilate

dilate(
    *, ksize: "IntOrExpr" = 3, iterations: "IntOrExpr" = 1
) -> "LazyPipelineExpr"

Morphological dilation (local maximum filter).

Parameters:

Name Type Description Default
ksize 'IntOrExpr'

Size of the square structuring element. Accepts a Polars expression for per-row dynamic values.

3
iterations 'IntOrExpr'

Number of times the dilation is applied. Accepts a Polars expression for per-row dynamic values.

1

Returns:

Type Description
'LazyPipelineExpr'

New LazyPipelineExpr with dilation applied.

morphology_open

morphology_open(
    *, ksize: "IntOrExpr" = 3
) -> "LazyPipelineExpr"

Morphological opening (erode then dilate).

Parameters:

Name Type Description Default
ksize 'IntOrExpr'

Size of the square structuring element. Accepts a Polars expression for per-row dynamic values.

3

Returns:

Type Description
'LazyPipelineExpr'

New LazyPipelineExpr with opening applied.

morphology_close

morphology_close(
    *, ksize: "IntOrExpr" = 3
) -> "LazyPipelineExpr"

Morphological closing (dilate then erode).

Parameters:

Name Type Description Default
ksize 'IntOrExpr'

Size of the square structuring element. Accepts a Polars expression for per-row dynamic values.

3

Returns:

Type Description
'LazyPipelineExpr'

New LazyPipelineExpr with closing applied.

morphology_gradient

morphology_gradient(
    *, ksize: "IntOrExpr" = 3
) -> "LazyPipelineExpr"

Morphological gradient (dilate - erode).

Parameters:

Name Type Description Default
ksize 'IntOrExpr'

Size of the square structuring element. Accepts a Polars expression for per-row dynamic values.

3

Returns:

Type Description
'LazyPipelineExpr'

New LazyPipelineExpr with morphological gradient applied.

equalize_histogram

equalize_histogram() -> 'LazyPipelineExpr'

Apply histogram equalization for contrast enhancement.

Returns:

Type Description
'LazyPipelineExpr'

New LazyPipelineExpr with equalized histogram.

__repr__

__repr__() -> str

Return string representation with guidance.

__str__

__str__() -> str

Return string representation.