De grijswaarden van beelden kunnen voorgesteld worden in tabellen, waarbij elk tabelelement de grijswaarde van een locatie in het beeld voorstelt. We beschouwen beelden van $$M$$ rijen en $$N$$ kolommen die dus in een NumPy-tabel $$a$$ met $$M$$ rijen en $$N$$ kolommen kunnen voorgesteld worden. Het beeld $$a$$ is opgebouwd uit subblokken van $$m$$ rijen en $$n$$ kolommen waarbij $$m$$ en $$n$$ delers zijn van respectievelijk $$M$$ en $$N$$.
Om zo een subblok $$b$$ ($$m$$ rijen en $$n$$ kolommen) te bewerken (comprimeren, filteren, ...) wordt
dikwijls gebruik gemaakt onderstaande transformatie, die de tabel $$b$$ omzet naar de tabel $$c$$, die
eveneens $$m$$ rijen en $$n$$ kolommen telt:
$$
c_{ij} = \sum_{r = 0}^{m -1} \sum_{s = 0}^{n - 1} K_{rs} b_{rs}
$$
voor $$0 \le i \lt m$$ en $$0 \le j \lt n$$.
Hierin stelt $$K$$ een $$m \times n$$ tabel voor, gegeven door:
$$
K_{rs} = 2\frac{P(i)}{\sqrt{m}} \frac{P(j)}{\sqrt{n}} \cos[(r+\frac{1}{2})\frac{i\pi}{m}] \cos[(s+\frac{1}{2})\frac{j\pi}{n}]
$$
waarin
$$
P(k) = \left\{
\begin{array}{rl}
\frac{\sqrt{2}}{2}& \text{voor } k = 0\\
1 & \text{voor } k \ne 0\\
\end{array} \right.
$$
en $$k$$ geheel. Merk dus op dat de tabel $$K$$ afhankelijk is van $$i$$ en $$j$$. (De transformatie die de
tabel $$b$$ op de tabel $$c$$ afbeeldt wordt "de discrete cosinustransformatie in 2 dimensies" genoemd.
Deze transformatie wordt intensief gebruikt bij generatie en verwerking van beelden.)
Programmeer onderstaande functies:
kernmatrix()
heeft 4 argumenten, namelijk:
dct_2D()
heeft als enig argument een NumPy-tabel met $$M$$ rijen en $$N$$
kolommen. Het resultaat een NumPy-tabel met
dezelfde dimensies waarbij de hierboven geschetste transformatie uitgevoerd werd,
voor $$m = M$$ en $$n = N$$ (m.a.w. er is maar 1 subblok). dct_beeld()
heeft als argumenten:
LET OP : het is NIET toegelaten om in deze oefening gebruik te maken van lijsten. De oplossing mag enkel gebruik maken van NumPy-rijen of tabellen.
Merk op dat je resultaat, ten behoeve van de evaluatie in Dodona, afgebroken wordt op 4 decimalen (de
functie format_l()
uit het verbeterscript zorgt hiervoor). Je resultaat wordt ook
omgezet naar een lijst, maar let erop dat het resultaat van je functie WEL DEGELIJK een NumPy-tabel
MOET zijn.
K = kernmatrix(3, 4, 1, 2) print(K) #[[ 3.53553391e-01 -3.53553391e-01 -3.53553391e-01 3.53553391e-01] # [ 2.49979981e-17 -2.49979981e-17 -2.49979981e-17 2.49979981e-17] # [ -3.53553391e-01 3.53553391e-01 3.53553391e-01 -3.53553391e-01]] M, N = 4, 6Met
a = np.array([[10.*i + j for j in range(N)] for i in range(M)])komt er
print(a) #[[ 0. 1. 2. 3. 4. 5.] # [ 10. 11. 12. 13. 14. 15.] # [ 20. 21. 22. 23. 24. 25.] # [ 30. 31. 32. 33. 34. 35.]] b = dct_2D(a) print(b) #[[ 8.57321410e+01 -8.32512359e+00 -1.42108547e-14 -8.16496581e-01 -5.32907052e-15 -1.60157782e-01] # [ -5.46344602e+01 -7.10542736e-15 1.06581410e-14 8.88178420e-15 1.77635684e-15 1.50990331e-14] # [ -1.06581410e-14 0.00000000e+00 1.33226763e-15 -8.88178420e-16 -3.55271368e-15 -3.55271368e-15] # [ -3.88275154e+00 1.77635684e-15 5.32907052e-15 1.77635684e-15 1.77635684e-15 -8.88178420e-16]] b_2 = dct_beeld(np.array(a, dtype = float), 2, 3) print(b_2) #[[ 1.46969385e+01 -2.00000000e+00 8.88178420e-16 2.20454077e+01 -2.00000000e+00 8.88178420e-16] # [ -1.22474487e+01 0.00000000e+00 0.00000000e+00 -1.22474487e+01 -8.88178420e-16 -8.88178420e-16] # [ 6.36867333e+01 -2.00000000e+00 3.55271368e-15 7.10352025e+01 -2.00000000e+00 1.77635684e-15] # [ -1.22474487e+01 0.00000000e+00 1.77635684e-15 -1.22474487e+01 0.00000000e+00 0.00000000e+00]]