Ich beschäftige mich gerade mit der Bildverarbeitung in Python über PIL (Python Image Library). Mein Hauptziel ist es, die Anzahl der gefärbten Zellen in einem immunhistochemischen Bild zu zählen. Ich weiß, dass es relevante Programme, Bibliotheken, Funktionen und Tutorials gibt, und ich habe fast alle überprüft. Mein Hauptziel ist es, den Code so weit wie möglich manuell von Grund auf neu zu schreiben. Daher versuche ich, viele externe Bibliotheken und Funktionen zu vermeiden. Ich habe den größten Teil des Programms geschrieben. Also hier ist, was Schritt für Schritt vor sich geht:
Programm nimmt die Bilddatei auf:
Und verarbeitet es für die roten Zellen (im Grunde werden die RGB-Werte unter einem bestimmten Schwellenwert für Rot deaktiviert):
Und erstellt die boolesche Karte davon (ich werde einen Teil davon einfügen, da es groß ist), die im Grunde genommen nur 1 setzt, wo immer es auf ein rotes Pixel im verarbeiteten zweiten Bild oben stößt.
22222222222222222222222222222222222222222
20000000111111110000000000000000000000002
20000000111111110000000000000000000000002
20000000111111110000000000000000000000002
20000000011111100000000000000000001100002
20000000001111100000000000000000011111002
20000000000110000000000000000000011111002
20000000000000000000000000000000111111002
20000000000000000000000000000000111111102
20000000000000000000000000000001111111102
20000000000000000000000000000001111111102
20000000000000000000000000000000111111002
20000000000000000000000000000000010000002
20000000000000000000000000000000000000002
22222222222222222222222222222222222222222
Ich habe dieses rahmenartige Element absichtlich an den Rändern mit 2 generiert, um die Anzahl der Einergruppen in dieser booleschen Karte zu ermitteln.
Meine Frage an euch ist, wie kommt es, dass ich die Anzahl der Zellen (Einergruppen) in einer solchen booleschen Karte effizient zählen kann? Ich habe http://en.wikipedia.org/wiki/Connected-component_labeling gefunden, das sehr ähnlich und ähnlich aussieht, aber soweit ich das sehe, liegt es auf Pixelebene. Meins ist auf der booleschen Ebene. Nur 1s und 0s.
Danke vielmals.
Antworten:
Etwas wie ein Brute-Force-Ansatz, aber durch Invertieren des Problems, um über Sammlungen von Pixeln zu indizieren, um Regionen zu finden, anstatt über das Array zu rastern.
Drucke:
quelle
Scipy
gibt, die wahrscheinlich auch schneller ist ^^ 'Aber wahrscheinlich trotzdem eine gute Übung und es zeigt, wie man das im Allgemeinen macht. Ich werde dann abstimmen.Sie können verwenden
ndimage.label
, was eine schöne Möglichkeit ist, dies zu tun. Es wird ein neues Array zurückgegeben, wobei jedes Feature einen eindeutigen Wert und die Anzahl der Features hat. Sie können auch ein Verbindungselement angeben.quelle
Hier ist ein Algorithmus, der 0 ist (Gesamtzahl der Pixel + Anzahl der Zellenpixel). Wir scannen das Bild einfach nach Zellpixeln und wenn wir eines finden, füllen wir die Zelle mit einer Flut, um es zu löschen.
Implementierung in Common Lisp, aber Sie können es trivial in Python übersetzen.
quelle
Mehr ein erweiterter Kommentar als eine Antwort:
Wie @interjay angedeutet hat, nehmen in einem Binärbild, dh einem Bild, in dem nur 2 Farben vorhanden sind, die Pixel den Wert 1 oder 0 an. Dies kann in dem von Ihnen verwendeten Bilddarstellungsformat wahr sein oder nicht, ist aber wahr in der "konzeptuellen" Darstellung Ihres Bildes; Lassen Sie sich in diesem Punkt nicht von Implementierungsdetails verwirren. Eine dieser Implementierungsdetails ist die Verwendung von 2s um den Bildrand - eine absolut sinnvolle Methode, um die tote Zone um das Bild herum zu identifizieren, ohne die Binärheit des Bildes qualitativ zu beeinflussen.
Zur Untersuchung der Pixel N, NE, NW und W: Dies hängt mit der Konnektivität der Pixel bei der Bildung der Komponente zusammen. Jedes Pixel (abgesehen von den Rand-Sonderfällen) hat 8 Nachbarn (N, S, E, W, NE, NW, SE, SW). Welche sind jedoch Kandidaten für die Aufnahme in dieselbe Komponente? Manchmal werden Komponenten, die sich nur an Ecken treffen (NE, NW, SE, SW), nicht als verbunden angesehen, manchmal sind sie es.
Sie müssen entscheiden, was für Ihre Anwendung geeignet ist. Ich schlage vor, Sie arbeiten einige Operationen des sequentiellen Algorithmus von Hand aus, indem Sie für jedes Pixel verschiedene Nachbarn überprüfen, um ein Gefühl dafür zu bekommen, was vor sich geht.
quelle