Je m'occupe actuellement d'un traitement d'image en Python via PIL (Python Image Library). Mon objectif principal est de compter le nombre de cellules colorées dans une image d'immunohistochimie. Je sais qu'il existe des programmes, des bibliothèques, des fonctions et des didacticiels pertinents à ce sujet, et j'ai vérifié presque tous. Mon objectif principal est d'écrire le code manuellement à partir de zéro, autant que possible. Par conséquent, j'essaie d'éviter d'utiliser de nombreuses bibliothèques et fonctions extérieures. J'ai écrit la plupart du programme. Voici donc ce qui se passe pas à pas:
Le programme prend le fichier image:
Et le traite pour les globules rouges (en gros, il désactive les valeurs RVB en dessous d'un certain seuil pour le rouge):
Et crée la carte booléenne de celui-ci (je vais en coller une partie car il est grand) qui met simplement 1 à chaque fois qu'il rencontre un pixel rouge dans la deuxième image traitée ci-dessus.
22222222222222222222222222222222222222222
20000000111111110000000000000000000000002
20000000111111110000000000000000000000002
20000000111111110000000000000000000000002
20000000011111100000000000000000001100002
20000000001111100000000000000000011111002
20000000000110000000000000000000011111002
20000000000000000000000000000000111111002
20000000000000000000000000000000111111102
20000000000000000000000000000001111111102
20000000000000000000000000000001111111102
20000000000000000000000000000000111111002
20000000000000000000000000000000010000002
20000000000000000000000000000000000000002
22222222222222222222222222222222222222222
J'ai intentionnellement généré ce trame comme une chose sur les bordures avec 2 pour m'aider à compter le nombre de groupes de 1 dans cette carte booléenne.
Ma question est la suivante: comment se fait-il que je puisse compter efficacement le nombre de cellules (groupes de 1) dans ce type de carte booléenne? J'ai trouvé http://en.wikipedia.org/wiki/Connected-component_labeling qui semble extrêmement apparenté et similaire, mais pour autant que je vois, c'est au niveau des pixels. Le mien est au niveau booléen. Juste 1 et 0.
Merci beaucoup.
Réponses:
Quelque chose d'une approche par force brute, mais réalisée en inversant le problème d'indexation sur des collections de pixels pour trouver des régions, au lieu de tramer sur le tableau.
Tirages:
la source
Scipy
faire, ce qui est probablement aussi plus rapide ^^ 'Mais probablement un bon exercice de toute façon et cela montre comment le faire en général. Je voterai alors.Vous pouvez utiliser
ndimage.label
, ce qui est une bonne façon de le faire. Il renvoie un nouveau tableau, chaque fonctionnalité ayant une valeur unique et le nombre de fonctionnalités. Vous pouvez également spécifier un élément de connexion.la source
Voici un algorithme qui est O (nombre total de pixels + nombre de pixels des cellules). Nous scannons simplement l'image pour les pixels des cellules, et lorsque nous en trouvons un, nous remplissons la cellule pour l'effacer.
Implémentation en Common Lisp, mais vous pourrez la traduire trivialement en Python.
la source
Plus un commentaire étendu qu'une réponse:
Comme @interjay l'a laissé entendre, dans une image binaire, c'est-à-dire dans laquelle seulement 2 couleurs sont présentes, les pixels prennent la valeur 1 ou 0. Cela peut ou peut ne pas être vrai dans le format de représentation d'image que vous utilisez, mais c'est vrai dans la représentation «conceptuelle» de votre image; ne laissez pas les détails de mise en œuvre vous dérouter sur ce problème. L'un de ces détails d'implémentation est votre utilisation de 2 autour de la bordure de l'image - un moyen parfaitement sensé d'identifier la zone morte autour de l'image, mais sans affecter qualitativement la binaire de l'image.
Quant à l'examen des pixels N, NE, NW et W: il s'agit de la connectivité des pixels dans la formation du composant. Chaque pixel (sauf les cas spéciaux de bordure) a 8 voisins (N, S, E, W, NE, NW, SE, SW) mais lesquels sont candidats à l'inclusion dans le même composant? Parfois, les composants qui ne se rencontrent qu'aux coins (NE, NW, SE, SW) ne sont pas considérés comme connectés, parfois ils le sont.
Vous devez décider de ce qui convient à votre candidature. Je vous suggère de travailler, à la main, quelques opérations de l'algorithme séquentiel, en vérifiant différents voisins pour chaque pixel, pour avoir une idée de ce qui se passe.
la source