Hallo zusammen,
wer mikroskopiert wird regelmäßig in der Situation sein, daß er oder sie eine hinreichend große (>=20) Sporen eines Pilzes vermessen muß. Deshalb ist es hilfreich, wenn man dafür einen möglichst effizienten Arbeitsablauf hat. Ich hatte mich zu diesem Thema die Tage mit Vitus Schäfftlein ausgetauscht und dabei meinen Workflow noch etwas optimiert und möchte aus diesem Grund hier einmal vorstellen, wie ich Sporen mit Fiji/ImageJ und einem kleinen Python-Script vermesse. Ich selber nutze auf meinem Rechner Linux als Betriebssystem, aber im Prinzip funktioniert alles (mit entsprechenden Anpassungen) auch unter Windows oder MacOS, da Fiji/ImageJ ein Java-basiertes Programm ist.
Zunächst einmal muß man Fiji/ImageJ installieren. Die entsprechenden Downloads gibt es hier. Des weiteren benötigen wir die Erweiterung Microscopic Measurement Tools, die man hier herunterladen kann. Dort ist dann auch erklärt, in welchen Ordner von Fiji man die Erweiterung stecken muß, wie man seine Meßskala kalibiert und dauerhaft abspeichert. Wenn das alles geschafft ist, startet man Fiji und öffnet ein zu vermessendes Bild.
Nun kann man das Tool zum Ziehen von geraden Linien auswählen und damit eine gerade Linie von der Sporenspitze zur Sporenbasis ziehen. Anschließend drückt man 't' und erzeugt auf diese Weise eine sogenannte "Region of Interest" ROI, die im sich öffnenden ROI Manager angezeigt wird. Dann zieht man eine Linie über die Sporenbreite, drückt wieder 't' und hat eine weitere ROI erzeugt. Das wiederholt man dann Sporen für Spore, wobei man im ROI Manager die Option "Show All" aktivieren kann, damit man die bereits gezogenen Linien dauerhaft angezeigt bekommt. Nach einiger Zeit sieht das Ganze dann so aus
Jetzt wählt man unter Analyze > Microscope Measurement Tools > Choose Microscope Calibration die entsprechende Umrechnung von Pixeln in Mikrometern aus. Um diesen Schritt möglichst effektiv zu gestalten, kann man sich natürlich eine Tastenkombination für das Aufrufen dieses Fensters definieren.
Anschließend wählt man im ROI Manager alle bisher gezogenen Linien aus (einfach mit der Maus auf eine ROI im ROI Manager klicken und dann Strg+A drücken) und wählt dann im ROI Manager "Measure" aus. Es öffnet sich ein neues Fenster, das dann u.a. die Länge der gemessenen Linien in µm zeigt. Falls dort nicht nur Winkel und Länge, sondern auch noch andere Größen angezeigt werden, die man eigentlich gar nicht braucht, kann man bei Analyse > Set Measurements seine Einstellungen entsprechend so anpassen:
Das Ergebnis der Messung sieht dann am Ende so aus
Jetzt möchten wir natürlich Mittelwert, Standardabweichung sowie Minimal- und Maximalwerte von Sporenlänge, Sporenbreite und Länge-Breite-Verhältnis bestimmen. Dafür gibt es zwei Möglichkeiten. Entweder wir speichern unsere Meßergebnisse über File > Save as (Strg+S) in eine Datei, oder wir markieren wieder mit Strg+A alle Inhalte unserer Meßtabelle und kopieren sie mit Strg+C in die Zwischenablage. Im Folgenden stelle ich erstmal diesen zweiten Weg vor. Der Inhalt der Zwischenablage kann nun mit folgendem Python-Script entsprechend bearbeitet werden.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import numpy as np
from sys import stdin
i=0
last_column_even=[]
last_column_odd=[]
for line in stdin:
if line=='\n':
break
i=i+1
parts=line.split()
value=float(parts[-1])
if i % 2 == 0:
last_column_even.append(value)
else:
last_column_odd.append(value)
print(f"")
print(f"")
print(f"")
print(f" # | Länge (µm) | Breite (µm) | Q |")
print(f"---|------------|-------------|-----|")
q=[]
q=[a/b for a,b in zip(last_column_odd,last_column_even)]
for i,l_c in enumerate(last_column_odd):
print(f"{i+1:>2} | {last_column_odd[i]:>4.1f} | {last_column_even[i]:>4.1f} | {q[i]:.1f} |")
print(f"")
laenge=np.mean(last_column_odd)
laenge_std=np.std(last_column_odd)
breite=np.mean(last_column_even)
breite_std=np.std(last_column_even)
Q=np.mean(q)
Q_std=np.std(q)
laenge_min=np.min(last_column_odd)
laenge_max=np.max(last_column_odd)
breite_min=np.min(last_column_even)
breite_max=np.max(last_column_even)
Q_min=np.min(Q)
Q_max=np.max(Q)
print(f"Sporenmaße: {laenge:.1f}±{laenge_std:.1f} µm × {breite:.1f}±{breite_std:.1f} µm, Q={Q:.1f}±{Q_std:.1f}")
print(f" {laenge_min:.1f}-{laenge_max:.1f} µm × {breite_min:.1f}-{breite_max:.1f} µm, Q={Q_min:.1f}-{Q_max:.1f}")
with open("Sporenmaße.txt","w") as g:
print(f" | Länge (µm) | Breite (µm) | Q |",file=g)
print(f"---|------------|-------------|-----|",file=g)
for i,l_c in enumerate(last_column_odd):
print(f"{i+1:>2} | {last_column_odd[i]:>4.1f} | {last_column_even[i]:>4.1f} | {q[i]:.1f} |",file=g)
print(f"",file=g)
print(f"Sporenmaße: {laenge:.1f}±{laenge_std:.1f} µm × {breite:.1f}±{breite_std:.1f} µm, Q={Q:.1f}±{Q_std:.1f}",file=g)
print(f" {laenge_min:.1f}-{laenge_max:.1f} µm × {breite_min:.1f}-{breite_max:.1f} µm, Q={Q_min:.1f}-{Q_max:.1f}",file=g)
g.close()
Alles anzeigen
Konkret sieht das dann so aus. Man ruft in der Konsole das Script auf und kopiert dann mit Strg+Shift+C den Inhalt der Zwischenablage
Drückt man nun Enter, erscheint das Ergebnis
Das Ergebnis wird dann auch noch in eine Datei Sporenmaße.txt gespeichert. Hat man sich alternativ oben dafür entschieden, die Meßergebnisse in eine .csv-Datei zu speichern, kann man folgendes Script benutzen (der Speicherort der csv-Datei muß natürlich entsprechend angepaßt werden):
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import numpy as np
last_column_even=[]
last_column_odd=[]
print(f" | Länge (µm) | Breite (µm) | Q |")
print(f"---|------------|-------------|-----|")
with open('/directory/of/file/Results.csv','r') as f:
i=0
next(f)
for line in f:
i=i+1
parts=line.split(",")
value=float(parts[-1])
if i % 2 == 0:
last_column_even.append(value)
else:
last_column_odd.append(value)
q=[]
q=[a/b for a,b in zip(last_column_odd,last_column_even)]
for i,l_c in enumerate(last_column_odd):
print(f"{i+1:>2} | {last_column_odd[i]:>4.1f} | {last_column_even[i]:>4.1f} | {q[i]:.1f} |")
print(f"")
laenge=np.mean(last_column_odd)
laenge_std=np.std(last_column_odd)
breite=np.mean(last_column_even)
breite_std=np.std(last_column_even)
Q=np.mean(q)
Q_std=np.std(q)
laenge_min=np.min(last_column_odd)
laenge_max=np.max(last_column_odd)
breite_min=np.min(last_column_even)
breite_max=np.max(last_column_even)
Q_min=np.min(Q)
Q_max=np.max(Q)
print(f"Sporenmaße: {laenge:.1f}±{laenge_std:.1f} µm × {breite:.1f}±{breite_std:.1f} µm, Q={Q:.1f}±{Q_std:.1f}")
print(f" {laenge_min:.1f}-{laenge_max:.1f} µm × {breite_min:.1f}-{breite_max:.1f} µm, Q={Q_min:.1f}-{Q_max:.1f}")
with open("Sporenmaße.txt","w") as g:
print(f" | Länge (µm) | Breite (µm) | Q |",file=g)
print(f"---|------------|-------------|-----|",file=g)
for i,l_c in enumerate(last_column_odd):
print(f"{i+1:>2} | {last_column_odd[i]:>4.1f} | {last_column_even[i]:>4.1f} | {q[i]:.1f} |",file=g)
print(f"",file=g)
print(f"Sporenmaße: {laenge:.1f}±{laenge_std:.1f} µm × {breite:.1f}±{breite_std:.1f} µm, Q={Q:.1f}±{Q_std:.1f}",file=g)
print(f" {laenge_min:.1f}-{laenge_max:.1f} µm × {breite_min:.1f}-{breite_max:.1f} µm, Q={Q_min:.1f}-{Q_max:.1f}",file=g)
f.close()
g.close()
Alles anzeigen
Ruft man das Script dann auf, erhält man direkt das Ergebnis
welches auch wieder zusätzlich in eine Datei Sporenmaße.txt geschrieben wird.
Björn
