Skip to content

Commit

Permalink
add files
Browse files Browse the repository at this point in the history
  • Loading branch information
sabidea23 committed Dec 20, 2021
0 parents commit a6e51ef
Show file tree
Hide file tree
Showing 27 changed files with 889 additions and 0 deletions.
62 changes: 62 additions & 0 deletions README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
Dinu Andreea Sabina

->Interpolaea nearest-neighbour

Pentru functia nn 2x2(f, STEP) am gandit matricea finala ca fiind
impartita in 4 zone distincte, de replicare a valorilor functiei f.
Valoarea pixelului din imaginea finala este data de pozitia sa intr-o
astfel de zona. Pentru cazul unei imagini colorate, am extras matricele
corespunzatoare fiecarui canal de culoare, pentru care am aplicat functia
de mai sus, iar in final am format matricea finala.

Pentru functia nn resize(I, p, q), in cadrul calculului
celor 2 constante de scalare, am tinut cont de pozitionarea pixelilor din
imaginea finala, deoarece in Octave indexarea incepe de la 1, nu de la 0.
Matricea de transformare are pe diagonala principala factorii de scalara,
in rest 0. Pentru fiecare pixel (x, y) din imaginea finala, am aplicat matricea inversa
de transformare am trecut in coordonatele imaginii initiale si am obtinut coordonatele (x_p, y_p).
Spre deosebire de functia nn 2x2(f, STEP), aici am folosit functia de rotunjire round(),
pentru simplificare. Pentru cazul unei imagini colorate, am extras matricele
corespunzatoare fiecarui canal de culoare, pentru care am aplicat functia
de mai sus, iar in final am format matricea finala.

->Interpolaea biliniara

La acest task imi apar warning-uri la compilare, insa obtin punctajul pentru
toate testele.
Pentru calcularea coeficientilor biliniari, am calculat pe rand fiecare
coloana a matricei A si am rezolvat sistemul de ecuatii liniare folosind operatorul
specific din Octave, "/", afland vectorul de coeficienti.
Pentru functia de resize, dupa calculul coordonatelor (x_p, y_p), am aflat
coordonatele punctelor care le inconjoara,apeland surrounding_points(). Pentru
aproximarea in sus am folosit functia ceil, iar pentru aproximare in jos,
functia fix. Am aflat coeficientii biliniari si am calculat valoarea pixelului
din imaginea finala cu ajutorul acestora.
Pentru functia bilinear_rotate, atunci cand coordonatele (x_p, y_p) nu se incadeaza in
dimensiunile imaginii, am pus un pixel negru (=0) si am trecut la calculul urmatorii valori
din matricea finala.

-> Interpolare bicubica

Pentru aproximarea derivatelor am tinut cont ca se considera si coordonatele x, y = −1
si x, y = 2 si la marginile imaginii am considerat ca derivatele sunt 0.
La calcularea matricelor ce contin derivatele, am parcurs matricele cu 2 for-uri, iar
acolo unde erau probleme la functia de aproximare, am inceput for-ul de la 2, pentru a
fi sigura ca nu vor intra pe conditia pentru coordonatele care sunt la margine.

->Feedback

Consider ca ideea de interpolare pe fotografii a fost una foarte interesanta si bine aleasa
pentru tema noastra. Scheletul de cod este foarte bine realizat, indicatiile sunt clare,
si indicatiile din pdf-ul temei sunt complete. Am putut realiza usor tema, in ciuda faptului
ca nu sunt foarte priceputa la scris cod Octave. M-am bucurat sa invat atat de multe lucruri
despre fotografii si alcatuirea lor din pixeli, sa aflu functii cu care sa le citesc
sub forma unei matrice precum imread si sa testez manual testele de la checker, pentru a
intelege mai bine algoritmul. De asemenea, am apreciat raspunsurile rapide si clare la
intrebarile de pe forum, care m-au ajutat si pe mine la implementare.

->Punctaj obtinut local

nearest-neighbour: 30p
bilinear: 30p
bicubic : 35p
18 changes: 18 additions & 0 deletions bicubic/bicubic_coef.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
function A = bicubic_coef(f, Ix, Iy, Ixy, x1, y1, x2, y2)
% =========================================================================
% Calculeaza coeficientii de interpolare bicubica pentru 4 puncte alaturate
% =========================================================================

% TODO: calculeaza matricile intermediare
B = [f(y1, x1) f(y2,x1) Iy(y1, x1) Iy(y2, x1);
f(y1, x2) f(y2,x2) Iy(y1, x2) Iy(y2, x2);
Ix(y1, x1) Ix(y2,x1) Ixy(y1, x1) Ixy(y2, x1);
Ix(y1, x2) Ix(y2,x2) Ixy(y1, x2) Ixy(y2, x2)];

% TODO: converteste matricile intermediare la double
B = double(B);

% TODO: calculeaza matricea finala
C = [1 0 0 0; 0 0 1 0; -3 3 -2 -1; 2 -2 1 1];
A = C * B * C';
endfunction
91 changes: 91 additions & 0 deletions bicubic/bicubic_resize.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
function R = bicubic_resize(I, p, q)
% =========================================================================
% Upscaling de imagine folosind algoritmul de interpolare bicubica
% Transforma imaginea I din dimensiune m x n in dimensiune p x q
% =========================================================================

[m n nr_colors] = size(I);

% initializeaza matricea finala
R = zeros(p, q);

% TODO: cast I la double
I = double(I);

% daca imaginea e alb negru, ignora
if nr_colors > 1
R = -1;
return
endif

% Obs:
% Atunci cand se aplica o scalare, punctul (0, 0) al imaginii nu se va
% deplasa.
% In Octave, pixelii imaginilor sunt indexati de la 1 la n.
% Daca se lucreaza in indici de la 1 la n si se inmulteste x si y cu s_x
% si s_y, atunci originea imaginii se va deplasa de la (1, 1) la (sx, sy)!
% De aceea, trebuie lucrat cu indici in intervalul de la 0 la n - 1!

% TODO: calculeaza factorii de scalare
% Obs: daca se lucreaza cu indici in intervalul [0, n - 1], ultimul
% pixel al imaginii se va deplasa de la (m - 1, n - 1) la (p, q).
% s_x nu va fi q ./ n

s_x = (q - 1) / (n - 1);
s_y = (p - 1) / (m - 1);
scale = [s_x s_y];

% TODO: defineste matricea de transformare pentru redimensionare
Trans = diag(scale);

% TODO: calculeaza inversa transformarii
Inv_trans = inv(Trans);

% TODO: precalculeaza derivatele
[Ix, Iy, Ixy] = precalc_d(I);

% parcurge fiecare pixel din imagine
% foloseste coordonate de la 0 la n - 1
for y = 0 : p - 1
for x = 0 : q - 1
% TODO: aplica transformarea inversa asupra (x, y) si calculeaza
% x_p si y_p din spatiul imaginii initiale
v = zeros(2,1);
v = Inv_trans * [x y]';
x_p = v(1);
y_p = v(2);

% TODO: trece (xp, yp) din sistemul de coordonate de la 0 la n - 1 in
% sistemul de coordonate de la 1 la n pentru a aplica interpolarea
x_p = x_p + 1;
y_p = y_p + 1;

% TODO: gaseste cele 4 puncte ce inconjoara punctul x, y
[x1 y1 x2 y2] = surrounding_points(m, n, x_p, y_p);

% TODO: calculeaza coeficientii de interpolare A
A = zeros(4);
A = bicubic_coef(I, Ix, Iy, Ixy, x1, y1, x2, y2);

% TODO: trece coordonatele (xp, yp) in patratul unitate, scazand (x1, y1)
x_p = x_p - x1;
y_p = y_p - y1;

% TODO: calculeaza valoarea interpolata a pixelului (x, y)
% Obs: pentru scrierea in imagine, x si y sunt in coordonate de
% la 0 la n - 1 si trebuie aduse in coordonate de la 1 la n
vect_y = [1 y_p y_p^2 y_p^3];
vect_x = [1 x_p x_p^2 x_p^3];
R(y + 1, x + 1) = vect_x * A * vect_y';

endfor
endfor

% TODO: transforma matricea rezultat in uint8 pentru a fi o imagine valida
R = uint8(R);
endfunction





25 changes: 25 additions & 0 deletions bicubic/bicubic_resize_RGB.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
function out = bicubic_resize_RGB(img, p, q)
% =========================================================================
% Redimensioneaza imaginea img a.i. aceasta sa fie de dimensiune p x q.
% Imaginea img este colorata.
% Practic, apeleaza de 3 ori functia nn pe fiecare canal al imaginii.
% =========================================================================

% TODO: extrage canalul rosu al imaginii
R = img(:, :, 1);

% TODO: extrage canalul verde al imaginii
G = img(:, :, 2);

% TODO: extrage canalul albastru al imaginii
B = img(:, :, 3);

% TODO: aplica functia nn pe cele 3 canale ale imaginii
R_resize = bicubic_resize(R, p, q);
G_resize = bicubic_resize(G, p, q);
B_resize = bicubic_resize(B, p, q);

% TODO: formeaza imaginea finala cu cele 3 canale de culori
% Hint: functia cat
out = cat(3, R_resize, G_resize, B_resize);
endfunction
23 changes: 23 additions & 0 deletions bicubic/checker_bicubic.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
function [score] = checker_bicubic()
bicubic_points = 35;

[bicubic_diff, bicubic_diff_max] = test("checker_props/checker-bicubic_diff");
printf("Bicubic derivate: %d / %d teste trecute.\n", bicubic_diff, bicubic_diff_max);

[bicubic_coef, bicubic_coef_max] = test("checker_props/checker-bicubic_coef");
printf("Bicubic coefficients: %d / %d teste trecute.\n", bicubic_coef, bicubic_coef_max);

[bicubic_resize, bicubic_resize_max] = test("checker_props/checker-bicubic_resize");
printf("Resize image: %d / %d teste trecute.\n", bicubic_resize, bicubic_resize_max);

[bicubic_resize_RGB, bicubic_resize_RGB_max] = test("checker_props/checker-bicubic_resize_RGB");
printf("Resize RGB image: %d / %d teste trecute.\n", bicubic_resize_RGB, bicubic_resize_RGB_max);

score = bicubic_points * (bicubic_diff / bicubic_diff_max / 4 + bicubic_coef / bicubic_coef_max / 4 +
bicubic_resize / bicubic_resize_max / 4 + bicubic_resize_RGB / bicubic_resize_RGB_max / 4);
printf("Punctaj total: %.2f\n", score);

fout = fopen("results", "w");
fprintf(fout, "%.2f", score);
fclose(fout);
endfunction
15 changes: 15 additions & 0 deletions bicubic/fx.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
function r = fx(f, x, y)
% =========================================================================
% Aproximeaza derivata fata de x a lui f in punctul (x, y).
% =========================================================================
[m n nr_colors] = size(f);

if (x - 1 < 1 || x + 1 > n)
r = 0;
return;
endif

% TODO: calculeaza derivata
dif = f(y, x + 1) - f(y, x - 1);
r = dif / 2;
endfunction
21 changes: 21 additions & 0 deletions bicubic/fxy.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
function r = fxy(f, x, y)
% =========================================================================
% Aproximeaza derivata fata de x si y a lui f in punctul (x, y).
% =========================================================================
[m n nr_colors] = size(f);
if (x -1 < 1 || x + 1 > n)
r = 0;
return;
endif

if (y -1 < 1 || y + 1 > m)
r = 0;
return;
endif

% TODO: calculeaza derivata
dif1 = f(y - 1,x - 1) + f(y + 1, x + 1);
dif2 = f(y - 1,x + 1) + f(y + 1, x - 1);
sum = dif1 - dif2;
r = sum / 4;
endfunction
15 changes: 15 additions & 0 deletions bicubic/fy.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
function r = fy(f, x, y)
% =========================================================================
% Aproximeaza derivata fata de y a lui f in punctul (x, y).
% =========================================================================
[m n nr_colors] = size(f);

if (y - 1 < 1 || y + 1 > m)
r = 0;
return;
endif

% TODO: calculeaza derivata
dif = f(y + 1, x) - f(y - 1, x);
r = dif / 2;
endfunction
37 changes: 37 additions & 0 deletions bicubic/precalc_d.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
function [Ix, Iy, Ixy] = precalc_d(I)
% =========================================================================
% Prealculeaza matricile Ix, Iy si Ixy ce contin derivatele dx, dy, dxy ale
% imaginii I pentru fiecare pixel al acesteia
% =========================================================================

% obtine dimensiunea imaginii
[m n nr_colors] = size(I);

% TODO: fa cast matricii I la double
I = double(I);
% TODO: calculeaza matricea cu derivate fata de x Ix
for i = 1: m
for j = 2 : n
if (i == 1 && j == 1)
Ix(i,j) = 0;
break;
endif
Ix(i,j) = fx(I, j,i);
endfor
endfor

% TODO: calculeaza matricea cu derivate fata de y Iy
for i = 2 : m
for j = 1 : n
Iy(i,j) = fy(I, j,i);
endfor
endfor

% TODO: calculeaza matricea cu derivate fata de xy Ixy
for i = 2 : m
for j = 2 : n
Ixy(i,j) = fxy(I, j,i);
endfor
endfor

endfunction
1 change: 1 addition & 0 deletions bicubic/results
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
35.00
24 changes: 24 additions & 0 deletions bicubic/surrounding_points.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
function [x1 y1 x2 y2] = surrounding_points(m, n, x, y)
% =========================================================================
% Calculeaza cele 4 puncte ce contin in interior (x, y)
% Primeste si dimensiunea unei imagini m x n, pentru a asigura ca nu se
% iese din matrice.
% =========================================================================

% TODO: Calculeaza x1, y1, x2, y2
x1 = fix(x);
y1 = fix(y);
x2 = ceil(x);
y2 = ceil(y);

% TODO: daca y se afla pe ultima linie, asigura ca y2 nu o sa iasa din
% matrice (nu o sa fie m + 1 daca y1 = m)
if (y1 == m)
y2 = y2 - 1;
endif

% TODO: analog daca x se afla pe ultima coloana
if (x1 == n)
x2 = x2 - 1;
endif
endfunction
40 changes: 40 additions & 0 deletions bilinear/bilinear_2x2.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
function out = bilinear_2x2(f, STEP = 0.1)

% =========================================================================
% Aplica interpolare biliniara pe imaginea 2x2 f cu puncte intermediare
% echidistante.
% f are valori cunoscute in punctele (1, 1), (1, 2), (2, 1) si (2, 2).
%
% Parametrii:
% - f = imaginea ce se doreste sa fie interpolata
% - STEP = distanta dintre doua puncte succesive
% =========================================================================

% defineste coordonatele x si y ale punctelor intermediare
x_int = 1 : STEP : 2;
y_int = 1 : STEP : 2;

% afla nr. de puncte
n = length(x_int);

% cele 4 punctele incadratoare vor fi aceleasi pentru toate punctele din
% interior
x1 = y1 = 1;
x2 = y2 = 2;

% TODO: calculeaza coeficientii de interpolare biliniara folosind bilinear_coef
a = bilinear_coef(f,x1,y1,x2,y2);

% TODO: initializeaza rezultatul cu o matrice n x n plina de zero
out = zeros(n);
% parcurge fiecare pixel din imaginea finala
for i = 1 : n
for j = 1 : n
% TODO: calculeaza valoarea pixelului
out(j,i) = a(1) + a(2) * x_int(i) + a(3) * y_int(j) + a(4) * x_int(i) * y_int(j);
endfor
endfor

% TODO: converteste rezultatul la uint8 pentru a ramane o imagine
out = uint8(out);
endfunction
Loading

0 comments on commit a6e51ef

Please sign in to comment.