Initial commit with project files
This commit is contained in:
38
3_Signalorientierte_Bildverarbeitung/ü1/README.md
Normal file
38
3_Signalorientierte_Bildverarbeitung/ü1/README.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# Übung 1: Bildkompression
|
||||
|
||||
In dieser Übung wird der Informationsgehalt eines Bildes reduziert und die Auswirkung auf die Interpretierbarkeit
|
||||
für den Menschen betrachtet. Die Reduzierung der Informationen kann für eine Komprimierung verwendet.
|
||||
|
||||
Wenden Sie die folgenden Aufgaben auf die Bilder **data/yellowlilly.jpg** und **data/cameraman.png** an.
|
||||
|
||||
## Aufgabe a) Entfernen hochfrequenter Frequenzen
|
||||
Implementieren sie die Funktion und *remove_dft(img, rate)*, wobei mit der
|
||||
diskreten Kosinus- bzw. Fouriertransformation folgende Schritte durchgeführt werden sollen:
|
||||
|
||||
- Iterieren Sie Blockweise über das Bild mithilfe zweier for-Schleifen und einer Blockgröße von 8x8 Pixel
|
||||
- Verwenden Sie `np.fft.fft2()` um den Block in den Frequenzraum zu transformieren
|
||||
- Entfernen Sie die *n* hochfrequentesten Koefizienten mit `n = 8 * 8 * rate`
|
||||
- Transformieren Sie den Block zurück in den Ortsraum mit `np.fft.ifft2`
|
||||
|
||||
Wie stark wirkt sich der Parameter `rate` auf die Interpretierbarkeit des Bildes für den Menschen aus?
|
||||
|
||||
Die Lösung ist in der Date [l_a.py](l_a.py) zu finden.
|
||||
|
||||
## Aufgabe b) Diskrete Kosinus Transformation
|
||||
Implementieren Sie eine Funktion `dct(a: np.ndarray)`, welche als input eine zweidimensionale Matrix erhält und
|
||||
auf diese die 2D Diskrete Kosinus Transformation nach
|
||||
|
||||

|
||||
|
||||
anwendet und ausgibt.
|
||||
|
||||
Validieren Sie Ihre Funktion, indem Sie die `fft2()` und `ifft2()` Funktion aus Aufgabe a) durch die `dct()` und `idct()` Funktionen ersetzen.
|
||||
Die inverse der Transformation ist mit der Funktion `idct(a: np.ndarray)` gegeben, welche bereits in *l_b.py* implementiert ist.
|
||||
|
||||
|
||||
|
||||
## Aufgabe c) Fragen
|
||||
- Wie kann die Reduzierung der Fourier-Koeffizienten für eine Komprimierung genutzt werden?
|
||||
- Was versteht man unter diskreter Kosinustransformation und was ist der wesentliche Unterschied zur DFT?
|
||||
- Welchen Vorteil bietet die DCT gegenüber der FFT in der Praxis?
|
||||
|
||||
BIN
3_Signalorientierte_Bildverarbeitung/ü1/data/dct.png
Normal file
BIN
3_Signalorientierte_Bildverarbeitung/ü1/data/dct.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
57
3_Signalorientierte_Bildverarbeitung/ü1/l_a.py
Normal file
57
3_Signalorientierte_Bildverarbeitung/ü1/l_a.py
Normal file
@@ -0,0 +1,57 @@
|
||||
import numpy as np
|
||||
import cv2
|
||||
import math
|
||||
|
||||
|
||||
def remove_dft(img, rate):
|
||||
"""
|
||||
Diese Implementierung wendet die diskrete Fourier Transformation auf das Bild img an. Daraufhin werden die hoch-
|
||||
frequenten Anteile anteilig der Rate rate entfernt. Am Ende wird das Bild wieder in den Bildbereich transformiert.
|
||||
:param img:
|
||||
:param rate:
|
||||
:return:
|
||||
"""
|
||||
assert rate <= 1, "Die Rate muss kleiner gleich 1 sein!"
|
||||
|
||||
height, width = img.shape
|
||||
for i in range(math.ceil(width / 8)):
|
||||
for j in range(math.ceil(height / 8)):
|
||||
# Block extrahieren
|
||||
block = np.zeros((8, 8))
|
||||
horizontal_pixel, vertical_pixel = min(8, width - i * 8), min(8, height - j * 8)
|
||||
block[0:vertical_pixel, 0:horizontal_pixel] = \
|
||||
img[j * 8: (j * 8) + vertical_pixel, i * 8: (i * 8) + horizontal_pixel]
|
||||
# In den Frequenzbereich tranformieren
|
||||
block_freq = np.fft.fft2(block)
|
||||
# Hochfrequente Anteile löschen
|
||||
values_to_delete = 8 * 8 * rate
|
||||
values_deleted = 0
|
||||
for m in range(0, 16):
|
||||
for n in range(0, m + 1):
|
||||
if values_deleted >= values_to_delete:
|
||||
break
|
||||
if 7 - m + n < 0 or 7 - n < 0:
|
||||
continue
|
||||
block_freq[7 - m + n, 7 - n] = 0. + 0.j
|
||||
values_deleted += 1
|
||||
|
||||
# Rücktransformation in den Bildbereich
|
||||
block = np.fft.ifft2(block_freq)
|
||||
# Einfügen in Ursprungsbild
|
||||
img[j * 8: (j * 8) + vertical_pixel, i * 8: (i * 8) + horizontal_pixel] = \
|
||||
block[0:vertical_pixel, 0:horizontal_pixel]
|
||||
|
||||
return img
|
||||
|
||||
|
||||
''' Bild laden '''
|
||||
img = cv2.imread("../../data/cameraman.png")
|
||||
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
|
||||
img = (img / 256).astype(np.float32)
|
||||
|
||||
''' Funktion anwenden '''
|
||||
img = remove_dft(img, 0.9)
|
||||
|
||||
''' Bild anzeigen '''
|
||||
cv2.imshow("IMG", img)
|
||||
cv2.waitKey(0)
|
||||
93
3_Signalorientierte_Bildverarbeitung/ü1/l_b.py
Normal file
93
3_Signalorientierte_Bildverarbeitung/ü1/l_b.py
Normal file
@@ -0,0 +1,93 @@
|
||||
import numpy as np
|
||||
import cv2
|
||||
import math
|
||||
|
||||
|
||||
def dct(a: np.ndarray):
|
||||
a_freq = np.zeros_like(a)
|
||||
N, M = a_freq.shape[1], a_freq.shape[0]
|
||||
# Iteriere über jeden Koeffizienten
|
||||
for k in range(N):
|
||||
for m in range(M):
|
||||
dct_k_m = 0
|
||||
# Iteriere über jede Position im Ortsraum
|
||||
for x in range(N):
|
||||
for y in range(M):
|
||||
dct_k_m += a[y, x] * np.cos(k*np.pi*(2*x+1)/(2*N)) * np.cos(m*np.pi*(2*y+1)/(2*M))
|
||||
dct_k_m = 4 * dct_k_m / (np.sqrt(2*N) * np.sqrt(2*M))
|
||||
a_freq[m, k] = dct_k_m
|
||||
return a_freq
|
||||
|
||||
|
||||
def idct(a_freq: np.ndarray):
|
||||
a = np.zeros_like(a_freq)
|
||||
N, M = a_freq.shape[1], a_freq.shape[0]
|
||||
a_freq = (np.sqrt(2*N) * np.sqrt(2*M)) * a_freq / 16
|
||||
a_freq[0, :] = a_freq[0, :] / 2
|
||||
a_freq[:, 0] = a_freq[:, 0] / 2
|
||||
# Iteriere über jeden Koeffizienten
|
||||
for x in range(N):
|
||||
for y in range(M):
|
||||
f_x_y = 0 #a_freq[0, 0] / (4)# * np.sqrt(2))
|
||||
# Iteriere über jede Position im Ortsraum
|
||||
for k in range(N):
|
||||
for m in range(M):
|
||||
f_x_y += a_freq[m, k] * np.cos(k*np.pi*(2*x+1)/(2*N)) * np.cos(m*np.pi*(2*y+1)/(2*M))
|
||||
f_x_y = f_x_y / 4
|
||||
a[y, x] = f_x_y
|
||||
return a
|
||||
|
||||
|
||||
def remove_dct(img, rate):
|
||||
"""
|
||||
Diese Implementierung wendet die diskrete Fourier Transformation auf das Bild img an. Daraufhin werden die hoch-
|
||||
frequenten Anteile anteilig der Rate rate entfernt. Am Ende wird das Bild wieder in den Bildbereich transformiert.
|
||||
:param img:
|
||||
:param rate:
|
||||
:return:
|
||||
"""
|
||||
assert rate <= 1, "Die Rate muss kleiner gleich 1 sein!"
|
||||
|
||||
height, width = img.shape
|
||||
for i in range(math.ceil(width / 8)):
|
||||
for j in range(math.ceil(height / 8)):
|
||||
# Block extrahieren
|
||||
block = np.zeros((8, 8))
|
||||
horizontal_pixel, vertical_pixel = min(8, width - i * 8), min(8, height - j * 8)
|
||||
block[0:vertical_pixel, 0:horizontal_pixel] = \
|
||||
img[j * 8: (j * 8) + vertical_pixel, i * 8: (i * 8) + horizontal_pixel]
|
||||
# In den Frequenzbereich tranformieren
|
||||
block_freq = dct(block)
|
||||
# Hochfrequente Anteile löschen
|
||||
values_to_delete = 8 * 8 * rate
|
||||
values_deleted = 0
|
||||
for m in range(0, 16):
|
||||
for n in range(0, m + 1):
|
||||
if values_deleted >= values_to_delete:
|
||||
break
|
||||
if 7 - m + n < 0 or 7 - n < 0:
|
||||
continue
|
||||
block_freq[7 - m + n, 7 - n] = 0.
|
||||
values_deleted += 1
|
||||
# Rücktransformation in den Bildbereich
|
||||
block = idct(block_freq)
|
||||
# Einfügen in Ursprungsbild
|
||||
img[j * 8: (j * 8) + vertical_pixel, i * 8: (i * 8) + horizontal_pixel] = \
|
||||
block[0:vertical_pixel, 0:horizontal_pixel]
|
||||
|
||||
return img
|
||||
|
||||
|
||||
''' Bild laden '''
|
||||
img = cv2.imread("../../data/cameraman.png")
|
||||
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
|
||||
img = cv2.resize(img, (160, 160))
|
||||
img = (img.astype(np.float64) / 256)
|
||||
cv2.imshow("ORIGINAL", img)
|
||||
|
||||
''' Funktion anwenden '''
|
||||
img = remove_dct(img, 0.8)
|
||||
|
||||
''' Bild anzeigen '''
|
||||
cv2.imshow("IMG", img)
|
||||
cv2.waitKey(0)
|
||||
5
3_Signalorientierte_Bildverarbeitung/ü1/l_c.md
Normal file
5
3_Signalorientierte_Bildverarbeitung/ü1/l_c.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# Lösung zu 1c)
|
||||
|
||||
- entfernen hoher Frequenzen, da diese für den Menschen nicht so **aussagekräftig** erscheinen
|
||||
- siehe Formeln
|
||||
- keine komplexen Zahlen
|
||||
Reference in New Issue
Block a user