バイリニア補間を使用して画像のサイズを変更し、画像ピラミッドを作成する必要があります。ピラミッドのさまざまなレベルでコーナーを検出し、ピクセル座標をスケーリングして、最大画像の寸法に相対的になるようにします。
オブジェクトのコーナーがすべてのレベルでコーナー/キーポイント/機能として検出された場合、異なるレベルから対応するピクセル座標をスケーリングして最大の画像に収まるようにした後、理想的にはそれらが同じであることを望みます価値。したがって、画像のサイズを変更するときは、できるだけ正確にしようとしています。
画像 L_n_minus_1 のサイズを変更して、より小さな画像 L_n を作成するとします。私のスケール係数は「比率」です(比率> 1)。
※どの図書館も使えません。
以下の疑似コードを使用してサイズを変更できます (これは、サイズ変更アルゴリズムをオンラインで検索したときに通常見つけられるものです)。
int offset = 0;
for (int i = 0; i < height_of_L_n; i++){
for (int j = 0; j < width_of_L_n; j++){
//********* This part will differ in the later version I provided below
//
int xSrcInt = (int)(ratio * j);
float xDiff = ratio * j - xSrcInt;
int ySrcInt = (int)(ratio * i);
float yDiff = ratio * i - ySrcInt;
// The above code will differ in the later version I provided below
index = (ySrcInt * width_of_L_n_minus_1 + xSrcInt);
//Get the 4 pixel values to interpolate
a = L_n_minus_1[index];
b = L_n_minus_1[index + 1];
c = L_n_minus_1[index + width_of_L_n_minus_1];
d = L_n_minus_1[index + width_of_L_n_minus_1 + 1];
//Calculate the co-efficients for interpolation
float c0 = (1 - x_diff)*(1 - y_diff);
float c1 = (x_diff)*(1 - y_diff);
float c2 = (y_diff)*(1 - x_diff);
float c3 = (x_diff*y_diff);
//half is added for rounding the pixel intensity.
int intensity = (a*c0) + (b*c1) + (c*c2) + (d*c3) + 0.5;
if (intensity > 255)
intensity = 255;
L_n[offset++] = intensity;
}
}
または、以下の変更されたコードを使用できます。
int offset = 0;
for (int i = 0; i < height_of_L_n; i++){
for (int j = 0; j < width_of_L_n; j++){
// Here the code differs from the first piece of code
// Assume pixel centers start from (0.5,0.5). The top left pixel has co-ordinate (0.5,0.5)
// 0.5 is added to go to the co-ordinates where top left pixel has co-ordinate (0.5,0.5)
// 0.5 is subtracted to go to the generally used co-ordinates where top left pixel has co-ordinate (0,0)
// or in other words map the new co-ordinates to array indices
int xSrcInt = int((ratio * (j + 0.5)) - 0.5);
float xDiff = (ratio * (j + 0.5)) - 0.5 - xSrcInt;
int ySrcInt = int((ratio * (i + 0.5)) - 0.5);
float yDiff = (ratio * (i + 0.5)) - 0.5 - ySrcInt;
// Difference with previous code ends here
index = (ySrcInt * width_of_L_n_minus_1 + xSrcInt);
//Get the 4 pixel values to interpolate
a = L_n_minus_1[index];
b = L_n_minus_1[index + 1];
c = L_n_minus_1[index + width_of_L_n_minus_1];
d = L_n_minus_1[index + width_of_L_n_minus_1 + 1];
//Calculate the co-efficients for interpolation
float c0 = (1 - x_diff)*(1 - y_diff);
float c1 = (x_diff)*(1 - y_diff);
float c2 = (y_diff)*(1 - x_diff);
float c3 = (x_diff*y_diff);
//half is added for rounding the pixel intensity.
int intensity = (a*c0) + (b*c1) + (c*c2) + (d*c3) + 0.5;
if (intensity > 255)
intensity = 255;
L_n[offset++] = intensity;
}
}
2 番目のコードは、ピクセルの中心が (0.5, 0.5) のような座標を持つと想定して開発されました。このようにして、左上のピクセルの座標は (0.5, 0.5) になります。
仮定しましょう:
2 x 2 の宛先イメージが 4 x 4 のソース イメージからサイズ変更されています。
最初のコードでは、最初のピクセルの座標が (0,0) であると想定されているため、たとえば私の比率は 2 です。
xSrcInt = (int)(0*2); // 0 ySrcInt = (int)(0*2); // 0
xDiff = (0*2) - 0; // 0 yDiff = (0*2) - 0; // 0
したがって、c0 が 1 になり、c1、c2、および c3 が 0 になるため、事実上、ソースから最初のピクセル値をコピーするだけです。
しかし、2番目のコードでは取得します
xSrcInt = (int)((0.5*2) - 0.5); // 0; ySrcInt = (int)((0.5*2) - 0.5); // 0;
xDiff = ((0.5*2) - 0.5) - 0; // 0.5; yDiff = ((0.5*2) - 0.5) - 0; // 0.5;
この場合、c0、c1、c2、および c3 はすべて 0.25 になります。したがって、左上の 4 ピクセルを使用します。
どう思うか、私の 2 番目のコードにバグがあるかどうか教えてください。視覚的な結果に関する限り、完全に機能しています。しかし、はい、キーポイントと 2 番目のコードの配置が改善されていることに気付いたようです。しかし、それは私が偏見で判断しているためかもしれません:-)。
前もって感謝します。