2

我需要使用双线性插值调整图像大小并创建图像金字塔。我将检测金字塔不同级别的角点并缩放像素坐标,使它们与最大图像的尺寸相关。

如果在所有级别中将对象的角检测为角/关键点/特征,则在缩放不同级别的相应像素坐标以使其落在最大图像上之后,理想情况下我希望它们具有相同的价值。因此,在调整图像大小时,我会尽可能准确。

假设我正在调整图像 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 个像素。

请让我知道您的想法以及我的第二段代码中是否有任何错误。就视觉效果而言,它们运行良好。但是是的,我似乎确实注意到关键点与第二段代码更好地对齐。但可能是因为我有偏见:-)。

提前致谢。

4

0 回答 0