Initial commit with project files

This commit is contained in:
2025-06-27 14:34:11 +02:00
commit 7ea3207e63
310 changed files with 9331 additions and 0 deletions

View 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
![](./data/dct.png)
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?

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View 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)

View 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)

View 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