De nombreux algorithmes de traitement d'image nécessitent de calculer la valeur d'un niveau sur un point qui ne coïncide pas avec un pixel. Cette valeur peut être obtenue par interpolation bilinéaire avec les 4 pixels voisins.
On considère une image en niveaux de gris. Les coordonnées des pixels sont des indices, c'est-à-dire des entiers. On note Vi,j la valeur du pixel (i,j). La figure suivante montre un point M(x,y) quelconque, dont les coordonnées ne sont en général pas entières, avec les 4 pixels qui l'entourent.
Figure pleine pageOn pose :
Une interpolation linéaire sur le côté gauche permet d'obtenir la valeur au point A :
De même pour le point B sur le côté droit :
La valeur au point M est obtenue en faisant une interpolation linéaire entre les points A et B :
Les indices i et j sont les valeurs entières de x et y. Lorsque le point M se trouve sur le bord droit, il faut faire une interpolation linéaire simple entre les points (i,j) et (i,j+1). Il en est de même sur le bord haut (dernier indice j).
La fonction suivante calcule l'interpolation linéaire sur un tableau numpy.
import numpy import math def interpolation(array,x,y): s = array.shape i = math.floor(x) j = math.floor(y) t = x-i u = y-j u1 = 1.0-u t1 = 1.0-t if j==s[0]-1: if i==s[1]-1: return array[j][i] return t*array[j][i]+t1*array[j][i+1] if i==s[1]-1: return u*array[j][i]+u1*array[j+1][i] return t1*u1*array[j][i]+t*u1*array[j][i+1]+t*u*array[j+1][i+1]+t1*u*array[j+1][i]
Comme application simple, considérons l'échantillonnage sur un segment de droite, dans le but d'obtenir un profil de valeur sur ce segment. La fonction suivante prend en argument les deux extrémités du segment et le nombre de points à calculer. Elle renvoit l'abscisse sur le segment et la liste des valeurs correspondantes.
def segment(array,A,B,n): dx = (B[0]-A[0])/(n-1) dy = (B[1]-A[1])/(n-1) ds = math.sqrt(dx*dx+dy*dy) l = numpy.zeros(n) v = numpy.zeros(n) for k in range(n): l[k] = k*ds v[k] = interpolation(array,A[0]+k*dx,A[1]+k*dy) return (l,v)
Exemple :
from PIL import Image from matplotlib.pyplot import * img = Image.open("../../../../simul/image/objets.png") (red,green,blue,alpha)=img.split() array = numpy.array(red) figure(figsize=(4,4)) imshow(array,cmap=cm.gray)figA.pdf
(l,v)=segment(array,[0.0,0.0],[255.0,100.0],300) figure(figsize=(6,6)) plot(l,v)figB.pdf