线性插值
1、定义:
线性插值法是指使用连接两个已知量的直线来确定在这两个已知量之间的一个未知量的值的方法。
2、过程:
已知二维直角坐标系中的两点A(x0,y0)与B(x1,y1),要得到[x0,x1]区间内某一位置x在直线上的值。根据图中所示,我们得到两点式直线方程:
解出y的方程,也就是x的未知值,有:
这样,上式就可以表示成为:
这样通过α就可以直接得到 y。实际上,即使x不在x0到x1之间并且α也不是介于0到1之间,这个公式也是成立的。在这种情况下,这种方法叫作线性外插。已知y求x的过程与以上过程相同,只是x与y要进行交换。
双线性插值
定义:
双线性插值又称为双线性内插.在数学上,双线性插值是有两个变量的插值函数的线性插值扩展,其核心思想是在两个方向分别进行一次线性插值。
假设我们想得到未知函数f在点P(x,y)的值,即:根据红色的已知数据点得到绿色的未知点的待插值;已知函数f在Q11 = (x1,y1)、Q12 = (x1,y2)、Q21 = (x2,y1)以及Q22 = (x2,y2)四个点的值。
首先在x方向进行线性插值,得到:
然后在y方向进行线性插值,得到
注意,如果插值先沿着y方向做,然后沿着x方向做,我们会得到同样的结果。
双线性插值程序:
a、版本一
//双线性插值
PixValue BilinearInterpolation(const float xPos, const float yPos, unsigned char * pdfValue, const int nWidth, const int nHeight,const int channels)
{
float dfBilinearValue[3] = {0,0,0};
//双线性插值计算
int x_floor = xPos;
int x_ceil = (xPos+1);
int y_floor = yPos;
int y_ceil = (yPos+1);
PixValue pixvalue;
pixvalue.valueB = 0;
pixvalue.valueG = 0;
pixvalue.valueR = 0;
//B
float Br1 = (x_ceil - xPos)*pdfValue[(y_ceil*nWidth+x_floor)*channels]
+ (xPos - x_floor)*pdfValue[(y_ceil*nWidth+x_ceil)*channels];
float Br2 = (x_ceil - xPos)*pdfValue[(y_floor*nWidth+x_floor)*channels]
+ (xPos - x_floor)*pdfValue[(y_floor*nWidth+x_ceil)*channels];
dfBilinearValue[0] = (yPos - y_floor)*Br1 + (y_ceil - yPos)*Br2;
//G
float Gr1 = (x_ceil - xPos)*pdfValue[(y_floor*nWidth+x_floor)*channels+1]
+ (xPos- x_floor)*pdfValue[(y_ceil*nWidth+x_ceil)*channels+1];
float Gr2 = (x_ceil - xPos)*pdfValue[(y_floor*nWidth+x_floor)*channels+1]
+ (xPos - x_floor)*pdfValue[(y_floor*nWidth+x_ceil)*channels+1];
dfBilinearValue[1] = (yPos - y_floor)*Gr1 + (y_ceil - yPos)*Gr2;
//R
float Rr1 = (x_ceil - xPos)*pdfValue[(y_ceil*nWidth+x_floor)*channels+2]
+ (xPos - x_floor)*pdfValue[(y_ceil*nWidth+x_ceil)*channels+2];
float Rr2 = (x_ceil - xPos)*pdfValue[(y_floor*nWidth+x_floor)*channels+2]
+ (xPos - x_floor)*pdfValue[(y_floor*nWidth+x_ceil)*channels+2];
dfBilinearValue[2] = (yPos - y_floor)*Rr1 + (y_ceil - yPos)*Rr2;
pixvalue.valueB = (unsigned char)dfBilinearValue[0];
pixvalue.valueG = (unsigned char)dfBilinearValue[1];
pixvalue.valueR = (unsigned char)dfBilinearValue[2];
return pixvalue; // 所有波段都是无效值才返回false
}
b、版本二
void BilinearInterpolation(PixInfo &pix, unsigned char *pdfValue, unsigned char *dstValue,const int index,const int channels)
{
//双线性插值计算
int x_floor = pix.xPos;//向下取整
int y_floor = pix.yPos;//向下取整
int PartX = (pix.xPos - x_floor)*2048;
int PartY = (pix.yPos - y_floor)*2048;
int InvX = 2048 - PartX;
int InvY = 2048 - PartY;
int TL = y_floor*Samstride + x_floor*channels;//计算取样点左上角邻近的那个像素点的内存地址索引号
int BL = TL + Samstride;//左下角像素点地址
//R
int Br1 = InvX*pdfValue[BL]+ PartX*pdfValue[BL+3];
int Br2 = InvX*pdfValue[TL] + PartX*pdfValue[TL+3];
dstValue[index] = (PartY*Br1 + InvY*Br2)>>22;
//G
int Gr1 = InvX*pdfValue[BL+1] + PartX*pdfValue[BL+4];
int Gr2 = InvX*pdfValue[TL+1] + PartX*pdfValue[TL+4];
dstValue[index+1] = (PartY*Gr1 + InvY*Gr2)>>22;
//B
int Rr1 = InvX*pdfValue[BL+2] + PartX*pdfValue[BL+5];
int Rr2 = InvX*pdfValue[TL+2] + PartX*pdfValue[TL+5];
dstValue[index+2] = (PartY*Rr1 + InvY*Rr2)>>22;
}
附:
http://www.cnblogs.com/Imageshop/archive/2011/11/12/2246808.html
https://en.wikipedia.org/wiki/Linear_interpolation
https://en.wikipedia.org/wiki/Bilinear_interpolation
http://blog.youkuaiyun.com/u013146742/article/details/52923864
http://www.cnblogs.com/enigma19971/p/5828447.html