Filter Image Using Bilateral
SUMMARY
Filter Image Using Bilateral reduces image noise while keeping edges sharp.
Unlike filter_image_using_blur, which averages every pixel in a neighborhood regardless of content, the bilateral filter weights each neighbor by both spatial proximity (spatial_sigma) and color/intensity similarity (color_intensity_sigma). Pixels across a strong edge have dissimilar intensity, so they contribute little to the average, and the edge stays sharp while flat, noisy regions get smoothed. It is slower than a plain blur.
Use this Skill when you want to denoise an image without blurring its edges.
The Skill
from telekinesis import pupil
filtered_image = pupil.filter_image_using_bilateral(
image=image,
neighborhood_diameter=9,
color_intensity_sigma=75.0,
spatial_sigma=75.0,
border_type="default",
)Example
Input Image

Original noisy image of scattered nuts
Filtered Image

Denoised image with edges preserved (neighborhood_diameter=5, spatial_sigma=75.0, color_intensity_sigma=100.0)
The Code
"""Demonstrates filter_image_using_bilateral operation."""
from loguru import logger
import rerun as rr
from telekinesis import pupil, datatypes
def filter_image_using_bilateral_example():
"""Applies filter_image_using_bilateral operation."""
# ===================== Load Image ==========================================
image_url = "https://assets.telekinesis.ai/examples/v1/images/nuts_scattered_noised.jpg"
image = datatypes.Image.from_url(image_url)
# ===================== Run Skill ==========================================
filtered_image = pupil.filter_image_using_bilateral(
image=image,
neighborhood_diameter=5,
spatial_sigma=75.0,
color_intensity_sigma=100.0,
border_type="default",
)
# ===================== Log ================================================
logger.success(f"Applied filter_image_using_bilateral on {image}")
logger.success(f"Result: {filtered_image}")
# ===================== Visualization (Optional) ======================
rr.init("filter_image_using_bilateral_example", spawn=True)
datatypes.visualize(image, entity_path="1-Original")
datatypes.visualize(filtered_image, entity_path="2-Filtered")
if __name__ == "__main__":
filter_image_using_bilateral_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_bilateral.pyParameter Configuration
| Key | Type | Default | Description |
|---|---|---|---|
image | datatypes.Image | np.ndarray | required | The input image to filter, shape (H, W) or (H, W, C) |
neighborhood_diameter | datatypes.Int | int | 9 | Diameter of the kernel used for spatial filtering, in pixels. Must be odd |
color_intensity_sigma | datatypes.Float | float | int | 75.0 | Standard deviation of the color/intensity Gaussian; controls how much color difference is tolerated when averaging |
spatial_sigma | datatypes.Float | float | int | 75.0 | Standard deviation of the spatial Gaussian, in pixels; controls how far away a pixel can be and still contribute |
border_type | datatypes.String | str | "default" | Border handling mode: "default", "constant", "replicate", "reflect", or "reflect 101" |
Returns
| Type | Description |
|---|---|
datatypes.Image | Same shape as image, denoised while edges are kept sharp. |
Raises
| Exception | Condition |
|---|---|
TypeError | A parameter's value does not match its expected type (see the Parameter Configuration table above) |
ValueError | neighborhood_diameter is not odd, or 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_bilateral Skill exposes four parameters that trade off smoothing strength, edge preservation, and speed.
neighborhood_diameter
- Controls: The size of the spatial kernel used for filtering.
- Units: Pixels
- Default:
9 - Increase → more smoothing over a larger area, but slower
- Decrease → faster, but less effective smoothing
- Typical range: 3-15. Use 3-5 for small images or subtle smoothing, 5-9 for moderate noise, 9-15 for large images or heavy noise.
spatial_sigma
- Controls: How far away a neighboring pixel can be and still influence the result.
- Units: Pixels
- Default:
75.0 - Increase → considers pixels farther away, more smoothing over a larger region
- Decrease → limits smoothing to nearby pixels, preserving more local detail
- Typical range: 10.0-150.0. Use 10.0-50.0 for fine detail, 50.0-100.0 for balanced, 100.0-150.0 for strong smoothing.
color_intensity_sigma
- Controls: How large a color/intensity difference between two pixels can be while still letting them smooth together.
- Units: Intensity levels
- Default:
75.0 - Increase → larger color differences get merged, blending across weaker edges
- Decrease → preserves more color boundaries, less cross-edge blending
- Typical range: 10.0-150.0. Use 10.0-50.0 for strict edge preservation, 50.0-100.0 for balanced, 100.0-150.0 for more aggressive blending.
border_type
- Controls: How pixels beyond the image boundary are synthesized when the kernel extends past the edge.
- Default:
"default" - Options:
default– same asreflect 101; suitable for most casesconstant– pads with a fixed value; use for a known black/white borderreplicate– repeats the edge pixelreflect– mirrors the image without repeating the edge pixelreflect 101– mirrors with the edge pixel repeated; avoids dark border artifacts
TIP
Best practice: Start from the defaults (neighborhood_diameter=9, spatial_sigma=75.0, color_intensity_sigma=75.0) and adjust from there. If edges look blurred, lower color_intensity_sigma first; if noise remains, raise spatial_sigma or neighborhood_diameter before reaching for a larger kernel.
Where to Use the Skill
Common pipelines include:
- Preprocessing for detection/segmentation – Remove sensor noise while keeping object boundaries intact for downstream edge or contour detection
- Depth map refinement – Smooth depth data while preserving discontinuities at object boundaries
- Photography/inspection enhancement – Reduce noise in low-light captures without softening defects or part edges
Alternative Skills
| Skill | vs. Filter Image Using Bilateral |
|---|---|
| filter_image_using_blur | A plain box average — faster, but blurs edges along with noise. Use when speed matters more than edge preservation. |
| filter_image_using_gaussian_blur | A Gaussian-weighted blur — smoother than a box blur but still blurs across edges. Faster than bilateral. |
| filter_image_using_median_blur | Removes salt-and-pepper (impulse) noise specifically; bilateral is better suited to general sensor noise. |
When Not to Use the Skill
Do not use Filter Image Using Bilateral when:
- Processing speed on large images matters more than edge preservation (use
filter_image_using_blurorfilter_image_using_gaussian_blurinstead) - The goal is to detect edges rather than preserve them (use an edge/gradient filter such as
filter_image_using_sobelorfilter_image_using_laplacian) - The noise is salt-and-pepper (impulse) noise (use
filter_image_using_median_blur, which is specifically designed for this) - The image is already binary or heavily quantized (use morphological operations instead)

