Skip to content

Filter Image Using Frangi

SUMMARY

Filter Image Using Frangi applies the Frangi vesselness filter to enhance tubular structures in an image.

The filter runs Hessian eigenvalue analysis at multiple scales between scale_start and scale_end, combining a blobness term (weighted by alpha) and a structureness term (weighted by beta) into a per-pixel vesselness score, and keeps the strongest response across scales. It responds to elongated structures such as vessels, wires, scratches, or cracks, while suppressing blob-like and flat regions. Compare with filter_image_using_hessian (same eigenvalue approach, simpler vesselness formula) and filter_image_using_sato/filter_image_using_meijering (faster ridge filters without blobness weighting).

Use this Skill when you want to enhance and detect vessel-like tubular structures at multiple scales.

The Skill

python
from telekinesis import pupil

filtered_image = pupil.filter_image_using_frangi(
    image=image,
    scale_start=6,
    scale_end=10,
    scale_step=1,
    alpha=0.5,
    beta=0.5,
    detect_black_ridges=True,
    border_type="reflect",
    border_value=0.0,
)
API Reference
Full parameter and return type documentation for filter_image_using_frangi.
View Reference →

Example

Input Image

Input image

Original grayscale image, normalized to the 0-1 range

Filtered Image

Output image

Vesselness map highlighting tubular structures

The Code

python
"""Demonstrates filter_image_using_frangi operation."""

from loguru import logger
import rerun as rr

from telekinesis import pupil, datatypes


def filter_image_using_frangi_example():
    """Applies filter_image_using_frangi operation."""
    # ===================== Load Image ==========================================
    image_url = "https://assets.telekinesis.ai/examples/v1/images/tablets_arranged.jpg"
    image = datatypes.Image.from_url(image_url)

    # ===================== Run Skill ==========================================
    filtered_image = pupil.filter_image_using_frangi(
        image=image,
        scale_start=6,
        scale_end=10,
        scale_step=1,
        alpha=0.5,
        beta=0.5,
        detect_black_ridges=True,
        border_type="reflect",
        border_value=0.0,
    )

    # ===================== Log ================================================
    logger.success(f"Applied filter_image_using_frangi on {image}")
    logger.success(f"Result: {filtered_image}")

    # ===================== Visualization  (Optional) ======================
    rr.init("filter_image_using_frangi_example", spawn=True)
    datatypes.visualize(image, entity_path="1-Original")
    datatypes.visualize(filtered_image, entity_path="2-Filtered")

if __name__ == "__main__":
    filter_image_using_frangi_example()

Runnable examples are available in the Telekinesis examples repository.

Follow the README in that repository to set up the environment, run this specific example with:

bash
cd telekinesis-examples
python examples/image_processing/filter_image_using_frangi.py

Parameter Configuration

KeyTypeDefaultDescription
imagedatatypes.Image | np.ndarrayrequiredGrayscale input image, shape (H, W), normalized to the 0-1 range. Convert with convert_image_color_space first if starting from a color image
scale_startdatatypes.Int | int1Minimum scale (sigma) for structure detection
scale_enddatatypes.Int | int10Maximum scale (sigma) for structure detection
scale_stepdatatypes.Int | int2Step size between scales; smaller steps give finer scale resolution but are slower
alphadatatypes.Float | float | int0.5Weight for the blobness measure
betadatatypes.Float | float | int0.5Weight for the second-order structureness measure
gammadatatypes.Float | float | int | NoneNoneSensitivity to areas of high variance. When None, set internally to half of the maximum Hessian norm
detect_black_ridgesdatatypes.Bool | boolTrueWhether to detect dark ridges (vessels) instead of bright ones
border_typedatatypes.String | str"reflect"Border handling mode: "constant", "reflect", "wrap", "nearest", "mirror"
border_valuedatatypes.Float | float | int0.0Value used for constant padding, only relevant when border_type="constant"

Returns

TypeDescription
datatypes.ImageSame shape as image, with vesselness/ridge strength per pixel — higher values indicate a stronger tubular structure

Raises

ExceptionCondition
TypeErrorA parameter's value does not match its expected type (see the Parameter Configuration table above)
ValueErrorborder_type is not one of the supported border modes
ConfigurationErrorThe TELEKINESIS_API_KEY environment variable is not set
SerializationErrorThe request input failed to serialize, or the response failed to deserialize
RequestTimeoutErrorThe request to the Pupil service timed out
TransportErrorA network failure occurred before a response was received
ClientErrorThe Pupil service rejected the request due to invalid input, invalid data, or another unexpected 4xx response
AuthenticationErrorThe API key was rejected as invalid or expired
AuthenticationServiceErrorThe authentication service was unavailable
ServerErrorThe Pupil service returned a 5xx or otherwise unexpected error response

How to Tune the Parameters

The filter_image_using_frangi Skill exposes the scale range searched, the blobness/structureness weighting, ridge polarity, and border handling.

scale_start

  • Controls: The smallest sigma evaluated, i.e. the thinnest structure the filter can pick up.
  • Units: Pixels (sigma)
  • Default: 1
  • Increase → ignores very thin structures
  • Decrease → captures finer structures
  • Typical range: 1-5

scale_end

  • Controls: The largest sigma evaluated, i.e. the thickest structure the filter can pick up.
  • Units: Pixels (sigma)
  • Default: 10
  • Increase → captures thicker structures, slower
  • Decrease → narrower detectable width range, faster
  • Typical range: 5-20

scale_step

  • Controls: The spacing between evaluated scales.
  • Default: 2
  • Increase → faster, coarser scale sampling
  • Decrease → finer scale resolution, slower
  • Typical range: 1-5

alpha

  • Controls: How strongly blob-like structures are suppressed relative to tubular ones.
  • Default: 0.5
  • Increase → more tolerant of blob-like structures
  • Decrease → stricter tubular-only selectivity
  • Typical range: 0.1-2.0

beta

  • Controls: Sensitivity to second-order structureness (how much the response is suppressed in flat/background regions).
  • Default: 0.5
  • Increase → stronger tubular structure emphasis
  • Decrease → less sensitive to structureness
  • Typical range: 0.1-2.0

gamma

  • Controls: Sensitivity to overall Hessian-norm (background suppression).
  • Default: None (half of the maximum Hessian norm)
  • Increase → suppresses more low-contrast background
  • Decrease → retains more low-contrast response

detect_black_ridges

  • Controls: The polarity of ridge detected.
  • Default: True
  • Options:
    • True – detect dark tubular structures on a bright background
    • False – detect bright tubular structures on a dark background

border_type

  • Controls: How pixels beyond the image border are synthesized when computing derivatives near edges.
  • Default: "reflect"
  • Options:
    • "reflect" – reflects the image at the border
    • "constant" – pads with border_value
    • "wrap" – treats the image as periodic
    • "nearest" – extends with the nearest pixel
    • "mirror" – symmetric reflection

border_value

  • Controls: The constant fill value used only when border_type="constant".
  • Default: 0.0

TIP

Best practice: Set scale_start/scale_end to bracket the expected structure width in pixels, use scale_step=2 for a good speed/accuracy trade-off (drop to 1 only if you need maximum precision), and leave gamma=None unless background suppression needs manual tuning.

Where to Use the Skill

Common pipelines include:

  • Vessel/wire/crack enhancement – Boost elongated structures before thresholding or contour extraction
  • Defect inspection – Highlight scratches or hairline cracks on a surface prior to retina contour detection
  • Fingerprint ridge enhancement – Strengthen ridge continuity before minutiae extraction
  • Vesselness-based segmentation pre-processing – Feed the vesselness map into a segmentation skill instead of the raw image

Alternative Skills

Skillvs. Filter Image Using Frangi
filter_image_using_hessianSame eigenvalue-based approach with a simpler vesselness formula (no alpha blobness term); faster but less selective.
filter_image_using_satoA simpler, faster multi-scale ridge filter without blobness weighting; try it first if Frangi is too slow.
filter_image_using_meijeringTuned for fine branching structures (e.g. neurites); try if Frangi over-suppresses thin branch points.

When Not to Use the Skill

Do not use Filter Image Using Frangi when:

  • You need simple, fast edge detection (use filter_image_using_sobel or filter_image_using_scharr instead)
  • The structures of interest are not tubular/elongated (blobs, corners, or flat regions won't respond well)
  • Processing speed matters more than detection quality (multi-scale eigenvalue analysis is comparatively expensive — try filter_image_using_sato or filter_image_using_hessian first)
  • The input is a color image (convert to grayscale with convert_image_color_space first)