Statistical (rank) filters

Prerequisites

Before starting this lesson, you should be familiar with:

Learning Objectives

After completing this lesson, learners should be able to:
  • Understand conceptually how local statistical (rank) filter work

  • Apply statistical filters to images

Motivation

Concept map

graph TD P("pixel") --> NS("neighbourhood statistics") NS --> FP("filtered pixel value")



Figure


Shows the effect of a radius 2 disk shaped kernel statistical filter on an image. Top left: Input; Top middle: Minimum; Top right: Maximum; Bottom left: Mean; Bottom middle: Median; Bottom right: Variance.






Activities

Median filter exploration

Explore the effect of the median filter on various example images. Explore how changing the size (structural element) of the filter affects the result.

Example images:


Show activity for:  

ImageJ Macro

run("Close All");

//File > Open...
open("https://github.com/NEUBIAS/training-resources/raw/master/image_data/xy_8bit__two_noisy_squares_different_size.tif");
// Image > Duplicate...
run("Duplicate...", "title=Median_1");
// Image > Duplicate...
run("Duplicate...", "title=Median_2");
// Image > Duplicate...
run("Duplicate...", "title=Median_5");

selectWindow("Median_1");
// Process › Filters › Median...
run("Median...", "radius=1");

selectWindow("Median_2");
// Process › Filters › Median...
run("Median...", "radius=2");

selectWindow("Median_5");
// Process › Filters › Median...
run("Median...", "radius=5");
run("Tile")

skimage napari

# %%
# Median filtering

# %%
# import modules
import napari
import numpy as np
from skimage import filters
from skimage.filters import rank
from skimage.morphology import disk # Structuring element
from OpenIJTIFF import open_ij_tiff

# %%
# Instantiate the napari viewer
viewer = napari.Viewer()

# %%
# Read and view the image
image, *_ = open_ij_tiff('https://github.com/NEUBIAS/training-resources/raw/master/image_data/xy_8bit__two_noisy_squares_different_size.tif')
viewer.add_image(image)

# %% 
# Compare small median and mean filter
# - Appreciate that the median filter better preserves the edges
median_1 = filters.median(image, disk(1))
viewer.add_image(median_1)
mean_1 = rank.mean(image, disk(1))
viewer.add_image(mean_1)

# %% 
# Compare a larger median and mean filter
# - Appreciate that a median filter eliminates the small square entirely
median_3 = filters.median(image, disk(3))
viewer.add_image(median_3)
mean_3 = rank.mean(image, disk(3))
viewer.add_image(mean_3)


###########  New image: nucleare speckles #############

# %%
# Clear the napari viewer
viewer.layers.clear()

# %%
# Load image
image, *_ = open_ij_tiff('https://github.com/NEUBIAS/training-resources/raw/master/image_data/xy_8bit__PCNA.tif')

# %%
# View the image and find the radius of the intra-nuclear speckles
viewer.add_image(image)

# %%
# Remove small intra-nuclear structures 
# - Appreciate that a median filter removes the intra-nuclear speckles while keeping the nuclear shape intact
# - This can be helpful in many ways, e.g. some deep learning nuclear segmentation tools get confused by intra-nuclear speckles
# - Another application is to subtract the filtered image from the original image to only have the speckles; this will be used in the 
#   "local background subtraction" training module
image_without_speckles = filters.median(image, disk(radius=15))
viewer.add_image(image_without_speckles)

Galaxy

  • Upload the following images to Galaxy
  • Apply Median Filter
    • In the Tools panel, search Filter 2D image, and click Filter 2D image with scikit-image from the search results
    • In Galaxy main window,apply the followings
      • Filter type: Median
      • Radius/Sigma: Explore different values, such as 1,2 or 5
      • Source file: click the second button to activate Multiple datasets. Select images from the dropdown list.
    • Click Run Tool
    • Depending on the number of input images, you will see the corresponding number of outputs in the History panel on the right. Wait for them to turn green and download the resulting images.



Statistical filter exploration

Explore the effects of various statistical filters on an image.


Show activity for:  

ImageJ Macro

run("Close All");

// File > Open...
open("https://github.com/NEUBIAS/training-resources/raw/master/image_data/xy_8bit__statistical_filter_test_input.tif");
zoom();

// Manual activity:
// Choose one interesting 5x5 region
// in the image and manually compute
// the below statistical filters.
// Note down the resulting numbers and later check
// whether they agree with the below
// automated analysis.


// Image > Duplicate...
run("Duplicate...", "title=Minimum"); zoom();
run("Duplicate...", "title=Maximum"); zoom();
run("Duplicate...", "title=Mean"); zoom();
run("Duplicate...", "title=Median"); zoom();
run("Duplicate...", "title=Variance"); zoom();

// Apply Minimum filter
selectWindow("Minimum");
// Process › Filters › Minimum...
run("Minimum...", "radius=2");

// Apply Maximum filter
selectWindow("Maximum");
// Process › Filters › Maximum...
run("Maximum...", "radius=2");

// Apply Mean filter
selectWindow("Mean");
run("32-bit"); // Results of mean filter are generally not 8=bit
// Process › Filters › Mean...
run("Mean...", "radius=2");

// Apply Median filter
selectWindow("Median");
// Process › Filters › Median...
run("Median...", "radius=2");

// Apply Variance filter
selectWindow("Variance");
run("32-bit"); // Results of variance filter are generally not 8=bit
// Process › Filters › Variance...
run("Variance...", "radius=2");

// Arrange windows in a tiled layout
run("Tile");

// Learning opportunities:
// - Check the result of a variance filter without converting the image to 32-bit float

function zoom() { 
	run("In [+]");
	run("In [+]");
	run("In [+]");
	run("In [+]");
}

skimage napari

# %%
# Statistical filtering

# %%
# Import modules
import napari
import numpy as np
from skimage import io
from skimage.filters import rank
from skimage.morphology import disk  # Structuring element
from skimage import img_as_float, img_as_ubyte
from OpenIJTIFF import open_ij_tiff

# %%
# Instantiate the napari viewer
viewer = napari.Viewer()

# %%
# Read and view the image
image, *_ = open_ij_tiff('https://github.com/NEUBIAS/training-resources/raw/master/image_data/xy_8bit__statistical_filter_test_input.tif')
viewer.add_image(image, name="Original")

# %% 
# Apply Minimum filter
# - Removes bright details smaller than the structuring element
minimum_filtered = rank.minimum(image, disk(2))
viewer.add_image(minimum_filtered, name="Minimum (r=2)")

# %% 
# Apply Maximum filter
# - Removes dark details smaller than the structuring element
maximum_filtered = rank.maximum(image, disk(2))
viewer.add_image(maximum_filtered, name="Maximum (r=2)")

# %% 
# Apply Mean filter
# - Smooths the image by averaging pixels within the structuring element
mean_filtered = rank.mean(image, disk(2))
viewer.add_image(mean_filtered, name="Mean (r=2)")

# %% 
# Apply Median filter
# - Removes noise while preserving edges
median_filtered = rank.median(image, disk(2))
viewer.add_image(median_filtered, name="Median (r=2)")

# %% 
# Apply Variance filter
# - Highlights areas with high intensity variation
var_image = generic_filter(image, function=np.var, size=11)

viewer.add_image(variance_filtered, name="Entropy (r=2)")

# %%
# Manual activity:
# Choose one interesting 5x5 region in the image and manually compute
# the statistical filters. Compare with the automated results.

# %%
# Learning opportunity:
# - Compare the effect of different radii on the filter results
# - Observe how different filters affect noise and edges in the image






Assessment

Answer the questions

  1. What is the primary purpose of applying a median filter to an image?
  2. How does a local maximum filter differ from a local minimum filter in terms of the output pixel values?
  3. Why might variance filtering be particularly useful in label-free microscopy?

Solution

  1. To reduce noise in an image while preserving edges.
  2. A local maximum filter replaces each pixel with the maximum value in its neighborhood, while a local minimum filter replaces it with the minimum value.
  3. Variance filtering highlights regions with high variability, which can help detect structures in label-free microscopy such as transmission light microscopy or electron microscopy.




Follow-up material

Recommended follow-up modules:

Learn more: