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:

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.

Voorbeeld

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, 6
Met
 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]]