我得到了通过双线性插值缩放图像的代码。我知道这是可行的,但我无法弄清楚如果近似像素值是边缘(边缘我的意思是它在最后一行或最后一列)像素中的一件事会怎样输入图像然后我可以 gt 坐标 (x+1,y+1) 的像素,这应该会导致数组索引超出范围错误,但没有发生这样的错误,为什么?
代码是:
public int[] resizeBilinearGray(int[] pixels, int w, int h, int w2, int h2) {
int[] temp = new int[w2*h2] ;
int A, B, C, D, x, y, index, gray ;
float x_ratio = ((float)(w-1))/w2 ;
float y_ratio = ((float)(h-1))/h2 ;
float x_diff, y_diff, ya, yb ;
int offset = 0 ;
for (int i=0;i<h2;i++) {
for (int j=0;j<w2;j++) {
x = (int)(x_ratio * j) ;
y = (int)(y_ratio * i) ;
x_diff = (x_ratio * j) - x ;
y_diff = (y_ratio * i) - y ;
index = y*w+x ;
// range is 0 to 255 thus bitwise AND with 0xff
A = pixels[index] & 0xff ;
B = pixels[index+1] & 0xff ;
C = pixels[index+w] & 0xff ;
D = pixels[index+w+1] & 0xff ;
// Y = A(1-w)(1-h) + B(w)(1-h) + C(h)(1-w) + Dwh
gray = (int)(
A*(1-x_diff)*(1-y_diff) + B*(x_diff)*(1-y_diff) +
C*(y_diff)*(1-x_diff) + D*(x_diff*y_diff)
) ;
temp[offset++] = gray ;
}
}
return temp ;
}
原因是x_ratio
and y_ratio
计算不正确。
考虑最后一行的最后一个像素:
i=h2, j=w2
then:
x = x_ratio * j = (w-1)/w2 * (w2-1) = (w-1) * (w2-1)/w2 <= w-1
y = y_ratio * i = (h-1)/h2 * (h2-1) = (h-1) * (h2-1)/h2 <= h-1
index = y*w+x <= (h-1)*w + (w-1) < w*h
所以索引总是小于pixels
array.
但请注意,这是一个非常肮脏的黑客行为,这将导致结果不准确,尤其是对于小图像。
您应该按如下方式计算宽度/高度比:
float x_ratio = ((float)w)/w2;
float y_ratio = ((float)h)/h2;
并创建一个将坐标转换为数组索引的函数 - 让我们命名它coord2index
。该函数考虑了超出范围的坐标并实现了所谓的边界选项, which 模拟图像边界之外有像素。
边界的常见选项有:
对称的- 图像边界之外的像素通过在边界处镜面反射图像来计算。在这种情况下,这可能是最好的可能性。
复制- 假设图像边界之外的像素等于边界处最近的像素。这是最简单的方法。
circular- 图像实际上在所有方向上周期性地重复。用于一些高级图像处理算法;不利于图像调整大小。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)