插值算法

线性插值

1、定义:
线性插值法是指使用连接两个已知量的直线来确定在这两个已知量之间的一个未知量的值的方法。
2、过程:
已知二维直角坐标系中的两点A(x0,y0)与B(x1,y1),要得到[x0,x1]区间内某一位置x在直线上的值。根据图中所示,我们得到两点式直线方程:

 

解出y的方程,也就是x的未知值,有:



这样,上式就可以表示成为:


这样通过α就可以直接得到 y。实际上,即使x不在x0x1之间并且α也不是介于01之间,这个公式也是成立的。在这种情况下,这种方法叫作线性外插。已知yx的过程与以上过程相同,只是xy要进行交换

双线性插值

定义:
双线性插值又称为双线性内插.在数学上,双线性插值是有两个变量的插值函数的线性插值扩展,其核心思想是在两个方向分别进行一次线性插值。
假设我们想得到未知函数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.csdn.net/u013146742/article/details/52923864

http://www.cnblogs.com/enigma19971/p/5828447.html


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值