# Fourier on Meshes¶


This tour explores the use of the eigenvectors of the Laplacian, for filtering and for compression.

In [2]:
addpath('toolbox_signal')


## Fourier Basis on Meshes¶

The Fourier basis are defined as the eigenvector of the Laplacian.

In [3]:
name = 'elephant-50kv';
options.name = name;
n = size(vertex,2);


The combinatorial laplacian is a linear operator (thus a NxN matrix where N is the number of vertices). It depends only on the connectivity of the mesh, thus on face only.

Compute edge list.

In [4]:
E = [faces([1 2],:) faces([2 3],:) faces([3 1],:)];
p = size(E,2);


In [5]:
W = sparse( E(1,:), E(2,:), ones(p,1) );
W = max(W,W');


Compute the combinatorial Laplacian, stored as a sparse matrix.

In [6]:
D = spdiags(sum(W)', 0, n,n);
L = D-W;


The eigenvector of this matrix forms an orthogonal basis of the vector space of signal of NxN values (one real value per vertex). Those functions are the extension of the Fourier oscillating functions to surfaces. For a small mesh (less than 1000) vertices, one can compute this set of vectors using the |eig| functions. For large meshes, one can compute only a small (e.g. 50) number of low pass eigenvectors using the sparse eigenvector extraction procedure, |eigs|.

Compute the eigenvectors.

In [7]:
nb = 80;
opts.disp = 0;
[U,S] = eigs(L,nb,'SM',opts);
S = diag(S);


Order the eigenvector by increasing frequencies.

In [8]:
[S,I] = sort(S, 'ascend');
U = real( U(:,I) );


Plot the eigenvalues. This corresponds to the spectrum of the triangulation. It depends only on the topology of the mesh.

In [9]:
clf;
plot(S); axis('tight');


Display a sub-set of eigenvectors.

In [10]:
ilist = round(linspace(3,nb, 6));
tau=2.2; % saturation for display
clf;
for i=1:length(ilist)
v = real(U(:,ilist(i)));
v = clamp( v/std(v),-tau,tau );
options.face_vertex_color = v;
subplot(2,3,i);
plot_mesh(vertex,faces,options);
colormap jet(256);
end


## Linear Approximation over the Fourier Domain¶

Linear approximation is obtained by keeping only the low frequency coefficient. This corresponds to a low pass filtering, since high frequency coefficients are removed.

Compute the projection of each coordinate |vertex(i,:)| on the small set of |nb| frequencies.

In [11]:
pvertex = vertex*U;


Display the spectrum pf.

In [12]:
clf;
plot(pvertex'); axis('tight');
legend('X', 'Y', 'Z');


Reconstruct the mesh.

In [13]:
vertex1 = pvertex*U';


Compare before and after approximation.

In [14]:
clf;
subplot(1,2,1);
plot_mesh(vertex,faces);
subplot(1,2,2);
plot_mesh(vertex1,faces);


Exercise 1

Show the smoothed mesh for an increasing number of Fourier frequencies |nb|.

In [15]:
exo1()

In [16]:
%% Insert your code here.


## Non-linear Approximation over the Fourier Domain¶

Non-linear approximation is obtained by keeping the largest magnitude coefficients. It is more efficient than linear approximation since the L2 error is reduced.

We study here the approximation on a small mesh, to be able to compute all the wavelet coefficients.

In [17]:
name = 'venus';
options.name = name;
n = size(vertex,2);


Compute the combinatorial laplacian operator |L| of the mesh.

In [18]:
E = [faces([1 2],:) faces([2 3],:) faces([3 1],:)];
W = sparse( E(1,:), E(2,:), ones(size(E,2),1) );
W = max(W,W');
L = spdiags(sum(W)', 0, n,n) - W;


Compute the full set of eigenvector.

In [19]:
[U,S] = eig(full(L));
S = diag(S);
[S,I] = sort(S, 'ascend');
U = real( U(:,I) );


Plot the eigenvalues.

In [20]:
clf;
plot(S); axis('tight');


Exercise 2

Compute a best |m|-term non-linear approximation whith |m=.1*n|, by hard thresholding the Fourier coefficients using the correct threshold. Compare with linear |m| term approximation (use |m/3| coefficient for each coordinate X/Y/Z). on linear inear isplay

In [21]:
exo2()

Linear:     SNR=22dB
Non-linear: SNR=24.2dB

In [22]:
%% Insert your code here.


Exercise 3

Compare the rate-distortion curve (log of error as a function of the log of the number of coefficients) for linear and non-linear approximation. onlinear inear ormalize isplay

In [23]:
exo3()