Je voudrais vous indiquer ce graphique très perspicace de Wikipedia qui illustre comment faire une interpolation bilinéaire pour un point :
Source : Wikipedia
Comme vous pouvez le voir, les quatre points rouges correspondent à ce qui est connu. Ces points, vous les connaissez à l’avance et P
est le point que nous souhaitons interpoler. En tant que tel, nous devons faire deux étapes (comme vous l’avez indiqué dans votre post). Pour traiter la coordonnée x
(horizontale), nous devons calculer quelle est la valeur interpolée par rangée pour la rangée supérieure de points rouges et la rangée inférieure de points rouges. On obtient ainsi les deux points bleus R1
et R2
. Pour traiter la coordonnée y
(verticale), nous utilisons les deux points bleus et interpolons verticalement pour obtenir le point final P
.
Lorsque vous redimensionnez une image, même si nous ne voyons pas visuellement ce que je vais dire, mais imaginez que cette image est un signal 3D f
. Chaque point de la matrice est en fait une coordonnée 3D où l’emplacement de la colonne est la valeur x
, l’emplacement de la ligne est la valeur y
et la valeur z
est la quantité / valeur de niveau de gris de la matrice elle-même. Par conséquent, faire z = f(x,y)
est la valeur de la matrice à l’emplacement (x,y)
dans la matrice. Dans notre cas, parce que vous avez affaire à des images, chaque valeur de (x,y)
sont des entiers qui vont de 1 jusqu’à autant de lignes/colonnes que nous avons en fonction de la dimension que vous regardez.
Donc, étant donné la coordonnée que vous voulez interpoler à (x,y)
, et étant donné les coordonnées rouges dans l’image ci-dessus, que nous appelons x1,y1,x2,y2
selon le diagramme – allant spécifiquement avec la convention du diagramme et se référant à la façon dont les images sont accessibles : x1 = 1, x2 = 2, y1 = 2, y2 = 1
, les coordonnées bleues R1
et R2
sont calculées par interpolation 1D en colonne en utilisant la même ligne que celle sur laquelle les deux points coïncident :
R1 = f(x1,y1) + (x - x1)/(x2 - x1)*(f(x2,y1) - f(x1,y1))R2 = f(x1,y2) + (x - x1)/(x2 - x1)*(f(x2,y2) - f(x1,y2))
Il est important de noter que (x - x1) / (x2 - x1)
est un poids / une proportion de combien de mélange la sortie consiste entre les deux valeurs vues à f(x1,y1)
et f(x2,y1)
pour R1
ou f(x1,y2)
et f(x2,y2)
pour R2
. Plus précisément, x1
est le point de départ et (x2 - x1)
est la différence des valeurs x
. Vous pouvez vérifier que substituer x1
comme x
nous donne 0 alors que x2
comme x
nous donne 1. Ce poids fluctue entre , ce qui est nécessaire pour que les calculs fonctionnent.
Il faut noter que l’origine de l’image est dans le coin supérieur gauche, et donc (1,1)
est dans le coin supérieur gauche. Une fois que vous avez trouvé R1
et R2
, nous pouvons trouver P
en interpolant par rangées :
P = R2 + (y - y2)/(y2 - y1)*(R1 - R2)
Encore, (y - y2) / (y2 - y1)
dénotent la proportion / le mélange de combien R1
et R2
contribuent au résultat final P
. En tant que tel, vous avez calculé f5
correctement parce que vous avez utilisé quatre points connus : Le haut gauche est 100, le haut droit est 50, le bas gauche est 70 et le bas droit est 20. Plus précisément, si vous voulez calculer f5
, cela signifie que (x,y) = (1.5,1.5)
parce que nous sommes à mi-chemin entre les 100 et 50 en raison du fait que vous mettez l’image à l’échelle par deux. Si vous branchez ces valeurs dans le calcul ci-dessus, vous obtiendrez la valeur de 60 comme prévu. Les pondérations des deux calculs donneront également 0.5
, ce qui correspond à ce que vous avez obtenu dans vos calculs et c’est ce que nous attendons.
Si vous calculez f1
, cela correspond à (x,y) = (1.5,1)
et si vous le substituez dans l’équation ci-dessus, vous verrez que (y - y2)/(y2 - y1)
vous donne 0 ou le poids est 0, et donc ce qui est calculé est juste R2
, correspondant à l’interpolation linéaire le long de la ligne supérieure seulement. De même, si nous avons calculé f7
, cela signifie que nous voulons interpoler à (x,y) = (1.5,2)
. Dans ce cas, vous verrez que (y - y2) / (y2 - y1)
est 1 ou que le poids est 1 et donc P = R2 + (R1 - R2)
, qui se simplifie en R1
et correspond à l’interpolation linéaire le long de la ligne du bas uniquement.
Maintenant, il y a le cas de f3
et f5
. Ces deux valeurs correspondent respectivement à (x,y) = (1,1.5)
et (x,y) = (2,1.5)
. En substituant ces valeurs à R1
et R2
et P
pour les deux cas, on obtient:
f3
R1 = f(1,2) + (1 - 1)/(2 - 1)*(f(2,2) - f(1,2)) = f(1,2)R2 = f(1,1) + (1 - 1)/(2 - 1)*(f(1,2) - f(1,1)) = f(1,1)P = R1 + (1.5 - 1)*(R1 - R2) = f(1,2) + 0.5*(f(1,2) - f(1,1))P = 70 + 0.5*(100 - 70) = 85
f5
R1 = f(1,2) + (2 - 1)/(2 - 1)*(f(2,2) - f(1,2)) = f(2,2)R2 = f(1,1) + (2 - 1)/(2 - 1)*(f(1,2) - f(1,1)) = f(1,2)P = R1 + (1.5 - 1)*(R1 - R2) = f(2,2) + 0.5*(f(2,2) - f(1,2))P = 20 + 0.5*(50 - 20) = 35
Alors, qu’est-ce que cela nous dit ? Cela signifie que vous interpolez uniquement le long de la direction y. Cela est apparent lorsque nous jetons un coup d’œil à P
. En examinant les calculs plus en profondeur de P
pour chacun de f3
et f5
, vous voyez que nous considérons les valeurs le long de la direction verticale seulement.
Ainsi, si vous voulez une réponse définitive, f1
et f7
sont trouvés en interpolant le long de la direction x
/ colonne seulement le long de la même ligne. f3
et f5
sont trouvés en interpolant y
/ direction de la ligne le long de la même colonne. f4
utilise un mélange de f1
et f7
pour calculer la valeur finale, comme vous l’avez déjà vu.
Pour répondre à votre dernière question, f2
, f6
et f8
sont remplis en fonction des préférences personnelles. Ces valeurs sont considérées comme étant hors limites, les valeurs x
et y
étant toutes deux 2.5
et c’est en dehors de notre grille pour
(x,y)
. Dans MATLAB, l’implémentation par défaut consiste à remplir toutes les valeurs situées en dehors des limites définies pour qu’elles ne soient pas un nombre (NaN
), mais parfois, les gens extrapolent en utilisant l’interpolation linéaire, copient les valeurs limites ou effectuent un remplissage élaboré comme un remplissage symétrique ou circulaire. Cela dépend de la situation dans laquelle vous vous trouvez, mais il n’y a pas de réponse correcte et définitive sur la façon de remplir f2
, f6
et f8
– tout dépend de votre application et de ce qui a le plus de sens pour vous.
En prime, nous pouvons vérifier que mes calculs sont corrects dans MATLAB. Nous définissons d’abord une grille de (x,y)
points dans la plage , puis nous redimensionnons l’image pour qu’elle soit deux fois plus grande où nous spécifions une résolution de 0,5 par point plutôt que 1. Je vais appeler votre matrice définie
A
:
A = ; %// Define original matrix = meshgrid(1:2,1:2); %// Define original grid of points = meshgrid(1:0.5:2.5,1:0.5:2.5) %// Define expanded grid of pointsB = interp2(X,Y,A,X2,Y2,'linear'); %// Perform bilinear interpolation
La grille originale de points (x,y)
ressemble à:
>> XX = 1 2 1 2>> YY = 1 1 2 2
La grille étendue pour agrandir la taille de la matrice de deux fois plus ressemble à:
>> X2X2 = 1.0000 1.5000 2.0000 2.5000 1.0000 1.5000 2.0000 2.5000 1.0000 1.5000 2.0000 2.5000 1.0000 1.5000 2.0000 2.5000>> Y2Y2 = 1.0000 1.0000 1.0000 1.0000 1.5000 1.5000 1.5000 1.5000 2.0000 2.0000 2.0000 2.0000 2.5000 2.5000 2.5000 2.5000
B
est la sortie utilisant X
et Y
comme grille originale de points et X2
et Y2
sont les points auxquels nous voulons interpoler.
Nous obtenons:
>> BB = 100 75 50 NaN 85 60 35 NaN 70 45 20 NaN NaN NaN NaN NaN