Skip to content

Filter Image Using Sato Filter

SUMMARY

Filter Image Using Sato Filter applies Sato filter for multi-scale ridge detection.

Sato filter is designed to detect ridges and valleys at multiple scales, useful for detecting fine structures like vessels or fibers. This filter is optimized for general ridge detection and performs well on a variety of biological and industrial images where linear or curved structures need to be enhanced. It's particularly effective for structures that are elongated but may have varying contrast or width.

Use this Skill when you want to detect ridges and fine linear structures at multiple scales.

The Skill

python
from telekinesis import pupil

ridges = pupil.filter_image_using_sato(
    image=image,
    scale_start=1,
    scale_end=10,
    scale_step=2,
    detect_black_ridges=True,
    border_type="reflect",
    constant_value=0.0,
)

API Reference

Example

Input Image

Input image

Original grayscale image (normalized to 0-1 range)

Output Image

Output image

Sato filter highlighting thin, bright ridge-like PCB structures such as traces and IC pins.

The Code

python
from telekinesis import pupil
from datatypes import io, datatypes

import pathlib
from loguru import logger

DATA_DIR = pathlib.Path("path/to/telekinesis-data")

# Load the grayscale image
filepath = str(DATA_DIR / "images" / "pcb_top_gray.png")
image = io.load_image(filepath=filepath, as_gray=True)

# Apply Sato filter
ridges = pupil.filter_image_using_sato(
    image=image,
    scale_start=2,
    scale_end=6,
    scale_step=2,
    detect_black_ridges=True,
    border_type="reflect",
    constant_value=0.0,
)
logger.success(f"Applied Sato filter with ridges shape as {ridges.to_numpy().shape}")

The Explanation of the Code

The Sato filter enhances ridge-like structures by analyzing second-order intensity variations across multiple scales. It is designed to respond strongly to elongated, linear features such as fibers, cracks, traces, or thin ridges, even when their width or contrast varies across the image.

The code begins by importing the required modules. These imports provide access to the Pupil SDK for filtering operations, numerical utilities for preprocessing, and optional logging.

python
from telekinesis import pupil
from datatypes import io, datatypes

import pathlib

from loguru import logger

A data directory is defined, and the input image is loaded as a grayscale image. Sato filtering operates on single-channel intensity images, since ridge detection is based on spatial derivatives rather than color information.

python
DATA_DIR = pathlib.Path("path/to/telekinesis-data")

# Load the grayscale image
filepath = str(DATA_DIR / "images" / "pcb_top_gray.png")
image = io.load_image(filepath=filepath, as_gray=True)

Next, the parameters controlling the multi-scale Sato analysis are configured. The Sato filter enhances ridge-like structures by analyzing second-order intensity variations across multiple scales, making it effective for detecting linear features like fibers, cracks, or traces that may vary in width.

scale_start, scale_end, and scale_step parameters define the range of scales over which ridge structures are analyzed. Smaller scales emphasize thin ridges and fine linear details, while larger scales capture wider or more diffuse linear features. The filter evaluates all scales and combines responses to handle ridges of varying thickness.

detect_black_ridges determines whether the filter highlights dark ridges on a bright background or bright ridges on a dark background. This matches the contrast polarity of the ridges in your specific image.

border_type and constant_value parameters control how image borders are handled when ridge responses are computed near the edges of the image, where derivative calculations require pixels outside the image boundaries.

The Sato filter is then applied using the filter_image_using_sato Skill. For each pixel, the filter evaluates ridge strength at all specified scales and retains the strongest response.

python
ridges = pupil.filter_image_using_sato(
    image=image,
    scale_start=2,
    scale_end=6,
    scale_step=2,
    detect_black_ridges=True,
    border_type="reflect",
    constant_value=0.0,
)
logger.success(f"Applied Sato filter with ridges shape as {ridges.to_numpy().shape}")

The output is a ridge enhancement map, where higher values indicate a stronger likelihood that a pixel belongs to a linear or ridge-like structure. The original image remains unchanged.

Running the Example

Runnable examples are available in the Telekinesis examples repository. Follow the README in that repository to set up the environment. Once set up, you can run this specific example with:

bash
cd telekinesis-examples
python examples/pupil_examples.py --example filter_image_using_sato

How to Tune the Parameters

The filter_image_using_sato Skill has 6 parameters:

scale_start (default: 1):

  • The minimum scale (sigma) for structure detection
  • Typical range: 1-5

scale_end (default: 10):

  • The maximum scale (sigma) for structure detection
  • Typical range: 5-20

scale_step (default: 2):

  • The step size between scales
  • Typical range: 1-5

detect_black_ridges (default: True):

  • Whether to detect dark ridges instead of bright

border_type (default: "reflect"):

  • Padding mode
  • Options: "reflect", "constant", "edge", "symmetric", "wrap"

constant_value (default: 0.0):

  • Value used for constant padding mode
  • Typical range: 0.0-1.0

TIP

Best practice: Set scale_start and scale_end to span the expected range of ridge widths. Use scale_step=2 for efficiency.

Where to Use the Skill in a Pipeline

Filter Using Sato is commonly used in the following pipelines:

  • Fiber detection - Detect fibrous structures in materials
  • Crack detection - Identify cracks and linear defects
  • Ridge enhancement - Enhance ridge patterns in various images
  • Biological imaging - Detect fibers and elongated structures
  • Industrial inspection - Find linear features or defects

A typical pipeline for crack detection looks as follows:

python
# Example pipeline using Sato (parameters omitted).

from telekinesis import pupil
from datatypes import io

# 1. Load the inspection image
image = io.load_image(filepath=...)

# 2. Preprocess
preprocessed = pupil.filter_image_using_gaussian_blur(image=image, ...)

# 3. Apply Sato for ridge detection
ridges = pupil.filter_image_using_sato(image=preprocessed, ...)

# 4. Threshold
binary = ridges > threshold

# 5. Post-process
result = pupil.filter_image_using_morphological_close(image=binary, ...)

Related skills to build such a pipeline:

  • load_image: Load images
  • filter_image_using_gaussian_blur: Pre-smooth
  • filter_image_using_frangi: Alternative for vessel structures
  • filter_image_using_morphological_close: Post-process results

Alternative Skills

Skillvs. Filter Using Sato
filter_image_using_frangiFrangi is optimized for vessels. Use Sato for general ridges, Frangi for biological vessels.
filter_image_using_hessianHessian is simpler. Use Sato for better ridge detection, Hessian for speed.
filter_image_using_meijeringMeijering is optimized for neurites. Use Sato for general ridges.

When Not to Use the Skill

Do not use Filter Using Sato when:

  • You're detecting blob-like structures (Use blob detectors instead)
  • You need simple edge detection (Use Sobel or Canny)
  • Structures are not ridge-like (Use appropriate filters)
  • You need very fast processing (Sato is computationally expensive)