Détection de taches#

Cet exemple illustre les techniques de détection de taches disponibles dans Sigima pour analyser des structures circulaires ou en amas dans des images. Il montre comment générer des filtres de prétraitement et détecter des taches à l’aide d’algorithmes basés sur OpenCV, avec des paramètres ajustés pour obtenir des résultats optimaux.

Le script présente des chaînes de traitement d’image couramment utilisées en microscopie, en analyse de particules et dans les applications de détection de caractéristiques.

On importe les modules nécessaires#

On commence par importer tous les modules nécessaires au traitement d’image et à la visualisation. Pour exécuter cet exemple, on vérifie que l’ensemble des dépendances requises est installé.

import numpy as np
import skimage.draw

import sigima.objects
import sigima.proc.image
from sigima import viz

Générer une image de test synthétique avec des taches connues#

On crée une image synthétique avec un bruit de fond et plusieurs taches circulaires de tailles et d’intensités variées. Cette configuration permet de valider efficacement les algorithmes de détection de taches. Pour réaliser cette tâche, on utilise une fonction dédiée dont les détails dépassent le cadre de ce tutoriel ; une fois que vous maîtriserez Sigima, vous pourrez appliquer la bibliothèque à vos propres données.

def generate_test_image() -> None:
    """Generate test image with randomly placed blobs."""
    rng = np.random.default_rng(0)
    arr = rng.normal(10000, 1000, (2048, 2048))
    for _ in range(10):
        row = rng.integers(0, arr.shape[0])
        col = rng.integers(0, arr.shape[1])
        rr, cc = skimage.draw.disk((row, col), 40, shape=arr.shape)
        arr[rr, cc] -= rng.integers(5000, 6000)
    icenter = arr.shape[0] // 2
    rr, cc = skimage.draw.disk((icenter, icenter), 200, shape=arr.shape)
    arr[rr, cc] -= rng.integers(5000, 8000)
    data = np.clip(arr, 0, 65535).astype(np.uint16)

    # Create a new image object
    image = sigima.objects.create_image("Test image", data, units=("mm", "mm", "lsb"))
    return image


original_image = generate_test_image()

print("✓ Test image created successfully!")
✓ Test image created successfully!

Visualiser l’image originale#

On visualise l’image synthétique originale pour en apprécier les caractéristiques avant tout traitement ou détection de blobs. On peut utiliser la visionneuse d’images de son choix (par exemple plotpy, matplotlib, …). Les développeurs de Sigima privilégient plotpy, une bibliothèque conçue pour la performance.

On a encapsulé une fonction simple pour réaliser les visualisations nécessaires à ce tutoriel et aux autres, afin de limiter l’impact du code lié à l’interface graphique dans la documentation et de vous laisser vous concentrer sur l’analyse.

viz.view_images([original_image], title="Original Test Image with Synthetic Blobs")
Qt widget 1

Prétraitement d’image - binning#

Observez l’image : les taches recherchées sont grandes par rapport à la taille des pixels. Un binning aide à réduire l’importance du bruit.

binning_factor = 2
binned_image = sigima.proc.image.binning(original_image, binning_factor)

print(f"\n✓ Binning applied with factor {binning_factor}")
print(f"Original size: {original_image.data.shape}")
print(f"Binned size: {binned_image.data.shape}")
print("Binning reduces computational load and can improve blob detection")

# Compare original and binned images
viz.view_images_side_by_side(
    [original_image, binned_image],
    titles=["Original Image", "Binned Image (2x2)"],
    title="Image Binning Comparison",
)
Qt widget 1
✓ Binning applied with factor 2
Original size: (2048, 2048)
Binned size: (1024, 1024)
Binning reduces computational load and can improve blob detection

Prétraitement supplémentaire - filtre médian glissant#

Le résultat du binning est satisfaisant, mais il est possible de vouloir aller plus loin. On applique alors un filtre médian glissant pour atténuer les pics. On utilise ici une fenêtre de 5 ; en pratique, on teste différentes tailles de fenêtre pour trouver le bon compromis entre réduction du bruit et résolution. Voyons comment procéder.

filter_size = 5
filtered_image = sigima.proc.image.moving_median(binned_image, n=filter_size)

print(f"\n✓ Moving median filter applied (window size: {filter_size})")

# Show progression of preprocessing steps
viz.view_images_side_by_side(
    [original_image, binned_image, filtered_image],
    titles=["Original", "Binned", "Median Filtered"],
    title="Image Preprocessing Pipeline",
)
Qt widget 1
✓ Moving median filter applied (window size: 5)

Configurer les paramètres de détection de taches#

On valide l’image filtrée et on passe à la détection de taches. On commence par configurer les paramètres de l’algorithme de détection, étape essentielle pour obtenir de bons résultats. Cet exemple offre une vue d’ensemble des paramètres ajustables.

Créer l’objet de paramètres de détection de taches :

Paramètres de seuil pour la détection de taches :

Répétabilité minimale (nombre de fois où le centre d’une tache est détecté) :

Filtrage sur la couleur (non utilisé en niveaux de gris) :

Filtrage sur la surface pour sélectionner les tailles de taches adaptées :

blob_param.filter_by_area = True
blob_param.min_area = 600.0  # Minimum area in pixels
blob_param.max_area = 6000.0  # Maximum area in pixels

Filtrage sur la circularité pour privilégier les objets ronds :

blob_param.filter_by_circularity = True
blob_param.min_circularity = 0.8  # 0 = not circular, 1 = perfect circle
blob_param.max_circularity = 1.0

Désactiver le filtrage sur l’inertie et la convexité pour cet exemple :

On affiche enfin les paramètres configurés :

print("\n✓ Blob detection parameters configured:" + "\n")
print(blob_param)
✓ Blob detection parameters configured:

Blob detection using OpenCV:
    _roi_g:
      Create regions of interest: ☐
      ROI geometry: Rectangle
    Min. threshold: 10.0
    Max. threshold: 200.0
    Min. repeatability: 2
    Min. distance between blobs: 10.0
    Filter by color: ☐
    Blob color: 0
    Filter by area: ☑
    Min. area: 600.0
    Max. area: 6000.0
    Filter by circularity: ☑
    Min. circularity: 0.8
    Max. circularity: 1.0
    Filter by inertia: ☐
    Min. inertia ratio: 0.6
    Max. inertia ratio: 1.0
    Filter by convexity: ☐
    Min. convexity: 0.8
    Max. convexity: 1.0

Exécuter la détection de taches#

On peut maintenant lancer la détection de taches sur l’image prétraitée avec les paramètres configurés.

# Detect blobs in the preprocessed image
blobs = sigima.proc.image.blob_opencv(filtered_image, blob_param)

print("\n✓ Blob detection completed!")
print(f"  Number of blobs detected: {len(blobs.coords) if blobs else 0}")

viz.view_images(
    [filtered_image],
    title="Filtered Image with Blob Detection",
    results=blobs,
    colormap="gray",
)
Qt widget 1
✓ Blob detection completed!
  Number of blobs detected: 8

On affiche les taches détectées et leurs propriétés :

if blobs and len(blobs.coords) > 0:
    blobs_df = blobs.to_dataframe()
    print("\nDetected blobs data frame:")
    print(blobs_df)

else:
    print("No blobs detected. Consider adjusting detection parameters.")
Detected blobs data frame:
   roi_index            x            y          r
0         -1  1929.505005  1629.516724  40.535240
1         -1  1550.487915  1070.406860  40.601971
2         -1  1444.442627   626.465759  40.596977
3         -1   197.523972   320.457184  40.515938
4         -1   749.518250   159.622253  40.518841
5         -1   368.359985   520.453979  40.556187
6         -1  1456.451782   227.557236  40.577053
7         -1   682.408081  1821.558105  40.533581

Galerie générée par Sphinx-Gallery