phenotypic.enhance.UnsharpMask#

class phenotypic.enhance.UnsharpMask(radius: float = 2.0, amount: float = 1.0, preserve_range: bool = False)[source]#

Bases: ImageEnhancer

Unsharp masking for enhanced colony edge definition on agar plates.

Unsharp masking is a classical sharpening technique that enhances edges by subtracting a blurred copy of the image from the original, then scaling the difference to emphasize high-contrast boundaries. On fungal colony plates, this makes soft or indistinct colony edges more pronounced, improving the ability of thresholding and edge-detection algorithms to identify colony boundaries precisely.

Use cases (agar plates): - Low-contrast colonies with soft, gradual edges (translucent growth) - Dense plates where colonies blend into background - Pre-threshold sharpening to improve segmentation accuracy - Enhancing subtle colony morphologies before downstream measurement - Improving edge definition when scanner or lens causes slight blurring

Tuning and effects: - radius: Controls the scale of features enhanced. Small values (0.5–2) sharpen

fine details like small colony boundaries and surface texture; larger values (5–15+) enhance broader features and colony-background contrast. For fungal colonies, keep radius smaller than the minimum colony radius to avoid creating visible halos or merging adjacent colonies. Start at 2.0 for general-purpose enhancement.

  • amount: Determines the magnitude of edge enhancement (how much darker/brighter the edges become). Low values (0.3–0.7) produce subtle improvements safe for noisy images; standard values (1.0–1.5) give moderate sharpening suitable for most colony plates; high values (2.0+) create aggressive enhancement but risk amplifying noise and creating visible bright/dark halos around colonies. Negative amounts produce blur (opposite effect).

  • preserve_range: Leave as False for consistency with other enhancers in the framework.

Caveats: - Amplifies noise: In noisy images, unsharp masking sharpens both signal

(colony edges) and noise artifacts. Consider denoising first (e.g., with GaussianBlur, BilateralDenoise, or MedianFilter) on very grainy agar scans.

  • Halo artifacts: Excessive radius or amount creates bright/dark rims around colonies, which can be mistaken for separate objects or cause thresholding to fail.

  • Already-sharp images: Applying unsharp mask to crisp, high-contrast colonies may be redundant and introduce artifacts. Reserve for low-contrast scenarios.

Parameters:
radius#

Standard deviation of Gaussian blur used to compute edges, in pixels. Controls the scale of features enhanced.

Type:

float

amount#

Multiplier for the sharpening effect. Controls intensity of edge enhancement.

Type:

float

preserve_range#

Whether to keep the original range of pixel values (False by default).

Type:

bool

Examples

Sharpening low-contrast fungal colonies before detection
from phenotypic import Image
from phenotypic.enhance import UnsharpMask
from phenotypic.detect import OtsuDetector

# Load image of low-contrast plate (e.g., translucent yeasts)
image = Image.from_image_path("yeast_plate.jpg")

# Apply unsharp masking with moderate settings
sharpener = UnsharpMask(radius=2.0, amount=1.2)
sharpened = sharpener.apply(image)

# Detect colonies in sharpened enhanced grayscale
detector = OtsuDetector()
detected = detector.apply(sharpened)

# Original image untouched, detection on enhanced data
colonies = detected.objects
print(f"Detected {len(colonies)} colonies")
Tuning radius and amount for dense high-throughput plates
from phenotypic import Image, ImagePipeline
from phenotypic.enhance import UnsharpMask, GaussianBlur
from phenotypic.detect import OtsuDetector

# For high-resolution 384-well plate scans with tiny colonies,
# use small radius to avoid merging adjacent growth

pipeline = ImagePipeline()

# Step 1: Light blur to reduce scanner noise
pipeline.add(GaussianBlur(sigma=1))

# Step 2: Enhance edges with small radius for dense plates
# radius=1.0 emphasizes only fine features (individual colonies)
pipeline.add(UnsharpMask(radius=1.0, amount=1.5))

# Step 3: Detect in enhanced grayscale
pipeline.add(OtsuDetector())

# Process a batch of images
images = [Image.from_image_path(f) for f in image_paths]
results = pipeline.operate(images)

for i, result in enumerate(results):
    print(f"Plate {i}: {len(result.objects)} colonies")
Aggressive sharpening for very translucent colonies
from phenotypic import Image
from phenotypic.enhance import UnsharpMask

# For extremely low-contrast colonies (e.g., slow-growing mutants,
# low-turbidity liquid culture plates), use higher amount

image = Image.from_image_path("faint_colonies.jpg")

# Aggressive parameters: larger radius for broader features,
# higher amount for stronger enhancement
aggressive_sharpener = UnsharpMask(radius=5.0, amount=2.5)
enhanced = aggressive_sharpener.apply(image)

# Inspect result for artifacts (halos); adjust if needed
# If halos appear, reduce amount to 1.5–2.0
print("Sharpening applied. Check for halo artifacts around large colonies.")

Methods

__init__

apply

Applies the operation to an image, either in-place or on a copy.

dispose_widgets

Drop references to the UI widgets.

sync_widgets_from_state

Push internal state into widgets.

widget

Return (and optionally display) the root widget.

__init__(radius: float = 2.0, amount: float = 1.0, preserve_range: bool = False)[source]#
Parameters:
  • radius (float) – Standard deviation (sigma) of the Gaussian blur in pixels. Defines the scale of features to enhance. Small values (0.5–2) sharpen fine details (thin colony edges, small morphologies); larger values (5–15) enhance broad features (large colonies, colony-background separation). Must be > 0. For fungal colonies, keep below the typical colony radius to avoid merging adjacent colonies. Recommended: 2.0–3.0 for general-purpose use, 1.0 for high-density plates, 5.0+ for emphasizing large-scale features on low-resolution images.

  • amount (float) – Amplification factor for the sharpening effect. Controls how much the edge enhancement contributes to the output. Typical range: 0.3–2.5. Low values (0.3–0.7) produce subtle enhancement suitable for noisy images; standard values (1.0–1.5) give balanced sharpening; high values (2.0+) create aggressive enhancement for very low-contrast colonies. Can be negative to produce blurring instead. Excessive amounts risk visible artifacts and noise amplification.

  • preserve_range (bool) – If False (default), output may be rescaled if necessary. If True, the original range of input values is preserved. Keep as False for consistency with other enhancers.

__del__()#

Automatically stop tracemalloc when the object is deleted.

__getstate__()#

Prepare the object for pickling by disposing of any widgets.

This ensures that UI components (which may contain unpickleable objects like input functions or thread locks) are cleaned up before serialization.

Note

This method modifies the object state by calling dispose_widgets(). Any active widgets will be detached from the object.

apply(image, inplace=False)#

Applies the operation to an image, either in-place or on a copy.

Parameters:
  • image (Image) – The arr image to apply the operation on.

  • inplace (bool) – If True, modifies the image in place; otherwise, operates on a copy of the image.

Returns:

The modified image after applying the operation.

Return type:

Image

dispose_widgets() None#

Drop references to the UI widgets.

Return type:

None

sync_widgets_from_state() None#

Push internal state into widgets.

Return type:

None

widget(image: Image | None = None, show: bool = False) Widget#

Return (and optionally display) the root widget.

Parameters:
  • image (Image | None) – Optional image to visualize. If provided, visualization controls will be added to the widget.

  • show (bool) – Whether to display the widget immediately. Defaults to False.

Returns:

The root widget.

Return type:

ipywidgets.Widget

Raises:

ImportError – If ipywidgets or IPython are not installed.