Compter automatiquement des objets sur une photographie ou une micrographie avec Python : application aux oiseaux et aux levures

par Nicolas Marange

Résumé

Le comptage d’objets est une activité fréquente en sciences. En écologie, il peut s’agir de compter des oiseaux sur une photographie aérienne. En microbiologie, il peut s’agir de dénombrer des cellules de levure observées au microscope.

Ce comptage peut se faire à l’œil (long et fastidieux quand les éléments sont nombreux) ou être contourné. Une cellule de Malassez peut être utilisée pour les comptages d’hématies, d’euglènes…

Dans le cas de mise en culture de levure, par exemple, un luxmètre peut être utilisé pour mesurer l’intensité d’un faisceau lumineux après son passage à travers le bain de culture.

La luminosité décroît au fur et à mesure de l’augmentation de la population dans son milieu nutritif. Ce type de comptage reste imprécis.

 

 Le programme « Compter levure » repose sur des techniques simples de traitement d’image permettant d’automatiser cette tâche. Il transforme une image couleur en niveaux de gris, applique un seuil de luminosité pour isoler les objets, puis compte les éléments détectés grâce à un étiquetage des régions de l’image.

L’image fournie montre de nombreuses cellules de levure colorées en bleu. Ce type de cliché est particulièrement adapté à un comptage automatisé car les cellules se distinguent nettement du fond clair.

 

Introduction

Le comptage manuel d’objets sur une image peut être long, fastidieux et source d’erreurs. Lorsque le nombre d’éléments dépasse quelques dizaines, la fatigue visuelle augmente le risque d’oubli ou de double comptage.

Les logiciels d’analyse d’images permettent aujourd’hui d’automatiser cette opération grâce à des algorithmes simples :

  • lecture de l’image ;
  • transformation en niveaux de gris ;
  • séparation objet/fond par seuillage ;
  • identification des objets ;
  • comptage automatique.

Cette méthode peut être utilisée aussi bien pour :

  • compter des levures sur une micrographie ;
  • compter des colonies bactériennes ;
  • compter des graines ;
  • compter des oiseaux sur une photographie aérienne ;
  • estimer une population d’animaux visibles sur une image.

 

Principe :

1. Conversion en niveaux de gris

Une image couleur contient trois composantes (Rouge, Vert, Bleu).

Le programme convertit l’image en niveaux de gris afin de ne conserver qu’une information de luminosité.

Cette étape simplifie considérablement l’analyse.

2. Détermination d’un seuil

Le programme utilise la méthode d’Otsu pour proposer automatiquement une valeur seuil optimale.

Le principe est simple :

  • les pixels plus sombres que le seuil appartiennent aux objets ;
  • les pixels plus clairs appartiennent au fond.

On obtient alors une image binaire :

  • noir = objet ;
  • blanc = fond.

3. Étiquetage des objets

Après binarisation, le programme recherche les groupes de pixels connectés.

Chaque groupe correspond à une cellule de levure (ou à un oiseau dans une photographie aérienne).

L’algorithme attribue un numéro différent à chaque objet détecté.

Le nombre maximal d’étiquettes correspond alors au nombre total d’objets présents sur l’image.

 

Utilisation de « Compter levures »

  • Ouvrir un terminal sur votre PC sous Ubuntu. Rejoindre le dossier « compter-levures » contenant le programme « compteur.py » et les images à analyser.

  • Lancer l’ouverture de « compteur.py » par Python3.

  • Sélectionner l’image à traiter.

  • Indiquez le seuil de luminosité choisi (en général 0,75).
  • Une interface graphique fait apparaître les différentes étapes de traitement de l’image et le résultat de ce comptage.

L’image a été convertie en noir et blanc puis binarisée (chaque pixel blanc a pris la valeur 0 et chaque pixel noir a pris la valeur 1). L’ordinateur va considérer chaque « 1 » lié à un autre « 1 » comme un élément. Chaque pixel est entouré de 8 pixels et donc chaque « zéro » ou « un » est entouré de huit valeurs « 0 » ou « 1 ». La fonction employée dans le programme permet de ne considérer que les 4 pixels « cardinaux », (la précision sera alors de 50 %) ou les 8 pixels.

  • La fenêtre du Terminal affiche le seuil qu’elle pensait être optimal et le nombre d’éléments comptés.

 

Applications en SVT au collège

Étude des micro-organismes

Les élèves peuvent :

  • observer une préparation microscopique ;
  • prendre une photographie ;
  • estimer automatiquement le nombre de cellules.

Cette approche introduit les notions :

  • de population cellulaire ;
  • d’échantillonnage ;
  • de traitement numérique de l’information.

Étude de la biodiversité

Le même principe peut être appliqué à :

  • des oiseaux sur une photographie ;
  • des insectes dans un piège ;
  • des graines dispersées sur une surface.

L’ordinateur effectue alors un comptage rapide et reproductible.

 

Intérêt pédagogique

Gain de temps

Le comptage manuel de 100 à 300 objets peut prendre plusieurs minutes.

Avec un logiciel de traitement d’image :

  • le résultat est obtenu en quelques secondes ;
  • plusieurs essais peuvent être réalisés ;
  • les élèves peuvent se concentrer sur l’interprétation scientifique plutôt que sur le comptage lui-même.

Réduction des erreurs

Le logiciel :

  • évite les doubles comptages ;
  • réduit les oublis ;
  • améliore la reproductibilité des mesures.

Aide aux élèves dyscalculiques

Pour certains élèves présentant des difficultés de dénombrement ou de traitement numérique :

  • le comptage automatique supprime une tâche cognitivement coûteuse ;
  • l’élève peut se concentrer sur l’analyse biologique ;
  • la réussite de l’activité devient davantage liée à la compréhension scientifique qu’à la capacité à compter rapidement.

Cet outil constitue donc une aide inclusive particulièrement intéressante en SVT.

 

Code du programme « Compter levure » en Python 3

 

#!/usr/bin/env python

# Auteurs: Nicolas Marangé  &  Nicolas Cedilnik (https://www.nicoco.fr) 

# License: Domaine public

# on importe les bibliothèques dont on a besoin

# Librarie standard de python
# ===========================

# pour faire apparaître la boîte de dialogue «choisir un fichier»
from tkinter import filedialog, simpledialog
# dirname = avoir le nom du répertoire en ayant le nom complet d'un fichier 
from os.path import dirname
# pour joindre des noms de dossiers de la même manière sur tous les OS
from os.path import join

# Des modules trouvés ailleurs
# ============================

# la fonction pour lire une image
from skimage.io import imread
# la fonction pour convertir 
from skimage.color import rgb2gray
# pour compter les objets dans une image binaire
from skimage.measure import label
# pour estimer le seuil optimal de «découpage de l'image niveau de gris»
from skimage.filters import threshold_otsu
# pour afficher les images à l'écran à la fin
from matplotlib import pyplot as plt

def demander_seuil():
    reponse = simpledialog.askstring(
        "Choisir un seuil",
        "Seuil de luminosité (entre 0 et 1) ? ")
    reponse = reponse.replace(",", ".")
    try:
        reponse = float(reponse)
    except ValueError:  # Si autre chose qu'un nombre est rentré
        reponse = -1
    return reponse

# créer la boîte de dialogue de sélection de fichier
filename = filedialog.askopenfilename(initialdir=dirname(__file__),
                                      title="Select file",
                                      filetypes=[("jpeg files", "*.jpg")])
# ouvrir le fichier qu'on a sélectionné
color_image = imread(filename)
# convertir une image couleur en niveau de gris
greyscale_image = rgb2gray(color_image)
# trouver automatiquement le seuil optimal
best_threshold = threshold_otsu(greyscale_image)
print("À mon avis, il faut choisir", best_threshold)

# demander le seuil à l'utilisaur
threshold = demander_seuil()
while not (0 < threshold < 1) :
    print("Veuillez entrer une valeur entre 0 et 1 !")
    threshold = demander_seuil()
# convertir l'image niveau de gris en image binaire
binary_image = greyscale_image < threshold

label_image = label(binary_image)
n_cellules = label_image.max()
print("À mon avis, il y a", n_cellules , "cellules sur cette image.")

# afficher le résultat graphiquement
fig, axes = plt.subplots(2, 2)
axes = axes.ravel()
for ax, image, name, cmap in zip(axes,
                                 (color_image, greyscale_image,
                                  binary_image, label_image),
                                 ('Image de départ',
                                  'Niveau de gris',
                                  'Image binaire',
                                  'Image labellisée ({} cellules)'.format(n_cellules)),
                                 ((None, plt.cm.gray,
                                   None, None))):
    if cmap is not None:
        im = ax.imshow(image, cmap=cmap)
    else:
        im = ax.imshow(image)
    ax.set_title(name)
plt.tight_layout()
plt.show()

Commentaire ligne par ligne du programme

Ligne Explication
from tkinter import filedialog, simpledialog Ouvre des boîtes de dialogue graphiques.
from os.path import dirname Récupère le dossier contenant le programme.
from skimage.io import imread Lit une image.
from skimage.color import rgb2gray Convertit une image couleur en niveaux de gris.
from skimage.measure import label Numérote les objets détectés.
from skimage.filters import threshold_otsu Calcule automatiquement un seuil optimal.
from matplotlib import pyplot as plt Affiche les résultats graphiquement.
def demander_seuil(): Fonction demandant une valeur seuil à l’utilisateur.
askstring(…) Ouvre une boîte de saisie.
replace(« , », « . ») Accepte les virgules françaises.
float(reponse) Convertit le texte en nombre réel.
except ValueError Gère les erreurs de saisie.
askopenfilename(…) Permet de choisir une image.
imread(filename) Charge l’image en mémoire.
rgb2gray(…) Transforme l’image en niveaux de gris.
threshold_otsu(…) Propose automatiquement un seuil de séparation.
demander_seuil() Demande la valeur définitive à l’utilisateur.
while not (0 < threshold < 1) Vérifie que le seuil est valide.
binary_image = greyscale_image < threshold Crée une image noir/blanc.
label(binary_image) Attribue un numéro à chaque objet.
label_image.max() Donne le nombre total d’objets détectés.
plt.subplots(2,2) Crée une fenêtre contenant quatre images.
imshow(…) Affiche chaque image.
set_title(…) Ajoute un titre.
tight_layout() Organise correctement l’affichage.
show() Affiche la fenêtre graphique.

 

Conclusion

Le programme Compter levure constitue une excellente introduction au traitement numérique des images. Bien que conçu pour le comptage de cellules de levure, il peut être adapté à de nombreuses situations scientifiques, notamment le comptage d’oiseaux, de graines ou d’autres organismes visibles sur une photographie. Son utilisation en SVT permet un gain de temps important, améliore la fiabilité des mesures et facilite l’inclusion des élèves présentant des difficultés de dénombrement, notamment les élèves dyscalculiques.

 

Téléchargement

Télécharger le code en Python3

Aller au contenu principal