双线性插值,又称为双线性内插。在数学上,双线性插值是有两个变量的插值函数的线性插值扩展,其核心思想是在两个方向分别进行一次线性插值。(摘自)
公式如见百度百科
由图可以看出,放大的图像之后,当出现x、y方向都放大一倍时,x、y位于x1、x2、y1、y2的中心点。
当放大倍数不为1时,那么就会出现即将绘制的像素偏向于哪个像素,因此需要求得这个像素的值就需要按比例对相邻的像素进行计算。
由图可以看出更偏向于x1,y1
首先求缩放倍率:
wscale =src.width/dst.width;
hscale = src.height/dst.height;
求源图对应像素
sx = dx*wscale;
sy = dy*hscale;
获得左一、上一像素:
X1= int(sx);
Y1= int(sy);
X2=X1 + 1
Y2= Y1 + 1
求权重:
weightx= sx – X1
weighty= sy – Y1;
求(x,y)点的像素值
tlx= (1-weightx)*F(X1,X1); //左上
trx= weightx*F(X2, Y1); //右上
blx= (1 – weightx)*F(X1, Y2); //左下
brx= weightx * F(X2,Y2); //右下
ty= (1 - weighty) * (tlx + trx);
by= weighty * (blx + brx);
F(X,Y)= ty + by;
伪代码
bilinear(src, dst)
{
//求比例
wscale = src.width / dst.width;
hscale = src.height / dst.height;
for(dy = 0; dy < dst.height; dy++){
//得到源图像Y方向最近的像素点
sy = dy * hscale;
Y1 = int(sy);
Y2 = Y1 + 1;
//求权重
weighty = sy - Y1;
for(dx = 0; dx < dst.width; dx++){
//得到源图像X方向最近的像素点
sx = dx * wscale;
X1 = int(sx);
X2 = X1 + 1;
weightx = sx - X1;
//计算与最近像素的值
tlx = (1 - weightx) * src.data[X1 + Y1 * src.width];
trx = weightx * src.data[X2 + Y1 * src.width];
blx = (1 - weightx) * src.data[X1 + Y2 * src.width];
brx = weightx * src.data[X2 + Y2 * src.width];
ty = (1 - weighty) * (tlx + trx);
by = weighty * (blx + brx);
dst.data[dx + dy * dst.width]= ty + by;
}
}
}