バイリニア画像補間/スケーリング – 計算例

Wikipedia から、1 点に対するバイリニア補間の方法を説明する、非常に洞察力のあるグラフィックを紹介します。 Wikipedia

見てのとおり、4 つの赤い点は既知のものです。 これらの点は事前に分かっていることで、Pは補間したい点です。 このように、(ご指摘の通り)2つのステップを行う必要があります。 xの座標(水平方向)を処理するために、赤い点の上の列と赤い点の下の列について、補間される値が何であるかを行単位で計算する必要があります。 この結果、2つの青い点R1R2が得られる。 y座標(垂直)を処理するために、2つの青いポイントを使い、垂直方向に補間して、最終的にPポイントを得ます。

画像をリサイズするとき、これから言うことは視覚的に見えないけれど、この画像は3次元信号fだと想像してみてください。 行列の各点は、実際には、列の位置がx値、行の位置がy値、z値が行列自体の量・階調値である3次元座標です。 したがって、z = f(x,y)を行うと、行列の(x,y)の位置の行列の値になります。 この場合、画像を扱っているので、(x,y) の各値は、見ている次元に応じて 1 から行/列の数だけある整数です。

したがって、(x,y) で補間したい座標が与えられ、上の画像の赤い座標、つまり図では x1,y1,x2,y2 と呼んでいますが、特に図の慣習に従って、画像へのアクセス方法を参照することにしましょう。 x1 = 1, x2 = 2, y1 = 2, y2 = 1, 青い座標 R1R2 は、両方の点が一致する同じ行を使って列方向に 1 次補間して計算されます:

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

ここで重要なのは、(x - x1) / (x2 - x1) が、R1 では f(x1,y1)f(x2,y1)R2 では f(x1,y2)f(x2,y2) で見た二つの値の間の、出力をどれだけ混合するか、重み/比率であることに注目する必要があることです。 具体的には、x1が出発点、(x2 - x1)xの値の差となる。 x1xに代入すると0になり、x2xに代入すると1になることが確認できる。 この重さは、計算がうまくいくために必要なの間で変動します。

注意すべきは、画像の原点が左上にあるため、(1,1)は左上にあることです。 5698>と<2996>を求めたら、行単位で補間して<1635>を求めます:<5008><7651><4947>ここでも<7679>は、<5698>と<2996>が最終出力<1635>にどれだけ貢献するかの割合/混合を表します。 このように、f5を正しく計算できたのは、4つの既知の点を使ったからです。 左上が100、右上が50、左下が70、右下が20です。 具体的には、f5を計算したい場合、画像を2倍に拡大する関係で100と50の中間になっているので、(x,y) = (1.5,1.5)となるわけです。 これらの値を上記の計算に突っ込めば、予想通り60という値が得られます。 また、両方の計算の重みは0.5となり、これはあなたが計算で得たものであり、私たちが期待するものです。

f1を計算すると、これは(x,y) = (1.5,1)に相当し、これを上の式に代入すると、(y - y2)/(y2 - y1)では0、つまり重みが0となり、計算されるのはR2だけで、上の行だけに沿った線形補間に相当することが分かります。 同様に、f7と計算された場合、これは(x,y) = (1.5,2)で補間したいことを意味します。 この場合、(y - y2) / (y2 - y1)は1、つまり重みが1なのでP = R2 + (R1 - R2)となり、単純化してR1となり、下の行のみに沿った線形補間となることがわかります。

さて、f3f5のケースがあります。 これらはそれぞれ(x,y) = (1,1.5)(x,y) = (2,1.5)に相当する。 これらの値をR1R2に代入すると、両方のケースでPが得られる:

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

さて、これで何がわかるでしょうか。 これは、Y方向にのみ補間していることを意味します。 このことは、Pを見てみると明らかです。 f3f5のそれぞれについて、Pの計算をより徹底的に調べると、縦方向に沿った値だけを考えていることがわかります。

そのため、決定的な答えを求めるなら、f1f7は同じ行に沿ってx/列方向だけに沿って補間して求めていることになります。 f3f5は、同じ列に沿ったy/列方向の補間で求めます。 f4 は、すでに見たように f1f7 を混合して最終値を計算しています。

最後の質問の答えですが、f2f6f8 は個人の好みで記入されているものです。 これらの値は、xyの値がともに2.5で、(x,y)グリッドの外側であるため、境界外であると考えられます。 MATLABのデフォルトの実装では、定義された境界の外側の値はすべて数字ではない値(NaN)に埋められますが、時には、線形補間を使用して外挿したり、境界の値をコピーしたり、対称パディングや円形パディングなどの手の込んだパディングを実行したりすることもできます。 どのような状況にあるかにもよりますが、f2f6f8 をどのように埋めるかについて、正しくて決定的な答えはありません – それはすべて、あなたのアプリケーションとあなたにとって最も意味のあることによります。 まず、 範囲の (x,y) 点のグリッドを定義し、次に、1 点あたり 1 ではなく 0.5 の解像度を指定し、画像が 2 倍になるようにリサイズします。 定義された行列を 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

元の (x,y) 点のグリッドは次のようになります:

>> XX = 1 2 1 2>> YY = 1 1 2 2

行列のサイズを2倍に拡大したグリッドは次のようになります:

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

BXY が元の点のグリッド、X2Y2 が補間する点で、出力はこのようなものです。

で、

>> BB = 100 75 50 NaN 85 60 35 NaN 70 45 20 NaN NaN NaN NaN NaN

となります。

コメントする