diff --git a/Bachelorarbeit.pdf b/Bachelorarbeit.pdf
index 362f9352222ae9f8ddfc139676aa681d7e3f17c2..504e60f51727b6fbc9742d3c0db8dba7712a8174 100644
Binary files a/Bachelorarbeit.pdf and b/Bachelorarbeit.pdf differ
diff --git a/chap/kalibrierung.tex b/chap/kalibrierung.tex
index aaeb0fb5b1f2af394e53f808db23aca4aedbe73c..e2a0dba2d0b86330412f3c6c5050b3d3f760ffcb 100644
--- a/chap/kalibrierung.tex
+++ b/chap/kalibrierung.tex
@@ -91,165 +91,153 @@
 
 		Zur Durchführung der Kalibrierung wir ein Python-Script erstellt, um die den Vorgang einfach und wiederholbar zu machen. Als Vorlage für
 		dieses dient die Anleitung zur Kamera Kalibrierung aus der \gls{OpenCV} Dokumentation \cite{OpenCV:CameraCalibration}.
-		\todo{Dependencies?}
-
-		% Das Script benötigt einige Bibliotheken, welche auf dem System vorhanden sein müssen. Um sie zu installieren, kann der Befehl
-		% \lstinline{pip3 install numpy opencv-python pyyaml} verwendet werden. Sind alle Voraussetzungen erfüllt, können die Bibliotheken in das Script
-		% importiert werden.
-
-		% \begin{lstlisting}[
-		% 	float,
-		% 	style=example,
-		% 	caption=Für das Kaliebrierscript benötigte Biblioteken,
-		% 	language=Python
-		% ]
-		% 	# * ----- Package imports: ----- *
-		% 	import glob
-		% 	import pathlib
-
-		% 	import cv2 as cv
-		% 	import numpy as np
-		% 	import yaml
-		% \end{lstlisting}
-
-		Grundlage für die Kalibrierung ist es, eine Reihe von Bildern mit der zu kalibrierenden Kamera aufzunehmen, auf denen sich ein
-		Schachbrettartiges Kalibriermuster befindet. Wichtig ist es, dasselbe Muster und dieselbe Auflösung für alle Bilder verwendet werden. Es muss
-		sich dabei nicht um eine quadratische Anordnung handeln, jedoch muss die Anzahl der Zeilen und spalten im Code angegeben werden. Dabei ist
-		allerdings nicht die Anzahle der Felder gemeint, sondern die Anzahl der inneren Kreuzungspunkten. Ein normales Schachbrett hat beispielsweise
-		$8 \!\times\! 8$ Felder, aber nur $7 \!\times\! 7$ interne Kreuzungen. Zur Verdeutlichung sind die Kreuzungspunkte des Verwendeten
-		Kalibriermuster in \autoref{fig: kalibriermuster} grün markiert.
 
-		\begin{figure}
-			\includegraphics[width=.4\textwidth]{img/kalibrieren_PATTER.png}
-			\caption{Schachbrett Kalibriermuster mit markierten inneren Kreuzungen}
-			\label{fig: kalibriermuster}
-		\end{figure}
+		Außerdem wird eine \gls{ROS Nodelet} erstellt, welches die Kalibrierung auf den Video-Stream anwendet und korrigierte Bilder publischt.
 
-		Es wird nun ein Standard Schachbrett als Kalibriermuster verwendet, wie es bereits in \autoref{fig: kalibriermuster} zu sehen ist. Dessen
-		Kalibriermustergröße von $7 \!\times\! 7$ wird im Code als Konstante definiert:
-
-		\begin{lstlisting}[
-			float,
-			style=example,
-			caption=Definiteion der Größe des Kalibriermuster,
-			language=Python
-		]
-			# define the grid pattern to look for
-			PATTERN = (7,7)
-		\end{lstlisting}
-
-		Entsprechend der Anleitung \cite{OpenCV:CameraCalibration} werden benötigte Variablen initialisiert (siehe \autoref{code: kali var init}).
-
-		\begin{lstlisting}[
-			float,
-			style=example,
-			caption=Initialisierung von Variablen für die Kalibreirung,
-			language=Python,
-			label=code: kali var init
-		]
-			# termination criteria
-			criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 30, 0.001)
-			# prepare object points, like (0,0,0), (1,0,0),...,(6,5,0)
-			objp = np.zeros((PATTERN[0]*PATTERN[1],3), np.float32)
-			objp[:,:2] = np.mgrid[0:PATTERN[0],0:PATTERN[1]].T.reshape(-1,2)
-			# Arrays to store object points and image points from all the images.
-			objpoints = [] # 3d point in real world space
-			imgpoints = [] # 2d points in image plane.
-		\end{lstlisting}
-
-		Nun werden alle im aktuellen Ordner befindlichen Bilder eingelesen und in einer Liste abgespeichert. Jedes Listenelement wird eingelesen und
-		in ein Schwarzweißbild umgewandelt. Dieses wird dann an die \gls{OpenCV} Funktion \lstinline{findChessboardCorners()} übergeben, welche die
-		Kreuzungspunkten findet und zurückgibt.
-
-		\begin{lstlisting}[
-			float,
-			style=example,
-			caption=Finden un Verarbeiten der Kalibrierbilder,
-			language=Python
-		]
-			# get all images in current directory
-			folder = pathlib.Path(__file__).parent.resolve()
-			images = glob.glob(f'{folder}/*.png')
-
-			# loop over all images:
-			for fname in images:
-				img = cv.imread(fname)
-				gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
-
-				# Find the chess board corners
-				ret, corners = cv.findChessboardCorners(gray, PATTERN, None, flags=cv.CALIB_CB_ADAPTIVE_THRESH)
-		\end{lstlisting}
-
-		Dabei ist es gar kein Problem, wenn nicht in jedem Bild das Kalibriermuster gefunden werden kann, solange insgesamt ausreichend nutzbare
-		Bilder vorhanden sind. Bei nicht nutzbaren Bildern gibt \lstinline{findChessboardCorners()} \lstinline{None} zurück und das Bild wird einfach
-		übersprungen.
-
-		Für alle nutzbaren Bilder werden die in \autoref{code: kali var init} erstellten Punktbezeichnungen zur Liste der gefundenen Objekte
-		hinzugefügt. Die Genauigkeit der gefunden Eckkoordinaten wird über die Funktion \lstinline{cornerSubPix()} erhöht und diese werden an die
-		Liste der gefundenen Bildpunkte angehängt.
-
-		\begin{lstlisting}[
-			float,
-			style=example,
-			caption=Abspeichern der Gefundenen Bildpunkte,
-			language=Python
-		]
-			# If found, add object points, image points
-			if ret == True:
-				objpoints.append(objp)
-				corners2 = cv.cornerSubPix(gray,corners, (11,11), (-1,-1), criteria)
-				imgpoints.append(corners)
-		\end{lstlisting}
-
-		Jetzt kann die eigentliche Kalibrierung mittels der \gls{OpenCV} Funktion \lstinline{calibrateCamera()} durchgeführt werden. Diese nimmt die
-		zuvor erstellten Listen von Objektkoordinaten und Bildpunkten und löst damit die in \autoref{sec: intrinsic} beschriebenen Gleichungen. Als
-		Ergebnis liefert sie die Kameramatrix $K$ und die Verzerrungskoeffizienten $D_{coeff}$ zurück. \cite{OpenCV:CameraCalibration}
-
-		\begin{lstlisting}[
-			float,
-			style=example,
-			caption=Ermitteln der Kalibrierwerte mittels OpenCV,
-			language=Python
-		]
-			# get calibration parameters:
-			ret, K, D_coeff, _, _ = cv.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)
-		\end{lstlisting}
-
-		Der gesamte Code wird nun auf einen Datensatz von Bilder angewandt, um die Ergebnisse für den vorliegenden Roboter zu erhalten. Der Datensatz
-		ist auf dem GitLab Server unter der URL \url{https://lab.it.hs-hannover.de/p9r-rxm-u1/videodrive_ws/-/wikis/uploads/6c853b3f41964eccd6671954a07ad5ed/intrinsicCalibration_down4.zip}
-		abgelegt. Damit ergeben sich die folgenden Kalibrierungsergebnisse.
-
-		\begin{align*}
-			k_1 &= -0,42049309612684654 \\
-			k_2 &= 0,3811654512587829 \\
-			p_1 &= -0,0018273837466050299 \\
-			p_2 &= -0,006355252159438178 \\
-			k_3 &= -0,26963105010742416 \\
-			K &=
-			\begin{pmatrix}
-				384,65 & 0 & 243,413 \\
-				0 & 384,31 & 139,017\\
-				0 & 0 & 1 \\
-			\end{pmatrix}
-		\end{align*}
-
-		Um zu zeigen, wie sich das Bild damit verbessern lässt, werden die Ergebnisse auf eines der Bilder angewandt. Da sich die Abmessungen des
-		entzerrten Bildes von denen des Verzehrten unterscheiden, wird zuerst die \gls{OpenCV} Funktion \lstinline{getOptimalNewCameraMatrix()}
-		verwendet, welche eine weiter Skalierte Kameramatrix ermittelt, mit der die Abmessungen zueinander passen. Diese liefert außerdem eine
-		\emph{Region of interes}, also den Bildbereich der nur relevante (nicht leere) Pixel enthält.
-
-		Mit dieser zusätzlichen Matrix kann nun die \gls{OpenCV} Funktion \lstinline{undistort()} auf das Bild angewandt werden. Diese Produziert das
-		entzerrte Bild mit leeren Pixeln in den Bereichen, wo keine Informationen im Originalbild vorlagen. Um diese leeren Pixel zu entfernen wird
-		das Bild auf die \gls{ROI} reduziert.
-
-		\medskip
-		In \autoref{fig: intrinsik schritte} ist die Entzerrung des Beispielbildes mit dem Zwischenschritt mit Leerpixeln gezeigt.
 
-		\begin{figure}
-			\includegraphics[width=\textwidth]{img/kalibrieren_schritte.png}
-			\caption{Schritte der intrinsischen Kalibrierung}
-			\label{fig: intrinsik schritte}
-		\end{figure}
+		\subsection{Python Script zur Durchführung der Kalibrierung}
+
+			Grundlage für die Kalibrierung ist es, eine Reihe von Bildern mit der zu kalibrierenden Kamera aufzunehmen, auf denen sich ein
+			Schachbrettartiges Kalibriermuster befindet. Wichtig ist es, dasselbe Muster und dieselbe Auflösung für alle Bilder verwendet werden. Es muss
+			sich dabei nicht um eine quadratische Anordnung handeln, jedoch muss die Anzahl der Zeilen und spalten im Code angegeben werden. Dabei ist
+			allerdings nicht die Anzahle der Felder gemeint, sondern die Anzahl der inneren Kreuzungspunkten. Ein normales Schachbrett hat beispielsweise
+			$8 \!\times\! 8$ Felder, aber nur $7 \!\times\! 7$ interne Kreuzungen. Zur Verdeutlichung sind die Kreuzungspunkte des Verwendeten
+			Kalibriermuster in \autoref{fig: kalibriermuster} grün markiert.
+
+			\begin{figure}
+				\includegraphics[width=.4\textwidth]{img/kalibrieren_PATTER.png}
+				\caption{Schachbrett Kalibriermuster mit markierten inneren Kreuzungen}
+				\label{fig: kalibriermuster}
+			\end{figure}
+
+			Es wird nun ein Standard Schachbrett als Kalibriermuster verwendet, wie es bereits in \autoref{fig: kalibriermuster} zu sehen ist. Dessen
+			Kalibriermustergröße von $7 \!\times\! 7$ wird im Code als Konstante definiert:
+
+			\begin{lstlisting}[
+				float,
+				style=example,
+				caption=Definiteion der Größe des Kalibriermuster,
+				language=Python
+			]
+				# define the grid pattern to look for
+				PATTERN = (7,7)
+			\end{lstlisting}
+
+			Entsprechend der Anleitung \cite{OpenCV:CameraCalibration} werden benötigte Variablen initialisiert (siehe \autoref{code: kali var init}).
+
+			\begin{lstlisting}[
+				float,
+				style=example,
+				caption=Initialisierung von Variablen für die Kalibreirung,
+				language=Python,
+				label=code: kali var init
+			]
+				# termination criteria
+				criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 30, 0.001)
+				# prepare object points, like (0,0,0), (1,0,0),...,(6,5,0)
+				objp = np.zeros((PATTERN[0]*PATTERN[1],3), np.float32)
+				objp[:,:2] = np.mgrid[0:PATTERN[0],0:PATTERN[1]].T.reshape(-1,2)
+				# Arrays to store object points and image points from all the images.
+				objpoints = [] # 3d point in real world space
+				imgpoints = [] # 2d points in image plane.
+			\end{lstlisting}
+
+			Nun werden alle im aktuellen Ordner befindlichen Bilder eingelesen und in einer Liste abgespeichert. Jedes Listenelement wird eingelesen und
+			in ein Schwarzweißbild umgewandelt. Dieses wird dann an die \gls{OpenCV} Funktion \lstinline{findChessboardCorners()} übergeben, welche die
+			Kreuzungspunkten findet und zurückgibt.
+
+			\begin{lstlisting}[
+				float,
+				style=example,
+				caption=Finden un Verarbeiten der Kalibrierbilder,
+				language=Python
+			]
+				# get all images in current directory
+				folder = pathlib.Path(__file__).parent.resolve()
+				images = glob.glob(f'{folder}/*.png')
+
+				# loop over all images:
+				for fname in images:
+					img = cv.imread(fname)
+					gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
+
+					# Find the chess board corners
+					ret, corners = cv.findChessboardCorners(gray, PATTERN, None, flags=cv.CALIB_CB_ADAPTIVE_THRESH)
+			\end{lstlisting}
+
+			Dabei ist es gar kein Problem, wenn nicht in jedem Bild das Kalibriermuster gefunden werden kann, solange insgesamt ausreichend nutzbare
+			Bilder vorhanden sind. Bei nicht nutzbaren Bildern gibt \lstinline{findChessboardCorners()} \lstinline{None} zurück und das Bild wird einfach
+			übersprungen.
+
+			Für alle nutzbaren Bilder werden die in \autoref{code: kali var init} erstellten Punktbezeichnungen zur Liste der gefundenen Objekte
+			hinzugefügt. Die Genauigkeit der gefunden Eckkoordinaten wird über die Funktion \lstinline{cornerSubPix()} erhöht und diese werden an die
+			Liste der gefundenen Bildpunkte angehängt.
+
+			\begin{lstlisting}[
+				float,
+				style=example,
+				caption=Abspeichern der Gefundenen Bildpunkte,
+				language=Python
+			]
+				# If found, add object points, image points
+				if ret == True:
+					objpoints.append(objp)
+					corners2 = cv.cornerSubPix(gray,corners, (11,11), (-1,-1), criteria)
+					imgpoints.append(corners)
+			\end{lstlisting}
+
+			Jetzt kann die eigentliche Kalibrierung mittels der \gls{OpenCV} Funktion \lstinline{calibrateCamera()} durchgeführt werden. Diese nimmt die
+			zuvor erstellten Listen von Objektkoordinaten und Bildpunkten und löst damit die in \autoref{sec: intrinsic} beschriebenen Gleichungen. Als
+			Ergebnis liefert sie die Kameramatrix $K$ und die Verzerrungskoeffizienten $D_{coeff}$ zurück. \cite{OpenCV:CameraCalibration}
+
+			\begin{lstlisting}[
+				float,
+				style=example,
+				caption=Ermitteln der Kalibrierwerte mittels OpenCV,
+				language=Python
+			]
+				# get calibration parameters:
+				ret, K, D_coeff, _, _ = cv.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)
+			\end{lstlisting}
+
+			Der gesamte Code wird nun auf einen Datensatz von Bilder angewandt, um die Ergebnisse für den vorliegenden Roboter zu erhalten. Der Datensatz
+			ist auf dem GitLab Server unter der URL \url{https://lab.it.hs-hannover.de/p9r-rxm-u1/videodrive_ws/-/wikis/uploads/6c853b3f41964eccd6671954a07ad5ed/intrinsicCalibration_down4.zip}
+			abgelegt. Damit ergeben sich die folgenden Kalibrierungsergebnisse.
+
+			\begin{align*}
+				k_1 &= -0,42049309612684654 \\
+				k_2 &= 0,3811654512587829 \\
+				p_1 &= -0,0018273837466050299 \\
+				p_2 &= -0,006355252159438178 \\
+				k_3 &= -0,26963105010742416 \\
+				K &=
+				\begin{pmatrix}
+					384,65 & 0 & 243,413 \\
+					0 & 384,31 & 139,017\\
+					0 & 0 & 1 \\
+				\end{pmatrix}
+			\end{align*}
+
+			Um zu zeigen, wie sich das Bild damit verbessern lässt, werden die Ergebnisse auf eines der Bilder angewandt. Da sich die Abmessungen des
+			entzerrten Bildes von denen des Verzehrten unterscheiden, wird zuerst die \gls{OpenCV} Funktion \lstinline{getOptimalNewCameraMatrix()}
+			verwendet, welche eine weiter Skalierte Kameramatrix ermittelt, mit der die Abmessungen zueinander passen. Diese liefert außerdem eine
+			\emph{Region of interes}, also den Bildbereich der nur relevante (nicht leere) Pixel enthält.
+
+			Mit dieser zusätzlichen Matrix kann nun die \gls{OpenCV} Funktion \lstinline{undistort()} auf das Bild angewandt werden. Diese Produziert das
+			entzerrte Bild mit leeren Pixeln in den Bereichen, wo keine Informationen im Originalbild vorlagen. Um diese leeren Pixel zu entfernen wird
+			das Bild auf die \gls{ROI} reduziert.
+
+			\medskip
+			In \autoref{fig: intrinsik schritte} ist die Entzerrung des Beispielbildes mit dem Zwischenschritt mit Leerpixeln gezeigt.
+
+			\begin{figure}
+				\includegraphics[width=\textwidth]{img/kalibrieren_schritte.png}
+				\caption{Schritte der intrinsischen Kalibrierung}
+				\label{fig: intrinsik schritte}
+			\end{figure}
+
+
+		\subsection{Anwenden der Kalibrierung in einem \gls{ROS Nodelet}}
 
 
 	\section{Extrinsische Kalibrierung} \label{sec: extrensic}