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
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,
)Example
Input Image

Original grayscale image, normalized to the 0-1 range
Filtered Image

Vesselness map highlighting tubular structures
The Code
"""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:
cd telekinesis-examples
python examples/image_processing/filter_image_using_frangi.pyParameter Configuration
| Key | Type | Default | Description |
|---|---|---|---|
image | datatypes.Image | np.ndarray | required | Grayscale 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_start | datatypes.Int | int | 1 | Minimum scale (sigma) for structure detection |
scale_end | datatypes.Int | int | 10 | Maximum scale (sigma) for structure detection |
scale_step | datatypes.Int | int | 2 | Step size between scales; smaller steps give finer scale resolution but are slower |
alpha | datatypes.Float | float | int | 0.5 | Weight for the blobness measure |
beta | datatypes.Float | float | int | 0.5 | Weight for the second-order structureness measure |
gamma | datatypes.Float | float | int | None | None | Sensitivity to areas of high variance. When None, set internally to half of the maximum Hessian norm |
detect_black_ridges | datatypes.Bool | bool | True | Whether to detect dark ridges (vessels) instead of bright ones |
border_type | datatypes.String | str | "reflect" | Border handling mode: "constant", "reflect", "wrap", "nearest", "mirror" |
border_value | datatypes.Float | float | int | 0.0 | Value used for constant padding, only relevant when border_type="constant" |
Returns
| Type | Description |
|---|---|
datatypes.Image | Same shape as image, with vesselness/ridge strength per pixel — higher values indicate a stronger tubular structure |
Raises
| Exception | Condition |
|---|---|
TypeError | A parameter's value does not match its expected type (see the Parameter Configuration table above) |
ValueError | border_type is not one of the supported border modes |
ConfigurationError | The TELEKINESIS_API_KEY environment variable is not set |
SerializationError | The request input failed to serialize, or the response failed to deserialize |
RequestTimeoutError | The request to the Pupil service timed out |
TransportError | A network failure occurred before a response was received |
ClientError | The Pupil service rejected the request due to invalid input, invalid data, or another unexpected 4xx response |
AuthenticationError | The API key was rejected as invalid or expired |
AuthenticationServiceError | The authentication service was unavailable |
ServerError | The 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 backgroundFalse– 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 withborder_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
retinacontour 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
| Skill | vs. Filter Image Using Frangi |
|---|---|
| filter_image_using_hessian | Same eigenvalue-based approach with a simpler vesselness formula (no alpha blobness term); faster but less selective. |
| filter_image_using_sato | A simpler, faster multi-scale ridge filter without blobness weighting; try it first if Frangi is too slow. |
| filter_image_using_meijering | Tuned 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_sobelorfilter_image_using_scharrinstead) - 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_satoorfilter_image_using_hessianfirst) - The input is a color image (convert to grayscale with
convert_image_color_spacefirst)

