Ich möchte Sie auf diese sehr aufschlussreiche Grafik aus Wikipedia hinweisen, die veranschaulicht, wie man eine bilineare Interpolation für einen Punkt durchführt:
Quelle: Wikipedia
Wie man sieht, sind die vier roten Punkte das, was bekannt ist. Diese Punkte kennt man vorher und P
ist der Punkt, den wir interpolieren wollen. Wir müssen also zwei Schritte durchführen (wie Sie in Ihrem Beitrag angedeutet haben). Um die Koordinate x
(horizontal) zu behandeln, müssen wir berechnen, wie hoch der interpolierte Wert zeilenweise für die oberste Reihe der roten Punkte und die unterste Reihe der roten Punkte ist. Daraus ergeben sich die beiden blauen Punkte R1
und R2
. Um die y
-Koordinate (vertikal) zu behandeln, verwenden wir die beiden blauen Punkte und interpolieren vertikal, um den endgültigen P
-Punkt zu erhalten.
Wenn Sie die Größe eines Bildes ändern, auch wenn wir visuell nicht sehen, was ich jetzt sagen werde, aber stellen Sie sich vor, dass dieses Bild ein 3D-Signal f
ist. Jeder Punkt in der Matrix ist in der Tat eine 3D-Koordinate, wobei die Spaltenposition der x
-Wert, die Zeilenposition der y
-Wert und der z
-Wert die Menge / der Graustufenwert der Matrix selbst ist. Daher ist z = f(x,y)
der Wert der Matrix an der Position (x,y)
in der Matrix. Da es sich in unserem Fall um Bilder handelt, ist jeder Wert von (x,y)
eine ganze Zahl, die von 1 bis zu so vielen Zeilen/Spalten geht, wie wir haben, je nachdem, welche Dimension Sie betrachten.
Angesichts der Koordinate, die Sie an (x,y)
interpolieren möchten, und angesichts der roten Koordinaten im obigen Bild, die wir gemäß dem Diagramm x1,y1,x2,y2
nennen – wobei wir uns speziell an die Konvention des Diagramms halten und darauf verweisen, wie auf Bilder zugegriffen wird: x1 = 1, x2 = 2, y1 = 2, y2 = 1
, die blauen Koordinaten R1
und R2
werden durch 1D-Interpolation spaltenweise berechnet, wobei dieselbe Zeile verwendet wird, auf der beide Punkte zusammenfallen:
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))
Es ist wichtig zu beachten, dass (x - x1) / (x2 - x1)
eine Gewichtung/ein Anteil ist, der angibt, wie viel von einer Mischung zwischen den beiden Werten f(x1,y1)
und f(x2,y1)
für R1
oder f(x1,y2)
und f(x2,y2)
für R2
die Ausgabe ausmacht. Konkret ist x1
der Ausgangspunkt und (x2 - x1)
ist die Differenz der x
-Werte. Wenn man x1
als x
einsetzt, erhält man 0, während x2
als x
1 ergibt. Dieses Gewicht schwankt zwischen , was für die Berechnungen erforderlich ist.
Es ist zu beachten, dass sich der Ursprung des Bildes in der linken oberen Ecke befindet, so dass (1,1)
in der linken oberen Ecke liegt. Sobald Sie R1
und R2
gefunden haben, können wir P
durch zeilenweises Interpolieren finden:
P = R2 + (y - y2)/(y2 - y1)*(R1 - R2)
Auch hier bezeichnet (y - y2) / (y2 - y1)
den Anteil / die Mischung, wie viel R1
und R2
zum endgültigen Ergebnis P
beitragen. Du hast also f5
richtig berechnet, weil du vier bekannte Punkte verwendet hast: Oben links ist 100, oben rechts ist 50, unten links ist 70 und unten rechts ist 20. Wenn Sie f5
berechnen wollen, bedeutet das konkret, dass (x,y) = (1.5,1.5)
, weil wir uns in der Mitte zwischen 100 und 50 befinden, weil Sie das Bild um zwei skalieren. Wenn Sie diese Werte in die obige Berechnung einfügen, erhalten Sie wie erwartet den Wert 60. Die Gewichte für beide Berechnungen ergeben ebenfalls 0.5
, das ist der Wert, den Sie in Ihren Berechnungen erhalten haben und den wir auch erwarten.
Wenn Sie f1
berechnen, entspricht dies (x,y) = (1.5,1)
, und wenn Sie dies in die obige Gleichung einsetzen, sehen Sie, dass (y - y2)/(y2 - y1)
den Wert 0 ergibt oder die Gewichtung 0 ist, so dass nur R2
berechnet wird, was der linearen Interpolation nur entlang der obersten Zeile entspricht. Wenn wir f7
berechnet haben, bedeutet dies, dass wir bei (x,y) = (1.5,2)
interpolieren wollen. In diesem Fall ist (y - y2) / (y2 - y1)
1 oder die Gewichtung ist 1 und somit P = R2 + (R1 - R2)
, was vereinfacht R1
ist und der linearen Interpolation nur entlang der unteren Reihe entspricht.
Nun gibt es den Fall von f3
und f5
. Diese beiden Werte entsprechen (x,y) = (1,1.5)
bzw. (x,y) = (2,1.5)
. Setzt man diese Werte für R1
und R2
und P
ein, erhält man für beide Fälle:
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
Was sagt uns das? Das bedeutet, dass Sie nur entlang der y-Richtung interpolieren. Dies wird deutlich, wenn wir einen Blick auf P
werfen. Wenn man die Berechnungen von P
für f3
und f5
genauer betrachtet, sieht man, dass wir nur Werte entlang der vertikalen Richtung betrachten.
Wenn man also eine endgültige Antwort haben möchte, werden f1
und f7
durch Interpolation entlang der x
/Spaltenrichtung nur entlang derselben Zeile gefunden. f3
und f5
werden durch Interpolation von y
/ Zeilenrichtung entlang derselben Spalte gefunden. f4
verwendet eine Mischung aus f1
und f7
, um den endgültigen Wert zu berechnen, wie Sie bereits gesehen haben.
Um Ihre letzte Frage zu beantworten, werden f2
, f6
und f8
je nach persönlicher Vorliebe ausgefüllt. Die Werte x
und y
liegen beide im Bereich 2.5
und damit außerhalb des -Rasters für
(x,y)
. In MATLAB wird dies standardmäßig so implementiert, dass alle Werte außerhalb der definierten Grenzen als Nicht-eine-Zahl (NaN
) aufgefüllt werden. Manchmal wird jedoch mit linearer Interpolation extrapoliert, die Randwerte werden kopiert oder es werden aufwendige Auffüllungen wie symmetrische oder kreisförmige Auffüllungen vorgenommen. Es hängt von der jeweiligen Situation ab, aber es gibt keine richtige und endgültige Antwort darauf, wie f2
, f6
und f8
auszufüllen sind – alles hängt von der jeweiligen Anwendung ab und davon, was für Sie am sinnvollsten ist.
Als Bonus können wir überprüfen, ob meine Berechnungen in MATLAB korrekt sind. Wir definieren zunächst ein Gitter mit (x,y)
Punkten im Bereich und verkleinern dann das Bild, so dass es doppelt so groß ist, wobei wir eine Auflösung von 0,5 pro Punkt statt 1 angeben. Ich nenne die von Ihnen definierte Matrix
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
Das ursprüngliche (x,y)
Punktraster sieht wie folgt aus:
>> XX = 1 2 1 2>> YY = 1 1 2 2
Das erweiterte Raster, um die Größe der Matrix um das Doppelte zu vergrößern, sieht wie folgt aus:
>> 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
ist die Ausgabe unter Verwendung von X
und Y
als ursprüngliches Punktraster und X2
und Y2
sind die Punkte, an denen wir interpolieren wollen.
Wir erhalten:
>> BB = 100 75 50 NaN 85 60 35 NaN 70 45 20 NaN NaN NaN NaN NaN