Un petit bout de code pour faire une Interpolation par spline cubique.

Par exemple pour avoir une estimation de la valeur d'un pixel de coordonnées non entiere. Utile, entre autres, dans les algos de redimensionnement


L'oeil de Lena (Agrandissement x 10)
A gauche: Interpolation plus proche pixel
A droite: Interpolation spline cubique

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
 
/**
 * Interpolation par Spline Cubique
 * 
 * @author Xavier Philippeau
 *
 */
public class Interpolate {
 
	// spline factor in the range [-1,0]
	private double a = -0.5;
 
	// original image
	private Channel channel = null;
 
	public Interpolate(Channel c) {
		this.channel = c;
	}
 
	// --- Spline coefficients ----------------------------------------------------
 
	// C0(t) = -at3 + at2 
	private double C0(double t) {
		return -a*t*t*t + a*t*t;
	}
 
	// C1(t) = -(a+2)t3 + (2a+3)t2 - at 
	private double C1(double t) {
		return -(a+2)*t*t*t + (2*a+3)*t*t - a*t;
	}
 
	// C2(t) = (a+2)t3 - (a+3)t2 + 1 
	private double C2(double t) {
		return (a+2)*t*t*t - (a+3)*t*t + 1;
	}
 
	// C3(t) = at3 - 2at2 + at 
	private double C3(double t) {
		return a*t*t*t - 2*a*t*t + a*t;
	}
 
	// --- Continous interpolation from discrete values ---------------------------
 
	// discret value for pixel of coordinates: i (integer) , j (integer)
	private double f(int i, int j) {
		return this.channel.getValue(i, j);
	}
 
	// compute interpolated value for pixel of coordinates: x (real) , j (integer)
	private double H(int j, double x) {
		int i = (int)x;
		return f(i-1,j)*C3(x-i) + f(i,j)*C2(x-i) + f(i+1,j)* C1(x-i) + f(i+2,j)*C0(x-i);
	}
 
	// compute interpolated value for pixel of coordinates: x (real) , y (real)
	public double value(double x, double y) {
		int j = (int)y;
		return H(j-1,x)*C3(y-j) + H(j,x)*C2(y-j) + H(j+1,x)*C1(y-j) + H(j+2,x)*C0(y-j);
	}
}
NB: Comme toujours, ce code est volontairement non optimisé. Pour info, on peut diviser par deux le nombre de multiplications, et egalement précalculer les valeurs des coefficients...