Bilineare Bildinterpolation / Skalierung – Ein Rechenbeispiel

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

Schreibe einen Kommentar