Table des matières Python

Interpolation bilinéaire

1. Introduction

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.

2. Interpolation bilinéaire

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.

figureA.svgFigure pleine page

On pose :

t=x-i(1)u=y-j(2)

Une interpolation linéaire sur le côté gauche permet d'obtenir la valeur au point A :

VA=(1-u)Vi,j+uVi,j+1(3)

De même pour le point B sur le côté droit :

VB=(1-u)Vi+1,j+uVi+1,j+1(4)

La valeur au point M est obtenue en faisant une interpolation linéaire entre les points A et B :

VM=(1-t)VA+tVB=(1-t)(1-u)Vi,j+t(1-u)Vi+1,j+tuVi+1,j+1+(1-t)uVi,j+1(5)

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).

3. Fonction python

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]
            

4. Application

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)
             
figAfigA.pdf
(l,v)=segment(array,[0.0,0.0],[255.0,100.0],300)
figure(figsize=(6,6))
plot(l,v)
             
figBfigB.pdf
Creative Commons LicenseTextes et figures sont mis à disposition sous contrat Creative Commons.