213 lines
6.8 KiB
Python
213 lines
6.8 KiB
Python
import cv2, datetime, os
|
|
import numpy as np
|
|
from copy import deepcopy
|
|
from matplotlib import pyplot as plt
|
|
|
|
from . import Algorithm
|
|
|
|
class InvisCloak (Algorithm):
|
|
|
|
""" init function """
|
|
def __init__(self):
|
|
# Number of buffered images
|
|
self.n = 5
|
|
|
|
# Picture buffer
|
|
self.picture_buffer = []
|
|
|
|
# Middle value image built of buffer images
|
|
# Includes noice reduction and histogram spread
|
|
self.middle_value_picture = None
|
|
|
|
# Clean up results folder
|
|
folder_path = os.path.join("results")
|
|
|
|
for filename in os.listdir(folder_path):
|
|
file_path = os.path.join(folder_path, filename)
|
|
|
|
if os.path.isfile(file_path):
|
|
os.unlink(file_path)
|
|
|
|
|
|
""" Processes the input image"""
|
|
def process(self, img):
|
|
|
|
""" 2.1 Vorverarbeitung """
|
|
""" 2.1.1 Rauschreduktion """
|
|
plotNoise = False # Schaltet die Rauschvisualisierung ein
|
|
if plotNoise:
|
|
self._plotNoise(img, "Rauschen vor Korrektur")
|
|
img = self._211_Rauschreduktion(img)
|
|
if plotNoise:
|
|
self._plotNoise(img, "Rauschen nach Korrektur")
|
|
""" 2.1.2 HistogrammSpreizung """
|
|
img = self._212_HistogrammSpreizung(img)
|
|
|
|
|
|
""" 2.2 Farbanalyse """
|
|
""" 2.2.1 RGB """
|
|
#self._221_RGB(img)
|
|
""" 2.2.2 HSV """
|
|
#self._222_HSV(img)
|
|
|
|
|
|
""" 2.3 Segmentierung und Bildmodifikation """
|
|
img = self._23_SegmentUndBildmodifizierung(img)
|
|
|
|
return img
|
|
|
|
""" Reacts on mouse callbacks """
|
|
def mouse_callback(self, event, x, y, flags, param):
|
|
if event == cv2.EVENT_LBUTTONUP:
|
|
print("A Mouse click happend! at position", x, y)
|
|
|
|
# Stores the current image to data folder
|
|
cv2.imwrite(f"results/{datetime.datetime.now().strftime('%Y-%m-%d_%H:%M:%S')}_original_image.png",
|
|
self.picture_buffer[self.n - 1])
|
|
|
|
# Create RGB histogram
|
|
self._221_RGB(self.middle_value_picture)
|
|
|
|
# Create HSV histogram
|
|
self._222_HSV(self.middle_value_picture)
|
|
|
|
# Get binary mask and write it to file
|
|
binary_mask = self._23_SegmentUndBildmodifizierung(self.middle_value_picture, True)
|
|
cv2.imwrite(f"results/{datetime.datetime.now().strftime('%Y-%m-%d_%H:%M:%S')}_binary_mask.png",
|
|
binary_mask)
|
|
elif event == cv2.EVENT_MBUTTONUP:
|
|
# Save current image as background
|
|
cv2.imwrite(f"results/background.png", self.picture_buffer[self.n - 1])
|
|
|
|
|
|
def _plotNoise(self, img, name:str):
|
|
height, width = np.array(img.shape[:2])
|
|
centY = (height / 2).astype(int)
|
|
centX = (width / 2).astype(int)
|
|
|
|
cutOut = 5
|
|
tmpImg = deepcopy(img)
|
|
tmpImg = tmpImg[centY - cutOut:centY + cutOut, centX - cutOut:centX + cutOut, :]
|
|
|
|
outSize = 500
|
|
tmpImg = cv2.resize(tmpImg, (outSize, outSize), interpolation=cv2.INTER_NEAREST)
|
|
|
|
cv2.imshow(name, tmpImg)
|
|
cv2.waitKey(1)
|
|
|
|
def _211_Rauschreduktion(self, img):
|
|
"""
|
|
Hier steht Ihr Code zu Aufgabe 2.1.1 (Rauschunterdrückung)
|
|
- Implementierung Mittelwertbildung über N Frames
|
|
"""
|
|
self.picture_buffer.append(img)
|
|
|
|
if len(self.picture_buffer) < self.n:
|
|
# If number of buffered images < defined buffer size n, return current image
|
|
return img
|
|
elif len(self.picture_buffer) > self.n:
|
|
# If number of buffered images > defined buffer size n, remove oldest image
|
|
self.picture_buffer.pop(0)
|
|
|
|
# Reduce noise, return result image
|
|
return np.mean(self.picture_buffer, axis=0).astype(np.uint8)
|
|
|
|
|
|
def _212_HistogrammSpreizung(self, img):
|
|
"""
|
|
Hier steht Ihr Code zu Aufgabe 2.1.2 (Histogrammspreizung)
|
|
- Transformation HSV
|
|
- Histogrammspreizung berechnen
|
|
- Transformation BGR
|
|
"""
|
|
# Convert brg image to hsv image
|
|
hsv_image = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
|
|
|
|
# Get hsv parts
|
|
h, s, v = cv2.split(hsv_image)
|
|
|
|
# Calc histogram spread
|
|
v = cv2.equalizeHist(v)
|
|
|
|
# Merge histogram spread to image
|
|
hsv_stretched = cv2.merge([h, s, v])
|
|
|
|
# Convert hsv image to brg and store result to member variable
|
|
self.middle_value_picture = cv2.cvtColor(hsv_stretched, cv2.COLOR_HSV2BGR)
|
|
|
|
# Return brg result image
|
|
return self.middle_value_picture
|
|
|
|
|
|
def _221_RGB(self, img, colorspectrum = "bgr"):
|
|
"""
|
|
Hier steht Ihr Code zu Aufgabe 2.2.1 (RGB)
|
|
- Histogrammberechnung und Analyse
|
|
"""
|
|
# Names of the colors in histogram
|
|
channels = ["b", "g", "r"]
|
|
|
|
# Calc histogram
|
|
for index, channel_name in enumerate(channels):
|
|
hist = cv2.calcHist([img], [index], None, [256], [0, 256])
|
|
plt.plot(hist, color=channel_name)
|
|
plt.xlim([0, 256])
|
|
|
|
# Save histogram, clear cache
|
|
plt.savefig(f"results/{datetime.datetime.now().strftime('%Y-%m-%d_%H:%M:%S')}_histogram_{colorspectrum}.png")
|
|
plt.clf()
|
|
|
|
|
|
def _222_HSV(self, img):
|
|
"""
|
|
Hier steht Ihr Code zu Aufgabe 2.2.2 (HSV)
|
|
- Histogrammberechnung und Analyse im HSV-Raum
|
|
"""
|
|
# Convert image to hsv, call _221_RGB to create histogram
|
|
self._221_RGB(cv2.cvtColor(img, cv2.COLOR_BGR2HSV), "hsv")
|
|
|
|
|
|
def _23_SegmentUndBildmodifizierung (self, img, save_binary_mask = False):
|
|
"""
|
|
Hier steht Ihr Code zu Aufgabe 2.3.1 (StatischesSchwellwertverfahren)
|
|
- Binärmaske erstellen
|
|
"""
|
|
# 0 = blue, 1 = green, 2 = red
|
|
selected_color_channel = 2
|
|
|
|
# Color threshold values for color deletion
|
|
lower_bound, upper_bound = 100, 255
|
|
|
|
# Creating binary mask
|
|
binary_mask = (lower_bound < img[:, :, selected_color_channel]) * (img[:, :, selected_color_channel] < upper_bound)
|
|
|
|
# Store binary mask to results folder
|
|
if save_binary_mask:
|
|
cv2.imwrite(f"results/{datetime.datetime.now().strftime('%Y-%m-%d_%H:%M:%S')}_binary_mask.png",
|
|
binary_mask * 256)
|
|
|
|
try:
|
|
# Get background image
|
|
background = cv2.imread("results/background.png")
|
|
|
|
# Apply mask to image
|
|
img[binary_mask] = background[binary_mask]
|
|
except:
|
|
print("No background image")
|
|
|
|
|
|
"""
|
|
Hier steht Ihr Code zu Aufgabe 2.3.2 (Binärmaske)
|
|
- Binärmaske optimieren mit Opening/Closing
|
|
- Wahl größte zusammenhängende Region
|
|
"""
|
|
|
|
|
|
"""
|
|
Hier steht Ihr Code zu Aufgabe 2.3.1 (Bildmodifizerung)
|
|
- Hintergrund mit Mausklick definieren
|
|
- Ersetzen des Hintergrundes
|
|
"""
|
|
|
|
|
|
return img |