Note
Aller à la fin pour télécharger le code complet de l’exemple.
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")
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",
)
✓ 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",
)
✓ 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 :
blob_param = sigima.proc.image.BlobOpenCVParam()
Paramètres de seuil pour la détection de taches :
blob_param.min_threshold = 10
blob_param.max_threshold = 200
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) :
blob_param.filter_by_color = False
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 :
blob_param.filter_by_inertia = False
blob_param.filter_by_convexity = False
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",
)
✓ 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