147 lines
6.8 KiB
TeX
147 lines
6.8 KiB
TeX
\newpage
|
|
\subsection{Segmentierung und Bildmodifizierung}
|
|
In diesem Arbeitspaket werden Sie auf Grundlage der vorherigen Analysen eine Segmentierung des magischen Umhangs realisieren. Anschließend werden Sie den segmentierten Bereich \glqq verschwinden\grqq\ lassen, indem sie ein statisches Bild des Hintergrunds auf diese Flächen einfügen.
|
|
|
|
|
|
\subsubsection{Statisches Schwellwertverfahren}
|
|
Implementieren Sie die von Ihnen gefundene Regel nach Gleichung~\ref{equ:segrule}, um eine Binärmaske zu erhalten. Sie können die Randbedingungen wie im folgenden Code-Schnipsel \ref{lst:conditions} implementieren.
|
|
|
|
\begin{lstlisting}[caption={Benutzung von Randbedingungen mit \textit{numpy}}, label={lst:conditions}]
|
|
import cv2
|
|
import numpy as np
|
|
|
|
channel1 = 0
|
|
lower_bound1, upper_bound1 = 15, 100
|
|
is_condition_1_true = (lower_bound1 < img[:, :, channel1]) * \
|
|
(img[:, :, channel1] < upper_bound1)
|
|
channel2 = 1
|
|
lower_bound2, upper_bound2 = 65, 172
|
|
is_condition_2_true = (lower_bound2 < img[:, :, channel2]) * \
|
|
(img[:, :, channel2] < upper_bound2)
|
|
|
|
binary_mask = is_condition_1_true * is_condition_2_true
|
|
\end{lstlisting}
|
|
|
|
Geben Sie die gefundene Binärmaske als Ausgangsbild auf dem Bildschirm aus. Sollten die gefundenen Wertebereich zu keinen sinnvollen Segmentierungen führen, dürfen Sie Gleichung~\ref{equ:segrule} selbstverständlich anpassen!
|
|
|
|
Implementieren Sie ebenfalls eine Mausklick-Funktion, mit der Sie das aktuelle Bild und die dazugehörige Binärmaske abspeichern können. Für das Abspeichern von Bildern können Sie die Funktion \textit{cv2.imwrite(img, "path\_to\_store.png")} verwenden.
|
|
|
|
\paragraph*{Aufgabe 1}
|
|
Geben Sie Ihren Code an und beschreiben Sie ihn. Geben Sie nur relevante Code Bereiche an! Geben Sie ebenfalls das aufgenommene Bild sowie die dazugehörige Binärmaske an.
|
|
|
|
\lstset{caption={Segmentierung und Bildmodifizierung, Aufgabe 1}}
|
|
\begin{lstlisting}
|
|
def _23_SegmentUndBildmodifizierung (self, img, save_binary_mask = False):
|
|
# Convert BGR -> HSV
|
|
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
|
|
|
|
# Area 1: H = 0-10 (strong Rot)
|
|
lower_red1 = np.array([0, 100, 50])
|
|
upper_red1 = np.array([0, 255, 255])
|
|
|
|
# Area 2: H = 169-179 (red-violet)
|
|
lower_red2 = np.array([171, 100, 50])
|
|
upper_red2 = np.array([179, 255, 255])
|
|
|
|
# Create binary mask for both red areas
|
|
mask1 = cv2.inRange(hsv, lower_red1, upper_red1)
|
|
mask2 = cv2.inRange(hsv, lower_red2, upper_red2)
|
|
|
|
# Combine both masks
|
|
mask = cv2.bitwise_or(mask1, mask2)
|
|
\end{lstlisting}
|
|
|
|
\subsubsection{Binärmaske}
|
|
Die in der vorherigen Aufgabe erhaltene Binärmaske ist ggf.\ ungeeignet für eine zufriedenstellende Segmentierung. Sie sollen die Maske nun optimieren. Wenden Sie dafür das \textit{Opening} und \textit{Closing} auf die Binärmaske an. Nutzen Sie die Funktionen \textit{cv2.erode(img, kernel)} und \textit{cv2.dilate(img, kernel)}.
|
|
|
|
Wählen Sie zum Schluss die größte zusammenhänge Region segmentierter Pixel aus, und löschen alle anderen Segmente. Folgender Code-Schnipsel~\ref{lst:contours} soll als Hilfestellung dienen. Recherchieren Sie ggf.\ im Internet.
|
|
|
|
\lstset{caption={Konturfindung}}
|
|
\lstset{label={lst:contours}}
|
|
\begin{lstlisting}
|
|
(cnts, _) = cv2.findContours(
|
|
binary_mask, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
|
|
c = max(cnts, key = cv2.contourArea)
|
|
img = cv2.drawContours(img, [c], -1, color=255, -1)
|
|
\end{lstlisting}
|
|
|
|
\paragraph*{Aufgabe 2}
|
|
Geben Sie Ihren Code an und beschreiben Sie ihn. Geben Sie nur relevante Code Bereiche an!
|
|
\lstset{caption={Segmentierung und Bildmodifizierung, Aufgabe 2}}
|
|
\begin{lstlisting}
|
|
def _23_SegmentUndBildmodifizierung (self, img, save_binary_mask = False):
|
|
# ...
|
|
|
|
# Optimizing mask with opening and closing
|
|
kernel = np.ones((5, 5), np.uint8)
|
|
|
|
mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
|
|
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)
|
|
|
|
# Select biggest connected area
|
|
cnts, _ = cv2.findContours(mask, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
|
|
|
|
if cnts:
|
|
c = max(cnts, key=cv2.contourArea)
|
|
new_mask = np.zeros_like(mask)
|
|
cv2.drawContours(new_mask, [c], -1, color = 255, thickness = -1)
|
|
mask = new_mask
|
|
else:
|
|
mask = np.zeros_like(mask)
|
|
\end{lstlisting}
|
|
|
|
\paragraph*{Aufgabe 3}
|
|
Welche Probleme oder Fehler können in der Binärmaske vorkommen, die mit den Maßnahmen beseitigt werden sollen?
|
|
|
|
\color{blue}
|
|
|
|
Durch das Opening und Closing können sich zwei Bereiche miteinander verbinden, die jedoch nicht zusammengehören. Die Wahl des größten zusammenhängenden Segments kann relevante Bereiche auch einfach auslassen, wenn das Opening und Closing diesen nicht zu größten Bereich zusammengeführt hat.
|
|
|
|
\color{black}
|
|
|
|
\subsubsection{Bildmodifizierung}
|
|
Nach dem Fertigstellen der vorherigen Aufgabenstellungen sollten Sie nun eine Binärmaske erhalten, welche den \glqq magischen Umhang\grqq\ segmentiert. Die letzte Aufgabe befasst sich mit der Bildmodifizierung, welche den Eindruck verschwindender Objekte vermittelt.
|
|
|
|
Sie sollen nun folgende Funktionen implementieren:
|
|
|
|
Erstellen Sie eine Member-Variable (z.B. \textit{self.variable}) in die Algorithmus Funktion \textit{\_\_init\_\_()}. Initiieren Sie die Variable mit dem Wert \textit{None}.
|
|
Modifizieren Sie den Algorithmus, sodass Sie mit einem Mausklick ein Bild in die Variable speichern können. Dieses Bild wird als Hintergrund definiert. Mausklick-Funktionen aus vorherigen Aufgaben können überschrieben werden!
|
|
|
|
Solange kein Bild in der Variable gespeichert ist, soll das Eingangsbild direkt wieder ausgegeben werden. Sobald ein Hintergrund vorhanden ist soll folgendes passieren: Modifizieren Sie das Bild, indem Sie das Ausgangsbild aus dem derzeitigen Kamera-Stream und dem Hintergrund zusammenfügen. Die durch die Binärmaske segmentierte Fläche soll aus dem Hintergrund entnommen werden, die unsegmentierte Fläche aus dem derzeitigen Videostream.
|
|
|
|
\textbf{Hinweis:} Verlassen Sie das Sichtfeld der Kamera, während Sie die Hintergrund Aufnahme aufnehmen.
|
|
|
|
\paragraph*{Aufgabe 4}
|
|
Geben Sie Ihren Code an und beschreiben Sie ihn. Geben Sie nur relevante Code Bereiche an!
|
|
\lstset{caption={Segmentierung und Bildmodifizierung, Aufgabe 4}}
|
|
\begin{lstlisting}
|
|
def _23_SegmentUndBildmodifizierung (self, img, save_binary_mask = False):
|
|
# ...
|
|
|
|
# Return image if no background is set
|
|
if self.background is None:
|
|
return img
|
|
|
|
# 3-channel mask for binary operations
|
|
mask_3ch = cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR)
|
|
|
|
# Background are: Get from save background image
|
|
background_part = cv2.bitwise_and(self.background, mask_3ch)
|
|
|
|
# Foreground area: Extract from current image
|
|
foreground_part = cv2.bitwise_and(img, cv2.bitwise_not(mask_3ch))
|
|
|
|
# Merge both areas
|
|
output = cv2.add(background_part, foreground_part)
|
|
return output
|
|
\end{lstlisting}
|
|
|
|
\paragraph*{Aufgabe 5}
|
|
Geben Sie ein Bild (z.B. Screenshot) an, in dem die Funktion Ihres \glqq magischen Umhangs\grqq\ gezeigt wird!
|
|
|
|
\begin{figure}
|
|
\centering
|
|
\includegraphics[width=10cm]{fig/Endergebnis.png}
|
|
\caption{Endergebnis}
|
|
\label{fig:histogram-endergebnis}
|
|
\end{figure} |