Python Tutorial 1

Werbung
Hochschule Bremerhaven
Medizinische Bildverarbeitung SS 17— MT-B 6
Eine sehr kurze Einführung in Python und SimpleITK
Teil 1
richard rascher-friesenhausen
[email protected]
Dies ist eine sehr, sehr kurze Einführung zu (I)Python und den Möglichkeiten, vermittels des
Moduls SimpleITK zwei- und dreidimensionale Grauwertbilder zu erzeugen und zu bearbeiten.
Python ist eine interpretierte objektorientierte Programmiersprache. D.h. insbesondere, dass
man sie direkt und ohne Übersetzer und Binder interaktiv verwenden kann. (Anders als bei
C++ oder Java.)
Ihr wird nachgesagt, eine leicht verständliche und erlernbare Syntax zu besitzen. Und es gibt
viele vorgefertigte Module, die einem eine Menge Programmierarbeit für spezielle Anwendungen abnehmen.
Python kann frei aus dem Internet heruntergeladen werden. Die in dieser Veranstaltung verwendete Distribution findet man bei www.anaconda.com mit allen hier verwendeten Modulen.
Die Programmiersprache ist gut dokumentiert und es findet sich jede Menge Hilfe zu Python
frei im Internet. Ich empfehle insbesondere das offizielle Python-Tutorial:
http://www.python.org/doc/current/tut/tut.html auf englisch.
Wir verwenden im weiteren die IPython Umgebung, weil wir dort auch interaktiv Grafiken
darstellen lassen können. Eine Alternative dazu ist die vollständigen Entwicklungsumgebungen
Spyder (enthält IPython als Python-Konsole im unteren rechten Fenster).
Die Bildverarbeitung wird mittels des Moduls SimpleITK durchgeführt. Informationen dazu
findet man unter
http://www.simpleitk.org/ auf englisch.
Das Modul gehört nicht zur Anaconda-Distribution und muss auf dem eigenen Rechner über
den Konsolen-Befehl
easy_install SimpleITK
nachinstalliert werden.
Um die Bilder einfach aus Python heraus mit SimpleITK darstellen zu können, wird auch
noch das Programm Fiji bzw. ImageJ benötigt, welches man frei unter
https://fiji.sc/ bzw. http://www.imagej.org
beziehen kann.
1 Erste Python Schritte
Rufen Sie IPython über das Windows-Startmenu auf. Suchen Sie dazu den Eintrag Anaconda in der Startleiste und wählen sie den Eintrag IPython aus. Damit starten Sie eine
kommandozeilenorientierte Entwicklungsumgebung für Python mit eingebauten Grafikfähigkeiten. Oder Sie verwenden das IPython Fenster in Spyder.
ImageTutorial 1
1
prof. dr. richard rascher-friesenhausen
Hochschule Bremerhaven
Medizinische Bildverarbeitung SS 17— MT-B 6
Es öffnet sich ein Fenster, in dem der Python Interpreter auf Eingaben wartet. Diese werden
hinter dem Prompt In [x]: eingetippt und mit der Eingabetaste abgeschlossen.
Python 3.5.1 |Anaconda 4.0.0 (64-bit)| (default, Feb 16 2016, 09:49:46) [MSC v.1900 64 bit (AMD64)]
Type "copyright", "credits" or "license" for more information.
IPython 4.1.2 – An enhanced Interactive Python.
?
-> Introduction and overview of IPython’s features.
%quickref -> Quick reference.
help
-> Python’s own help system.
object?
-> Details about ’object’, use ’object??’ for extra details.
In [1]:
Die IPython Umgebung kann man verlassen mittels
In [1]: exit
Ok, jetzt wieder die IPython Umgebung neu starten. Oder in Spyder im Menu Consoles eine
neue IPython-Konsole öffnen.
Und dann spielen wir einige einfache Berechnungen durch:
In [1]: 1+1
Out[1]: 2
In [2]: -42+27
Out[2]: -15
Python antwortet mit einer Ausgabe hinter dem Out[x]: Prompt und fordert zu neuen Eingaben auf.
In [3]: 1./2.
Out[3]: 0.5
Will man ‚schwierige‘ Mathematik rechnen, so benötigt man die üblichen mathematischen
Funktionen und Konstanten. Diese stellt einem das Modul pylab zusammen mit Grafikfunktionen direkt zur Verfügung. Deshalb importieren wir den vollständigen Inhalt von pylab
über
In [4]: from pylab import *
Dies ist zwar kein guter Python-Stil, aber für unsere Zwecke recht nützlich. Alternativ könnte
man auch
import numpy as np
import matplotlib.pyplot as plt
verwenden und den entsprechenden Befehlen ein np. bzw. plt. voranstellen.
ImageTutorial 1
2
prof. dr. richard rascher-friesenhausen
Hochschule Bremerhaven
Medizinische Bildverarbeitung SS 17— MT-B 6
An mathematischen Funktionen stehen zur Verfügung:
’acos’, ’asin’, ’atan’, ’atan2’, ’ceil’, ’cos’, ’cosh’, ’degrees’, ’e’,
’exp’, ’fabs’, ’floor’, ’fmod’, ’frexp’, ’hypot’, ’ldexp’, ’log’, ’log10’,
’modf’, ’pi’, ’pow’, ’radians’, ’sin’, ’sinh’, ’sqrt’, ’tan’, ’tanh’
Man kann bspw. jetzt Wurzeln ziehen oder trigonometrische Funktionen aufrufen:
In [5]: sqrt(4.)
Out[5]: 2.0
In [6]: 2.0**2
Out[6]: 4.0
Oben bedeutet ** das Potenzieren.
In [7]: for x in [0., pi/6., pi/4., pi/3., pi/2., pi]:
print(x, cos(x), sin(x))
0 1.0 0.0
0.523598775598 0.866025403784 0.5
0.785398163397 0.707106781187 0.707106781187
1.0471975512 0.5 0.866025403784
1.57079632679 6.12303176911e-017 1.0
3.14159265359 -1.0 1.22460635382e-016
Oben haben wir schon ein Beispiel für eine Python-Kontrollstruktur, nämlich die for Schleife.
Darüber hinaus wird auch mit einer Variablen gearbeitet, x.
Mit pylab und den eingebauten Vektorfunktionen würde man obige Schleife auch vermeiden
können, nämlich über
x = array([0., pi/6., pi/4., pi/3., pi/2., pi])
y1 = cos(x)
y2 = sin(x)
Die Funktionen werden elementweise auf den Vektor x angewendet.
Man kann Variablen anlegen durch Vergabe eines Namens und Zuweisung eines Wertes. Etwa
In [8]: x = 42
In [9]: x
Out[9]: 42
In [10]: y = 0.815
In [11]: y
Out[11]: 0.81499999999999995
ImageTutorial 1
3
prof. dr. richard rascher-friesenhausen
Hochschule Bremerhaven
Medizinische Bildverarbeitung SS 17— MT-B 6
In [12]: s = ’Hallo’
In [13]: s
Out[13]: ’Hallo’
Hier wurde den Variablen x, y und s eine ganze Zahl, ein Dezimalzahl und ein String zugewiesen und wieder abgefragt. Man kann insbesondere auch erkennen, dass manche Zahlen im
Binärsystem mit eingeschränkter Stellenzahl nicht exakt darstellbar sind.
Neben diesen einfachen Datentypen benötigen wir in Python noch sehr häufig den Typ der
Liste, bei dem die Elemente in eckigen Klammern eingefasst werden. Sollten in Liste nur
Zahlen vorkommen, auf denen später gerechnet wird, dann verwendet man array.
In [14]: l = [x, y, s]
In [15]: l[0]
Out[15]: 42
In [16]: l[1]
Out[16]: 0.81499999999999995
In [17]: l[2]
Out[17]: ’Hallo’
Es ist möglich, eigene Funktionen in Python zu definieren. Machen wir das mal vor für eine
Quadratfunktion:
In [18]: def quadrat(x):
...:
return x*x
...:
In [19]: quadrat(4)
Out[19]: 16
In [20]: y = quadrat(-1.2)
In [21]: y
Out[21]: 1.4399999999999999
In [22]: quadrat(’hi’)
––––––––––––––––––––––––––––––––––––
exceptions.TypeError
.....
TypeError: can’t multiply sequence by non-int
ImageTutorial 1
4
prof. dr. richard rascher-friesenhausen
Hochschule Bremerhaven
Medizinische Bildverarbeitung SS 17— MT-B 6
Oben steht die Definition der Funktion quadrat und einige Aufrufe dieser Funktion. Ein
Aufruf mit einem String geht schief!
2 Python Programdateien
Sobald man also jetzt ans Programmieren kommt, ist es sinnvoll, die Python-Befehle in eine
eigene Datei abzulegen. Verwenden Sie den Editor von Spyder, um die folgenden Befehlszeilen
einzugeben. (Aber jeder andere ASCII-Editor tut es auch.)
1 def quadrat(x):
2
return x*x
4 x = 12.0
5 y = quadrat(x)
6 z = quadrat(y)
8 print x, y, z
eins.py
Speichern Sie den Inhalt in einer Datei eins.py in Ihrem Heimatverzeichnis (bspw. unter dem
Verzeichnis c:~\mbv oder auf dem Desktop). Sie können nun dieses Skript ablaufen lassen,
indem Sie mit
In [23]: cd ~
in Ihr Heimatverzeichnis wechseln und dann mit
In [24]: run eins.py
das Skript starten. Wenn keine Fehler mehr vorhanden sind, bekommen Sie den Ausdruck
12.0 144.0 20736.0
In Spyder können Sie aus dem Editor heraus mit F5 ebenfalls das Skript starten.
3 Das SimpleITK Modul
In Python gibt es verschiedene Bibliotheken, die auf Bildern arbeiten PIL, scikit-image,
openCV, . . .
Für die medizinische Bildverarbeitung existiert mit ITK (Insight Segmentation and Registration Toolkit) eine große Sammlung von Algorithmen, die nativ in C++ codiert sind. Viele Teile
davon sind auch für Python verfügbar und können mit dem Modul itk in ein Pythonprogramm importiert werden. Als einfacheres Interface zu ITK wurde für Python das Modul
SimpleITK geschrieben, welches wir im Weiteren verwenden werden.
ImageTutorial 1
5
prof. dr. richard rascher-friesenhausen
Hochschule Bremerhaven
Medizinische Bildverarbeitung SS 17— MT-B 6
SimpleITK ist nicht in der Anaconda-Distribution von Python enthalten und muß nachinstalliert werden (siehe erste Seite).
SimpleITK kann 2D- und 3D-Bilder pixelweise bearbeiten und bietet eine große Menge ausgefeilter Algorithmen der medizinischen Bildverarbeitung an. Es fehlt leider eine eingebaute
Darstellungsmöglichkeit für die Bilder. Stattdessen wird das externe Programm ImageJ oder
Fiji dafür verwendet (siehe erste Seite).
Jedes Pythonprogramm, welches die SimpleITK-Objekte nutzen will, muss das Modul importieren über
import SimpleITK as sitk
Ein in einer Datei existierendes Bild kann in Python eingelesen werden über den Befehl
img = sitk.ReadImage(’clown.png’)
Dazu muss natürlich die Datei clown.png im aktuellen Arbeitsverzeichnis liegen. Man kann
nun das Bild (ein Objekt der Klasse sitk.Image) nach einigen seiner Eigenschaften befragen,
etwa die Dimension
print("Dimension:", img.GetDimension())
Dimension: 2
Es handelt sich also um ein 2D-Bild mit einer Breite und einer Höhe:
print("Width, Height:", img.GetWidth(), img.GetHeight())
Width, Height: 320 200
Wir haben es mit einem Bild mit 320 Spalten und 200 Zeilen zu tun. Die Spalten- und
Zeilenzählung beginnt bei 0! Eine ähnliche Ausgabe hätten wir auch mit dem Befehl
print("Size:", img.GetSize())
Size: (320, 200)
erhalten. Wir werden nun die ganze Spalte x = 42 des Bildes auf Weiß, also 255, setzen. Das
Bild wird koordinatenweise angesprochen, wobei die erste Koordinate, die x Koordinate, für
die Spalten steht und zweite Koordinate, die y Koordinate, für die Zeile. Der Programmcode
dazu verläuft nun wie folgt
x = 42
for y in range(img.GetHeight()):
img[x,y] = 255
Und danach kann man sich das neue Bild anschauen vermittels
sitk.Show(img)
Es öffnet sich ein ImageJ-Fenster, in dem unser Bild dargestellt wird.
ImageTutorial 1
6
prof. dr. richard rascher-friesenhausen
Hochschule Bremerhaven
Medizinische Bildverarbeitung SS 17— MT-B 6
Den Wert in einem Pixel erhalten wir über
print("img[10,23]=", img[10,23])
Damit ist es also möglich, existierende Bilder zu lesen, zu manipulieren und anzuschauen. Wir
können das Bild für spätere Analysen auch speichern:
sitk.WriteImage(img, ’myclown.png’)
Auf der Festplatte sollte sich jetzt im aktuellen Verzeichnis eine neue Datei myclown.png
befinden, in der das von uns veränderte Bild gespeichert ist.
Man kann auch eigene Bilder neu erzeugen.
Ein schwarzes Bild mit gegebener Breite w und Höhe h und dem Datentyp unsigned integer
8 bit (passt zu Grauwerten von 0 bis 255) kann wie folgt angelegt werden
w, h = 100, 80
Img = sitk.Image(w, h, sitk.sitkUInt8)
Und nun kann man über eine Doppelschleife über alle Pixel die Grauwerte setzen, die man
haben möchte
import random
for x in range(Img.GetWidth()):
for y in range(Img.GetHeight()):
Img[x,y] = random.randint(0, 255)
sitk.WriteImage(Img, ’random.png’)
Ok, das soll für die ersten Schritte mit SimpleITK erst einmal reichen.
ImageTutorial 1
7
prof. dr. richard rascher-friesenhausen
Hochschule Bremerhaven
Medizinische Bildverarbeitung SS 17— MT-B 6
Einladen des Moduls SimpleITK
import SimpleITK as sitk
Erzeugen eines sitk.Image Objektes aus einer Bilddatei:
img = sitk.ReadImage(dateiname)
dateiname: Name einer existierenden Bilddatei, String
Erzeugen eines sitk.Image-Objektes mit gegebener Dimension:
img = sitk.Image(breite, hoehe, sitk.sitkUInt8)
breite: Anzahl der Spalten des Bildes, Integer größer Null
hoehe: Anzahl der Zeilen des Bildes, Integer größer Null
Erzeugen einer Kopie eines schon angelegten Bildobjektes:
img = sitk.Image(bild)
bild: Bildobjekt der Klasse sitk.Image
Anzeigen eines Bildobjektes:
sitk.Show(img)
Speichern eines Bildeobjektes:
sitk.WriteImage(img, dateiname)
dateiname: Name der neuen Bilddatei, String
Auslesen der Breite eines Bildobjektes:
breite = img.GetWidth()
Auslesen der Höhe eines Bildobjektes:
hoehe = img.GetHeight()
Auslesen eine Pixels eines Bildobjektes:
g = img[x,y]
x: Spaltenindex des Pixels, Integer
y: Zeilenindex des Pixels, Integer
g: Grauwert des Pixels, Integer
Setzen eines Pixels eines Bildobjektes:
img[x,y] = g
x: Spaltenindex des Pixels, Integer
y: Zeilenindex des Pixels, Integer
g: Grauwert des Pixels, Integer
Für weitere Informationen zu den Methoden eines sitk.Image-Objektes siehe
http://www.itk.org/SimpleITKDoxygen/html/classitk_1_1simple_1_1Image.html.
ImageTutorial 1
8
prof. dr. richard rascher-friesenhausen
Herunterladen