我需要使用双线性插值调整图像大小并创建图像金字塔。我将检测金字塔不同级别的角点并缩放像素坐标,使它们与最大图像的尺寸相关。
如果在所有级别中将对象的角检测为角/关键点/特征,则在缩放不同级别的相应像素坐标以使其落在最大图像上之后,理想情况下我希望它们具有相同的价值。因此,在调整图像大小时,我会尽可能准确。
假设我正在调整图像 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;
}
}
第二段代码是假设像素中心的坐标像 (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。
但在第二段代码中我会得到
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 个像素。
请让我知道您的想法以及我的第二段代码中是否有任何错误。就视觉效果而言,它们运行良好。但是是的,我似乎确实注意到关键点与第二段代码更好地对齐。但可能是因为我有偏见:-)。
提前致谢。