Détection des oeufs dans un nid de poule

Le poulailler connecté eggs-iting devra pouvoir compter avec exactitude le nombre d'oeufs en direct dans les nids. Cette information est au coeur des applications à venir sur eggs-iting.

Conditions matérielles

Une des fonctionnalités essentielles du poulailler connecté eggs-iting est la notification du propriétaire lorsqu’un nouvel oeuf est pondu. Nous avons retenu un système de détection à partir d’une caméra basse résolution (type webcam) positionnée à l'aplomb des nids.

Les nids, placés à l’intérieur du poulailler, ne bénéficient pas d’un éclairage naturel constant, c’est pourquoi une source d’éclairage à LED permet d’illuminer la scène à photographier. La puissance et la durée d’éclairage ne doivent pas nuire au confort des animaux, ni entraîner une consommation d’énergie excessive.

L’ensemble du poulailler est piloté par un Raspberry pi tournant sous Debian Jessie Lite. La caméra est connectée directement au port USB. L’éclairage est piloté par les sorties GPIO de la carte dont les sorties logiques sont reprises par des transistors de puissance.

Résolution de la caméra 640 x 480
Puissance de l’éclairage à LED 0.2A sous 5V / 1W
Durée d’allumage des leds 5 secondes
Largeur du nid 22 cm
Profondeur du nid 30 cm
Hauteur du nid 40 cm

Caractérisation d'un oeuf

Un nid peut accueillir jusqu’à une douzaine d’oeufs, de tailles, de couleurs et de formes sensiblement identiques. Aucune de ces caractéristiques n’est cependant suffisamment stable pour être recherchée systématiquement.

Ci contre, deux oeufs de tailles et de couleurs différentes.

Approche par couleur

La couleur d’un oeuf pourra varier en fonction de plusieurs facteurs biologiques (espèce, alimentation, état de santé de la poule), et pourra être rendue aléatoirement par la caméra. Les capteurs grand public et l’électronique qui les accompagne procèdent en effet à des étalonnages automatiques (exposition, balance des blancs) sur la globalité de la scène. L’approche de repérage selon la couleur a donc rapidement été éliminée.

Approche par surface

De la paille, du foin, des plumes ou des salissures peuvent recouvrir partiellement les oeufs, interdisant le repérage de surfaces homogènes. Une première approche par détection de blobs avait été tentée.

A partir d'une version en niveau de gris, une détection des contours (type Laplace) est appliquée, puis une dilatation permet d'éliminer la majorité du bruit (comme les brins de paille). Un seuil est enfin appliqué pour isoler les zones "unies".

Tentative de détection de blobs

On constate que les brins de paille viennent "couper" les oeuf en plusieurs zones. Il est difficile, a-posteriori, de rassembler ces zones et de les associer à leur objet d'origine.

A partir de la surface moyenne d'un oeuf, on pourrait cependant calculer un nombre d'oeufs approximatif, sans s'occuper de la forme ou de la position des zones detectées.

Approche par géométrie

Un oeuf peut également être partiellement caché par un autre, s’il est positionné à son contact immédiat. Il peut par ailleurs se tenir debout, ou sur le côté.

La détection géométrique (transformée de Hough appliquée aux cercles) est donc relativement onéreuse, puisqu’elle doit rechercher des ellipses potentiellement incomplètes et orientées arbitrairement.

Approche par gradient

Outre la forme et la couleur des oeufs, leur caractère sphérique peut être exploité. Puisqu’on dispose d’une source lumineuse fixe, et que les oeufs sont par essence ovoïdes, on peut parier sur une diffusion régulière de la lumière d’un oeuf à l’autre.

En mesurant les gradients entre chaque pixel et ses voisins, on devrait pouvoir observer un pattern identifiable.

Les Local Binary Patterns (motifs binaires locaux) ont été définis avec comme objectif de pouvoir repérer des motifs répétitifs dans une image. Principalement utilisés pour détecter et reconnaître des textures, ils peuvent être exploités localement pour reconnaître des contours, des coins, ou des formes.

Méthode de calcul des LBP

Pour calculer la “dérivée LBP” d’une image, on procède de la manière suivante :

  • Pour chaque pixel p de l’image disposant de 8 voisins
  • Soit une valeur LBP sur 8 bits numérotés b0 à b7
  • Pour chacun des 8 voisins v (0 à 7) du pixel considéré, dans le sens horaire
  • Calculer la différence d’intensité entre ce voisin v et le pixel p
  • Si la différence est positive, mettre le bit correspondant de LBP à 1
  • Sinon mettre le bit correspondant de LBP à 0

Exemple de convolution Local Binary Pattern

De gauche à droite :

  • Image originale
  • Image en niveaux de gris
  • dérivée LBP

Comment exploiter les LBP

Après des tests sur une centaine d’images, on remarque que les oeufs, une fois "dérivés", présentent tous à peu près la même distribution de valeurs. On va exploiter cette caractéristique à partir d’histogrammes locaux sur un jeu d’images de référence.

Pour réaliser le training, on sélectionne une douzaine d’images de référence, recadrées au plus proche des objets à rechercher.

On calcule la LBP de chaque image du training, puis on extrait un histogramme local normalisé pour chacun des 4 quadrants (histA, histB, histC, histD) de l’image.

Une fois les 12 images traitées, on calcule la moyenne des histogrammes pour chacun des 4 coins. On obtient 4 histogrammes normalisés (avgA, avgB, avgC, avgD), qui présentent la distribution moyenne des valeurs pour chacun des 4 coins de l’image recherchée.

Recherche d’objets dans une image

On dérive l’image, puis on la parcourt à l’aide d’une fenêtre dont la taille est proche des objets à rechercher. Les dimensions de la fenêtre doivent être divisibles par 2.

On extrait les 4 histogrammes (roiA, roiB, roiC, roiD) de cette fenêtre, et on les compare aux histogrammes moyens (avgA, avgB, avgC, avgD). Le score obtenu est stocké dans une matrice de mêmes dimensions que l’image analysée.

Puisqu’on compare des histogrammes normalisés, le nombre de pixels utilisés pour le training ou l’analyse n’a pas d’importance, c’est bien la distribution des valeurs qui est comparée, pas les valeurs elles-mêmes.

La différence entre 2 histogrammes est obtenue à partir de la méthode Chi-square. Soit deux histogrammes A et B, on calcule la différence delta entre les deux de la manière suivante :

delta = somme( (a-b)² / (a+b) )

On considérera deux histogrammes “proches” si le delta obtenu est inférieur à un seuil S choisi. Le score de la fenêtre observée est le nombre de coins qui présentent une delta inférieur à S.

Le nombre et la position des objets détectés est obtenu en isolant les scores maximums.

Ilustration de l'analyse d'une image

Calcul des scores avec un seuil d'acceptation de 160

Zone deltaA deltaB deltaC deltaD Score
ROI 1 450 524 496 536 0
ROI 2 142 121 92 102 4
ROI 3 217 105 148 154 3

 

  • La zone 1 obtient un score nul car aucun des quadrants de l'image ne présente un histogramme proche de celui réalisé lors du training.
  • La zone 2 obtient le score maximal de 4 car les histogrammes des 4 quadrants sont suffisament proches.
  • La zone 3 otient un score de 3 car l'histogramme du coin supérieur gauche n'est pas retenu. (à cause de l'oeuf de gauche qui empiète sur ce quadrant)

Tests et résultats

Sur un jeu de test de 100 images, faisant figurer 0, 1, 2, 3 ou 4 oeufs (avec un total de 200 oeufs), cette méthode a permis d'atteindre un score de 100% de réussite.