精华内容
下载资源
问答
  • 上次的前菜——Lagrange插值相信难不倒聪明的小侠客们,是否还记得上次讲到Lagrange插值在每次有新的插值点增加时,整个Lagrange基函数就需要重新构建,这会大大增加计算量。还没有学习过常用的时序插值算法()的小...

    点击上方“算法数据侠”,选择“星标”公众号

    第一时间获取最新推文与资源分享d0fb9113e1cc31e25c12d46d6fadabd9.png小侠客们好呀,我是oubahe。上次的前菜——Lagrange插值相信难不倒聪明的小侠客们,是否还记得上次讲到Lagrange插值在每次有新的插值点增加时,整个Lagrange基函数就需要重新构建,这会大大增加计算量。还没有学习过常用的时序插值算法(一)的小侠客可以通过下方的传送门赶快脑补一波~

    常用的时序插值算法(一)

    今天的插值算法相信很多小侠客在大学本科就已经线性代数或者数值分析中学习过——大名鼎鼎的牛顿插值法(Newton Interpolation Method)。Newton插值与Lagrange插值不同的是,它引入了差商的概念,使其在插值节点增加时仍然能保持较高效率的计算。内容较短,争取十分钟以内学习完,begin~

    75b1926072f523a77541207fbaf01f85.gif

    01

    Newton插值原理

    假设插值节点为x0, x1, ... , xn,拟考虑函数组如下:

    3a3a36af11b548b09d7429adc06fd6e7.png其中fk(x)是k次多项式,它们之间是线性无关的,因此可以使用它们来构造基函数。我们可以看到,该基函数的一个优点是当增加一个新的插值节点xn+1时,只需要在原有基函数的基础上增加一个新的函数fn+1(x)即可,其中:862dbcd300466b7acc60cb3be0ed7e91.png那么,我们就得到了Newton插值多项式的表达式为:9454f6b6fb07dd66207390050822976e.png

    其中,ak=[y0, y1, ..., yk]表示差商,fk(x)为Newton插值的基函数。

    下面简单介绍一下差商的流程。

    假设我们已知的节点为x0, x1, ... , xn,那么得到关于节点xi, xj的一阶差商为:

    76a9026ca481ca53f1171b9541f1c77a.png

    关于节点xi, xj和xk的二阶差商为:

    86d863a278cf5ef0854d35ea341f29c0.png

    那么我们可以得到关于x0, x1, ..., xk的k阶差商为:

    6e600565b26ce97c17875253fa531a57.png

    这一幕有些熟悉了嘛,利用差商的递推,我们就可以构造差商来计算差商啦,进而也就可以得到得到了Newton插值多项式N(x)。将数据集中缺失点的x值代入得到的N(x)便可以进行插值填充。02动手干

    下面是python版本的Newton插值算法具体实现,可以根据自己的数据集情况实操一下Newton插值填充流程哟。

    import numpy as npdef difference_quotient(x_val, y_val):    '''    this function is to calculate the difference quotient    '''    assert len(x_val) == len(y_val)     n = len(x_val)                   p = np.zeros((n, n+1))           p[:, 0] = x_val                  p[:, 1] = y_val                  for j in range(2, n+1):              p[j-1: n, j] = (p[j-1: n, j-1] - p[j-2: n-1, j-1]) / (x_val[j-1: n] - x_val[: n+1-j])        q = np.diag(p, k=1)    return p, qdef newton_interpolate(x_val, y_val, x):    '''    this function is to compolish newton interpolate    '''    _, q = difference_quotient(x_val, y_val)       def basis(i):        if i > 0:            l_i = [(x - x_val[j]) for j in range(i)]        else:            l_i = [1]        return reduce(operator.mul, l_i) * q[i]    return sum(basis(i) for i in range(len(x_val)))
    03结语但是,无论是Lagrange插值还是Newton插值,本质上还是用一个高阶多项式来尽可能地拟合所给的已知点分布原始函数。多项式插值有很明显的缺陷在于,若已知点太少,则插值出来的函数与原始函数偏离较大,返回的插值结果会对算法模型造成较大影响;另一方面,若已知点太多,则拟合的多项式阶数会迅速增加,太高的阶数容易导致插值在边缘处出现龙格现象。有没有一种插值算法来避免高次插值多项式这一缺陷呢?哈哈,后面即将登场的分段线性插值便可以解决上述问题,具体内容我们下次再聊。我是oubahe,下次再见咯~

    码字虽少,原创不易。分享是快乐的源泉,来个素质三连 —>点击左下角分享 —> 右下角点赞—>右下角在看本文,可以汇聚好运气召唤神龙哟~

    98b86811fd3867051fbf7f88cf3acde1.gif

    e7ecce8a968a8b28e4a6c8279199c344.png

    展开全文
  • 通过计算行列式的值,对几种Hermite插值多项式的存在唯一性给出另种证明方法,对带不完全导数的m(m≥4)Hermite插值多项式,给出推广的基函数构造方法,并对带不完全导数的三及四Hermite插值多项式的具体实例,给...
  • 双三次插值(BiCubic插值)

    千次阅读 2018-11-26 11:13:02
    双三次插值(BiCubic插值 ) 双三次插值又称立方卷积插值。三次卷积插值是种更加复杂的插值方式。该算法利用待采样点周围16个点的灰度值作三次插值,...这种算法需要选取插值基函数来拟合数据,其最常用的插值基...

                         双三次插值(BiCubic插值 )

    双三次插值又称立方卷积插值。三次卷积插值是一种更加复杂的插值方式。该算法利用待采样点周围16个点的灰度值作三次插值,不仅考虑到4 个直接相邻点的灰度影响,而且考虑到各邻点间灰度值变化率的影响。三次运算可以得到更接近高分辨率图像的放大效果,但也导致了运算量的急剧增加。这种算法需要选取插值基函数来拟合数据,其最常用的插值基函数如图1所示,本次实验采用如图所示函数作为基函数。

    图像放大并进行BiCubic插值 Matlab/C++代码点击打开链接

     假设源图像A大小为m*n,缩放K倍后的目标图像B的大小为M*N,即K=M/m。A的每一个像素点是已知的,B是未知的,我们想要求出目标图像B中每一像素点(X,Y)的值,必须先找出像素(X,Y)在源图像A中对应的像素(x,y),再根据源图像A距离像素(x,y)最近的16个像素点作为计算目标图像B(X,Y)处像素值的参数,利用BiCubic基函数求出16个像素点的权重,图B像素(x,y)的值就等于16个像素点的加权叠加。

     

     根据比例关系x/X=m/M=1/K,我们可以得到B(X,Y)在A上的对应坐标为A(x,y)=A(X*(m/M),Y*(n/N))=A(X/K,Y/K)。如图所示P点就是目标图像B在(X,Y)处对应于源图像A中的位置,P的坐标位置会出现小数部分,所以我们假设 P的坐标为P(x+u,y+v),其中x,y分别表示整数部分,u,v分别表示小数部分(蓝点到a11方格中红点的距离)。那么我们就可以得到如图所示的最近16个像素的位置,在这里用a(i,j)(i,j=0,1,2,3)来表示,如上图。

     

     我们要做的就是求出BiCubic函数中的参数x,从而获得上面所说的16个像素所对应的权重W(x)。BiCubic基函数是一维的,而像素是二维的,所以我们将像素点的行与列分开计算。BiCubic函数中的参数x表示该像素点到P点的距离,例如a00距离P(x+u,y+v)的距离为(1+u,1+v),因此a00的横坐标权重i_0=W(1+u),纵坐标权重j_0=W(1+v),a00对B(X,Y)的贡献值为:(a00像素值)* i_0* j_0。因此,a0X的横坐标权重分别为W(1+u),W(u),W(1-u),W(2-u);ay0的纵坐标权重分别为W(1+v),W(v),W(1-v),W(2-v);B(X,Y)像素值为:

     

    上述可以用矩阵形式表示,下面图片来源:点击打开链接

    加权算法(a可以不取-0.5):

    Matlab代码:

    %双三次插值具体实现
    clc,clear;
    fff=imread('E:\Documents\BUPT\DIP\图片\lena.bmp'); 
    ff =rgb2gray(fff);%转化为灰度图像
    [mm,nn]=size(ff);               %将图像隔行隔列抽取元素,得到缩小的图像f
    m=mm/2;
    n=nn/2;
    f =zeros(m,n);
    for i=1:m
       for j=1:n
         f(i,j)=ff(2*i,2*j);
       end
    end
    
    k=5;                       %设置放大倍数
    bijiao1 =imresize(f,k,'bilinear');%双线性插值结果比较
    bijiao =uint8(bijiao1);
    
    a=f(1,:);
    c=f(m,:);             %将待插值图像矩阵前后各扩展两行两列,共扩展四行四列
    b=[f(1,1),f(1,1),f(:,1)',f(m,1),f(m,1)];
    d=[f(1,n),f(1,n),f(:,n)',f(m,n),f(m,n)];
    a1=[a;a;f;c;c];
    b1=[b;b;a1';d;d];
    ffff=b1';
    f1=double(ffff);
    g1 =zeros(k*m,k*n);
    fori=1:k*m                 %利用双三次插值公式对新图象所有像素赋值
       u=rem(i,k)/k;
    i1=floor(i/k)+2;
       A=[sw(1+u) sw(u) sw(1-u) sw(2-u)];  
      for j=1:k*n
         v=rem(j,k)/k;
    j1=floor(j/k)+2;
         C=[sw(1+v);sw(v);sw(1-v);sw(2-v)];
         B=[f1(i1-1,j1-1) f1(i1-1,j1) f1(i1-1,j1+1)f1(i1-1,j1+2)
           f1(i1,j1-1)   f1(i1,j1)  f1(i1,j1+1)   f1(i1,j1+2)
           f1(i1+1,j1-1)   f1(i1+1,j1) f1(i1+1,j1+1) f1(i1+1,j1+2)
           f1(i1+2,j1-1) f1(i1+2,j1) f1(i1+2,j1+1)f1(i1+2,j1+2)];
         g1(i,j)=(A*B*C);
       end
    end
    g=uint8(g1); 
    
    imshow(uint8(f));title('缩小的图像');             %显示缩小的图像
    figure,imshow(ff);title('原图');               %显示原图像
    figure,imshow(g);title('双三次插值放大的图像');     %显示插值后的图像
    figure,imshow(bijiao);title('双线性插值放大结果');     %显示插值后的图像 
    mse=0;
    ff=double(ff);
    g=double(g);            
    ff2=fftshift(fft2(ff));   %计算原图像和插值图像的傅立叶幅度谱                            
    g2=fftshift(fft2(g));
    figure,subplot(1,2,1),imshow(log(abs(ff2)),[8,10]);title('原图像的傅立叶幅度谱');
    subplot(1,2,2),imshow(log(abs(g2)),[8,10]);title('双三次插值图像的傅立叶幅度谱');
    
    基函数代码:
    functionA=sw(w1)
    w=abs(w1);
    ifw<1&&w>=0
       A=1-2*w^2+w^3;
    elseifw>=1&&w<2
       A=4-8*w+5*w^2-w^3;
    else
      A=0;
    end

    C++代码:

    
    #include "opencv2/imgproc/imgproc.hpp"
    #include "opencv2/highgui/highgui.hpp"
    #include <iostream>
    #include <cmath>
    #include <fstream>
    using namespace cv;
    using namespace std;
    #define PI 3.14159265
    float BiCubicPoly(float x);
    void MyScaleBiCubicInter(Mat& src, Mat& dst, float TransMat[3][3]);
    /**
     * @function main
     */
    int main( int argc, char** argv )
    {
      // load image
      char* imageName = "images/Lenna_256.png";
      Mat image;
      image = imread(imageName,1);
     
      if(!image.data)
      {
    	  cout << "No image data" << endl;
    	  return -1;
      }
      // show image
      namedWindow("image", CV_WINDOW_AUTOSIZE);
      imshow("image", image);  
      Mat dst;
      float transMat[3][3] = { {2.0, 0, 0}, {0, 2.0, 0}, {0, 0, 1} };
     
      MyScaleBiCubicInter(image, dst, transMat);
      namedWindow("out_image", CV_WINDOW_AUTOSIZE);
      imshow("out_image", dst);
      imwrite("Lenna_scale_biCubic2.jpg", dst);
      waitKey(0);
      return 0;
    }
    float BiCubicPoly(float x)
    {
    	float abs_x = abs(x);
    	float a = -0.5;
    	if( abs_x <= 1.0 )
    	{
    		return (a+2)*pow(abs_x,3) - (a+3)*pow(abs_x,2) + 1;
    	}
    	else if( abs_x < 2.0 )
    	{
    		return a*pow(abs_x,3) - 5*a*pow(abs_x,2) + 8*a*abs_x - 4*a;
    	}
    	else
    		return 0.0;
    }
     
    void MyScaleBiCubicInter(Mat& src, Mat& dst, float TransMat[3][3])
    {
    	CV_Assert(src.data);
    	CV_Assert(src.depth() != sizeof(uchar));
    	
    	// calculate margin point of dst image
    	float left =  0;
    	float right =  0;
    	float top =  0;
    	float down =  0;
     
    	float x = src.cols * 1.0f;
    	float y = 0.0f;
    	float u1 = x * TransMat[0][0] + y * TransMat[0][1];
    	float v1 = x * TransMat[1][0] + y * TransMat[1][1];
    	x = src.cols * 1.0f;
    	y = src.rows * 1.0f;
    	float u2 = x * TransMat[0][0] + y * TransMat[0][1];
    	float v2 = x * TransMat[1][0] + y * TransMat[1][1];
    	x = 0.0f;
    	y = src.rows * 1.0f;
    	float u3 = x * TransMat[0][0] + y * TransMat[0][1];
    	float v3 = x * TransMat[1][0] + y * TransMat[1][1];
     
    	left =  min( min( min(0.0f,u1), u2 ), u3);
    	right =  max( max( max(0.0f,u1), u2 ), u3);
    	top =  min( min( min(0.0f,v1), v2 ), v3);
    	down =  max( max( max(0.0f,v1), v2 ), v3);
     
    	// create dst image
    	dst.create(int(abs(right-left)), int(abs(down-top)), src.type());	
     
    	CV_Assert( dst.channels() == src.channels() );
    	int channels = dst.channels();
     
    	int i,j;
    	uchar* p;
    	uchar* q0;
    	uchar* q1;
    	uchar* q2;
    	uchar* q3;
    	for( i = 0; i < dst.rows; ++i)
    	{
    		p = dst.ptr<uchar>(i);
    		for ( j = 0; j < dst.cols; ++j)
    		{
    			// 
    			x = (j+left)/TransMat[0][0]  ; 
    			y = (i+top)/TransMat[1][1] ;
     
    			int x0 = int(x) - 1;
    			int y0 = int(y) - 1;
    			int x1 = int(x);
    			int y1 = int(y);
    			int x2 = int(x) + 1;
    			int y2 = int(y) + 1;
    			int x3 = int(x) + 2;
    			int y3 = int(y) + 2;
     
    			if( (x0 >= 0) && (x3 < src.cols) && (y0 >= 0) && (y3 < src.rows) ) 
    			{
    				q0 = src.ptr<uchar>(y0);
    				q1 = src.ptr<uchar>(y1);
    				q2 = src.ptr<uchar>(y2);
    				q3 = src.ptr<uchar>(y3);
    				
    				float dist_x0 = BiCubicPoly(x-x0);
    				float dist_x1 = BiCubicPoly(x-x1);
    				float dist_x2 = BiCubicPoly(x-x2);
    				float dist_x3 = BiCubicPoly(x-x3);
    				float dist_y0 = BiCubicPoly(y-y0);
    				float dist_y1 = BiCubicPoly(y-y1);
    				float dist_y2 = BiCubicPoly(y-y2);
    				float dist_y3 = BiCubicPoly(y-y3);
     
    				float dist_x0y0 = dist_x0 * dist_y0;
    				float dist_x0y1 = dist_x0 * dist_y1;
    				float dist_x0y2 = dist_x0 * dist_y2;
    				float dist_x0y3 = dist_x0 * dist_y3;
    				float dist_x1y0 = dist_x1 * dist_y0;
    				float dist_x1y1 = dist_x1 * dist_y1;
    				float dist_x1y2 = dist_x1 * dist_y2;
    				float dist_x1y3 = dist_x1 * dist_y3;
    				float dist_x2y0 = dist_x2 * dist_y0;
    				float dist_x2y1 = dist_x2 * dist_y1;
    				float dist_x2y2 = dist_x2 * dist_y2;
    				float dist_x2y3 = dist_x2 * dist_y3;
    				float dist_x3y0 = dist_x3 * dist_y0;
    				float dist_x3y1 = dist_x3 * dist_y1;
    				float dist_x3y2 = dist_x3 * dist_y2;
    				float dist_x3y3 = dist_x3 * dist_y3;
    				
    				switch(channels)
    				{
    					case 1:
    						{
    							break;
    						}
    					case 3:
    						{
    							p[3*j] =    (uchar)(q0[3*x0] * dist_x0y0 +
    												q1[3*x0] * dist_x0y1 +
    												q2[3*x0] * dist_x0y2 +
    												q3[3*x0] * dist_x0y3 +
    												q0[3*x1] * dist_x1y0 +
    												q1[3*x1] * dist_x1y1 +
    												q2[3*x1] * dist_x1y2 +
    												q3[3*x1] * dist_x1y3 +
    												q0[3*x2] * dist_x2y0 +
    												q1[3*x2] * dist_x2y1 +
    												q2[3*x2] * dist_x2y2 +
    												q3[3*x2] * dist_x2y3 +
    												q0[3*x3] * dist_x3y0 +
    												q1[3*x3] * dist_x3y1 +
    												q2[3*x3] * dist_x3y2 +
    												q3[3*x3] * dist_x3y3 ) ;
     
    							p[3*j+1] =  (uchar)(q0[3*x0+1] * dist_x0y0 +
    												q1[3*x0+1] * dist_x0y1 +
    												q2[3*x0+1] * dist_x0y2 +
    												q3[3*x0+1] * dist_x0y3 +
    												q0[3*x1+1] * dist_x1y0 +
    												q1[3*x1+1] * dist_x1y1 +
    												q2[3*x1+1] * dist_x1y2 +
    												q3[3*x1+1] * dist_x1y3 +
    												q0[3*x2+1] * dist_x2y0 +
    												q1[3*x2+1] * dist_x2y1 +
    												q2[3*x2+1] * dist_x2y2 +
    												q3[3*x2+1] * dist_x2y3 +
    												q0[3*x3+1] * dist_x3y0 +
    												q1[3*x3+1] * dist_x3y1 +
    												q2[3*x3+1] * dist_x3y2 +
    												q3[3*x3+1] * dist_x3y3 ) ;
     
    							p[3*j+2] =  (uchar)(q0[3*x0+2] * dist_x0y0 +
    												q1[3*x0+2] * dist_x0y1 +
    												q2[3*x0+2] * dist_x0y2 +
    												q3[3*x0+2] * dist_x0y3 +
    												q0[3*x1+2] * dist_x1y0 +
    												q1[3*x1+2] * dist_x1y1 +
    												q2[3*x1+2] * dist_x1y2 +
    												q3[3*x1+2] * dist_x1y3 +
    												q0[3*x2+2] * dist_x2y0 +
    												q1[3*x2+2] * dist_x2y1 +
    												q2[3*x2+2] * dist_x2y2 +
    												q3[3*x2+2] * dist_x2y3 +
    												q0[3*x3+2] * dist_x3y0 +
    												q1[3*x3+2] * dist_x3y1 +
    												q2[3*x3+2] * dist_x3y2 +
    												q3[3*x3+2] * dist_x3y3 ) ;
     
    							float thre = 198.0f;
    							if( (abs(p[3*j]-q1[3*x1]) > thre) || (abs(p[3*j+1]-q1[3*x1+1]) > thre) ||
    								(abs(p[3*j+2]-q1[3*x1+2]) > thre) )
    							{
    								p[3*j] = q1[3*x1];
    								p[3*j+1] = q1[3*x1+1];
    								p[3*j+2] = q1[3*x1+2];
    							}					
    							break;
    						}
    				}
    			}
    		}
    	}
    }

    【转载】https://blog.csdn.net/qq_34885184/article/details/79163991

                  https://blog.csdn.net/u010555688/article/details/24352343

    展开全文
  • 双三次插值 又称立方卷积插值。 三次卷积插值是种更加复杂的插值方式。...这种算法需要选取插值基函数来拟合数据,其最常用的插值基函数如图1所示,本次实验采用如图所示函数作为基函数。 假设源图像A大...

    具体推导参考:https://blog.csdn.net/qq_24451605/article/details/49474113
    双三次插值
    又称立方卷积插值。
    三次卷积插值是一种更加复杂的插值方式。
    该算法利用待采样点 周围16个点的灰度值三次插值,不仅考虑到4 个直接相邻点的灰度影响而且考虑到各邻点间灰度值变化率的影响
    三次运算可以得到更接近高分辨率图像的放大效果,但也导致了运算量的急剧增加。这种算法需要选取插值基函数来拟合数据,其最常用的插值基函数如图1所示,本次实验采用如图所示函数作为基函数。
    在这里插入图片描述
    假设源图像A大小为mn,缩放K倍后的目标图像B的大小为MN,即K=M/m。
    A的每一个像素点是已知的,B是未知的,我们想要求出目标图像B中每一像素点(X,Y)的值,
    必须先找出像素(X,Y)在源图像A中对应的像素(x,y),
    根据源图像A距离像素(x,y)最近的16个像素点作为计算目标图像B(X,Y)处像素值的参数,利用BiCubic基函数求出16个像素点的权重,图B像素(x,y)的值就等于16个像素点的加权叠加
    在这里插入图片描述
    在这里插入图片描述
    我们要做的就是求出BiCubic函数中的参数x , 从而获得上面所说的16个像素所对应的权重W(x)。
    BiCubic基函数是一维的,而像素是二维的,所以我们将像素点的行与列分开计算
    BiCubic函数中的参数x表示该像素点到P点的距离
    例如a00距离P(x+u,y+v)的距离为(1+u,1+v),因此a00的横坐标权重i_0=W(1+u),纵坐标权重j_0=W(1+v),
    a00对B(X,Y)的贡献值为:(a00像素值)* i_0* j_0。
    因此,a0X的横坐标权重分别为W(1+u),W(u),W(1-u),W(2-u);
    ay0的纵坐标权重分别为W(1+v),W(v),W(1-v),W(2-v);
    B(X,Y)像素值为:
    在这里插入图片描述
    在这里插入图片描述
    代码参考https://blog.csdn.net/Sunny_Future/article/details/90674853
    或者https://www.cnblogs.com/super-JJboom/p/9993431.html

    展开全文
  • 双三次插值 - 插值图像任意位置亚...这种算法需要选取插值基函数来拟合数据,其最常用的插值基函数如图1所示,本次实验采用如图所示函数作为基函数。 加权算法(a可以不取-0.5):点开链接 根据比例关系x/X=m/M=1/K

    双三次插值 - 插值图像任意位置亚像素C++

    一、概念

    双三次插值又称立方卷积插值。三次卷积插值是一种更加复杂的插值方式。该算法利用待采样点周围16个点的灰度值作三次插值,不仅考虑到4 个直接相邻点的灰度影响,而且考虑到各邻点间灰度值变化率的影响。三次运算可得到更接近高分辨率图像的放大效果,但也导致了运算量的急剧增加。这种算法需要选取插值基函数来拟合数据,其最常用的插值基函数如图1所示,本次实验采用如图所示函数作为基函数。

    图1

    加权算法(a可以不取-0.5):点开链接

    根据比例关系x/X=m/M=1/K,我们可以得到B(X,Y)在A上的对应坐标为A(x,y)=A(X*(m/M),Y*(n/N))=A(X/K,Y/K)。如图所示P点就是目标图像B在(X,Y)处对应于源图像A中的位置,P的坐标位置会出现小数部分,所以我们假设 P的坐标为P(x+u,y+v),其中x,y分别表示整数部分,u,v分别表示小数部分(蓝点到a11方格中红点的距离)。那么我们就可以得到如图所示的最近16个像素的位置,在这里用a(i,j)(i,j=0,1,2,3)来表示,如下图。

    图

    我们要做的就是求出BiCubic函数中的参数x,从而获得上面所说的16个像素所对应的权重W(x)。BiCubic基函数是一维的,而像素是二维的,所以我们将像素点的行与列分开计算。BiCubic函数中的参数x表示该像素点到P点的距离,例如a00距离P(x+u,y+v)的距离为(1+u,1+v),因此a00的横坐标权重i_0=W(1+u),纵坐标权重j_0=W(1+v),a00对B(X,Y)的贡献值为:(a00像素值)* i_0* j_0。因此,a0X的横坐标权重分别为W(1+u),W(u),W(1-u),W(2-u);ay0的纵坐标权重分别为W(1+v),W(v),W(1-v),W(2-v);B(X,Y)像素值为:

    图

    二、代码实现C++(可配合读取图片程序使用)

    //功能:双三边插值
    //image:输入图片
    //iImgWidth:图像宽度
    //iImgHeight:图像高度
    //dx,dy:亚像素点与整像素点posy在下x,y上的距离
    //ipos = (posy - 1)*(iImgWidth)+(posx - 1);  //得到ipos
    double CubicPolynomial(unsigned char * image, int iImgWidth, int iImgHeight, double dx, double dy, int ipos)
    {
    	// image为图像各个位置的像素值, iImgWidth为图像的宽度, iImgHeight为图像的高度, ipos为当前插值的位置。
    
    	// 先计算padding 图像的大小。
    	int padding_size = (iImgHeight + 2) * (iImgWidth + 2);
    	double * padding_img = new double[padding_size];
    
    	// 接着对 padding_img 进行赋值。
    	// 将原图像的值赋给padding_img的(2,2)-(iImgHeight+1, iImgWidth+1)
    	// 该部分验证无误。
    	for (int i = 0; i < iImgHeight; i++)
    	{
    		for (int j = 0; j < iImgWidth; j++)
    		{
    			int ipos1 = (i + 1) * (iImgWidth + 2) + (j + 1);
    
    			int temp = i * iImgWidth + j;
    
    			padding_img[ipos1] = image[temp];
    		}
    	}
    
    	// 第一行的值: 第二行、第三行、第四行的值的线性组合.
    	// 该部分验证无误。
    
    	for (int i = 1; i < iImgWidth + 1; i++)
    	{
    		int ipos1 = i;
    
    		double temp1 = padding_img[ipos1 + iImgWidth + 2];
    		double temp2 = padding_img[ipos1 + 2 * (iImgWidth + 2)];
    		double temp3 = padding_img[ipos1 + 3 * (iImgWidth + 2)];
    
    		padding_img[ipos1] = 3 * temp1 - 3 * temp2 + temp3;
    	}
    
    	// 最后一行的值:倒数第二、第三、第四行的值的线性组合。
    	// 该部分验证无误。
    
    	for (int i = 1; i < iImgWidth + 1; i++)
    	{
    		int ipos1 = i + (iImgHeight + 1)*(iImgWidth + 2);
    
    		double temp1 = padding_img[ipos1 - (iImgWidth + 2)];
    		double temp2 = padding_img[ipos1 - 2 * (iImgWidth + 2)];
    		double temp3 = padding_img[ipos1 - 3 * (iImgWidth + 2)];
    
    		padding_img[ipos1] = 3 * temp1 - 3 * temp2 + temp3;
    	}
    
    	// 第一列的值:第二列、第三列、第四列的值的线性组合。
    	// 该部分验证无误。
    	for (int i = 1; i < iImgHeight + 1; i++)
    	{
    		int ipos1 = i * (iImgWidth + 2);
    
    		double temp1 = padding_img[ipos1 + 1];
    		double temp2 = padding_img[ipos1 + 2];
    		double temp3 = padding_img[ipos1 + 3];
    
    		padding_img[ipos1] = 3 * temp1 - 3 * temp2 + temp3;
    	}
    
    	// 最后一列的值:倒数第二、第三、第四列的值的线性组合。
    	// 该部分验证无误。
    	for (int i = 1; i < iImgHeight + 1; i++)
    	{
    		int ipos1 = (i + 1)*(iImgWidth + 2) - 1;
    
    		double temp1 = padding_img[ipos1 - 1];
    		double temp2 = padding_img[ipos1 - 2];
    		double temp3 = padding_img[ipos1 - 3];
    
    		padding_img[ipos1] = 3 * temp1 - 3 * temp2 + temp3;
    	}
    
    	// 后面4个点的组合方向均为列的方向。即ipos+1, ipos+2, ipos+3,或ipos-1, ipos-2, ipos-3.
    
    	// 左上角的点。
    	padding_img[0] = 3 * padding_img[1] - 3 * padding_img[2] + padding_img[3];
    
    	// 右上角的点。
    	padding_img[iImgWidth + 1] = 3 * padding_img[iImgWidth] - 3 * padding_img[iImgWidth - 1] + padding_img[iImgWidth - 2];
    
    	// 左下角的点。
    
    	int pos_left_bottom = (iImgHeight + 1)*(iImgWidth + 2);
    	padding_img[pos_left_bottom] = 3 * padding_img[pos_left_bottom + 1] - 3 * padding_img[pos_left_bottom + 2] + padding_img[pos_left_bottom + 3];
    
    	// 右下角的点。
    
    	int pos_right_bottom = (iImgHeight + 2)*(iImgWidth + 2) - 1;
    	padding_img[pos_right_bottom] = 3 * padding_img[pos_right_bottom - 1] - 3 * padding_img[pos_right_bottom - 2] + padding_img[pos_right_bottom - 3];
    
    
    	// padding结束之后,进行插值操作。首先要把原图的ipos对应到新图的ipos。
    
    	int height = (ipos + 1) / iImgWidth;
    
    	int width = (ipos + 1) - height * iImgWidth;
    
    	// 在新图中的位置。
    
    	int new_ipos = width + (height + 1) * (iImgWidth + 2);
    
    
    	// x方向卷积
    	double dx_2 = dx * dx;
    	double dx_3 = dx * dx*dx;
    	double a4 = (-dx_3 + 2 * dx_2 - dx) / 2;
    	double a5 = (3 * dx_3 - 5 * dx_2 + 2) / 2;
    	double a6 = (-3 * dx_3 + 4 * dx_2 + dx) / 2;
    	double a7 = (dx_3 - dx_2) / 2;
    
    
    
    	double a8 = a4 * padding_img[new_ipos - 1 - (iImgWidth + 2)] + a5 * padding_img[new_ipos - (iImgWidth + 2)] + a6 * padding_img[new_ipos + 1 - (iImgWidth + 2)] + a7 * padding_img[new_ipos + 2 - (iImgWidth + 2)];
    	double a9 = a4 * padding_img[new_ipos - 1] + a5 * padding_img[new_ipos] + a6 * padding_img[new_ipos + 1] + a7 * padding_img[new_ipos + 2];
    	double a10 = a4 * padding_img[new_ipos - 1 + (iImgWidth + 2)] + a5 * padding_img[new_ipos + (iImgWidth + 2)] + a6 * padding_img[new_ipos + 1 + (iImgWidth + 2)] + a7 * padding_img[new_ipos + 2 + (iImgWidth + 2)];
    	double a11 = a4 * padding_img[new_ipos - 1 + 2 * (iImgWidth + 2)] + a5 * padding_img[new_ipos + 2 * (iImgWidth + 2)] + a6 * padding_img[new_ipos + 1 + 2 * (iImgWidth + 2)] + a7 * padding_img[new_ipos + 2 + 2 * (iImgWidth + 2)];
    
    
    
    	// y方向卷积
    	double dy_2 = dy * dy;
    	double dy_3 = dy * dy*dy;
    	double a12 = (-dy_3 + 2 * dy_2 - dy) / 2;
    	double a13 = (3 * dy_3 - 5 * dy_2 + 2) / 2;
    	double a14 = (-3 * dy_3 + 4 * dy_2 + dy) / 2;
    	double a15 = (dy_3 - dy_2) / 2;
    
    	double gray_value;
    	gray_value = a8 * a12 + a9 * a13 + a10 * a14 + a11 * a15;
    
    
    	delete padding_img;
    
    	return gray_value;
    
    
    }
    
    
    

    三、C++代码(基于opencv)

    #include <vector>
    #include "opencv2/core.hpp"
    #include "opencv2/imgproc.hpp"
    #include "opencv2/imgcodecs.hpp"
    #include <opencv2/opencv.hpp>
    #include "bmptools.h"
    #include <cstdlib>
    using namespace std;
    
    using namespace cv;
    
    
    
    double CubicPolynomial(cv::Mat pGray, double dx, double dy, int posx, int posy)
    {	
    	int rows = pGray.rows;
    	int cols = pGray.cols;
    
    	// 创建padding一圈的图像,用来做卷积
    	cv::Mat padded_image = cv::Mat::zeros(rows + 2, cols + 2, CV_64FC1);
    
    	// 将原始图像放置padding图像的中间
    	for (int i = 1; i < padded_image.rows-1; i++)
    	{	
    		for (int j = 1; j < padded_image.cols-1; j++)
    		{
    			double temp = pGray.at<uchar>(i - 1, j - 1);
    			padded_image.at<double>(i, j) = temp;
    		}
    	}
    
    	// 分别计算周围padding一圈的像素值
    	for (int j = 1; j < padded_image.cols-1; j++)
    	{
    		// 第一行
    		padded_image.at<double>(0, j) = 3 * padded_image.at<double>(1, j) - 3 * padded_image.at<double>(2, j) + padded_image.at<double>(3, j);
    		//最后一行
    		padded_image.at<double>(rows + 1, j) = 3 * padded_image.at<double>(rows, j) - 3 * padded_image.at<double>(rows - 1, j) + padded_image.at<double>(rows - 2, j);
    	}
    
    	for (int i = 1; i < padded_image.rows-1; i++)
    	{
    		// 第一列
    		padded_image.at<double>(i, 0) = 3 * padded_image.at<double>(i, 1) - 3 * padded_image.at<double>(i, 2) + padded_image.at<double>(i, 3);
    		// 最后一列
    		padded_image.at<double>(i, cols + 1) = 3 * padded_image.at<double>(i, cols) - 3 * padded_image.at<double>(i, cols - 1) + padded_image.at<double>(i, cols - 2);
    	}
    
    
    	padded_image.at<double>(0, 0) = 3 * padded_image.at<double>(0, 1) - 3 * padded_image.at<double>(0, 2) + padded_image.at<double>(0, 3);
    
    	padded_image.at<double>(0, cols + 1) = 3 * padded_image.at<double>(0, cols) - 3 * padded_image.at<double>(0, cols - 1) + padded_image.at<double>(0, cols - 2);
    
    	padded_image.at<double>(rows + 1, 0) = 3 * padded_image.at<double>(rows + 1, 1) - 3 * padded_image.at<double>(rows + 1, 2) + padded_image.at<double>(rows + 1, 3);
    
    	padded_image.at<double>(rows + 1, cols + 1) = 3 * padded_image.at<double>(rows + 1, cols) - 3 * padded_image.at<double>(rows + 1, cols - 1) + padded_image.at<double>(rows + 1, cols - 2);
    
    	// 卷积的过程
    
    	// x方向卷积
    	double dx_2 = dx*dx;
    	double dx_3 = dx*dx*dx;
    	double a4 = (-dx_3 + 2 * dx_2 - dx) / 2;
    	double a5 = (3 * dx_3 - 5 * dx_2 + 2) / 2;
    	double a6 = (-3 * dx_3 + 4 * dx_2 + dx) / 2;
    	double a7 = (dx_3 - dx_2) / 2;
    
    	double a8 = a4*padded_image.at<double>(posy - 1, posx - 1) + a5*padded_image.at<double>(posy - 1, posx) + a6*padded_image.at<double>(posy - 1, posx + 1) + a7*padded_image.at<double>(posy - 1, posx + 2);
    	double a9 = a4*padded_image.at<double>(posy, posx - 1) + a5*padded_image.at<double>(posy, posx) + a6*padded_image.at<double>(posy, posx + 1) + a7*padded_image.at<double>(posy, posx + 2);
    	double a10 = a4*padded_image.at<double>(posy + 1, posx - 1) + a5*padded_image.at<double>(posy + 1, posx) + a6*padded_image.at<double>(posy + 1, posx + 1) + a7*padded_image.at<double>(posy + 1, posx + 2);
    	double a11 = a4*padded_image.at<double>(posy + 2, posx - 1) + a5*padded_image.at<double>(posy + 2, posx) + a6*padded_image.at<double>(posy + 2, posx + 1) + a7*padded_image.at<double>(posy + 2, posx + 2);
    
    	// y方向卷积
    	double dy_2 = dy*dy;
    	double dy_3 = dy*dy*dy;
    	double a12 = (-dy_3 + 2 * dy_2 - dy) / 2;
    	double a13 = (3 * dy_3 - 5 * dy_2 + 2) / 2;
    	double a14 = (-3 * dy_3 + 4 * dy_2 + dy) / 2;
    	double a15 = (dy_3 - dy_2) / 2;
    
    	double gray_value;
    	gray_value = a8*a12 + a9*a13 + a10*a14 + a11*a15;
    
    	return gray_value;
    }
    
    
    // 这里的ipos是原图像中的位置,要把它对应到padding后图像的ipos,才能进行插值计算。
    
    double CubicPolynomial(unsigned char * image, int iImgWidth, int iImgHeight, double dx, double dy, int ipos)
    {
    	// image为图像各个位置的像素值, iImgWidth为图像的宽度, iImgHeight为图像的高度, ipos为当前插值的位置。
    
    	// 先计算padding 图像的大小。
    	int padding_size = (iImgHeight + 2) * (iImgWidth + 2);
    	double * padding_img = new double[padding_size];
    
    	// 接着对 padding_img 进行赋值。
    	// 将原图像的值赋给padding_img的(2,2)-(iImgHeight+1, iImgWidth+1)
    	// 该部分验证无误。
    	for (int i = 0; i < iImgHeight; i++)
    	{
    		for (int j = 0; j < iImgWidth; j++)
    		{
    			int ipos1 = (i+1) * (iImgWidth+2) + (j+1);
    
    			int temp = i*iImgWidth + j;
    
    			padding_img[ipos1] = image[temp];
    		}
    	}
    
    
    	// 第一行的值: 第二行、第三行、第四行的值的线性组合.
    	// 该部分验证无误。
    
    	for (int i = 1; i < iImgWidth+1; i++)
    	{
    		int ipos1 = i;
    
    		double temp1 = padding_img[ipos1 + iImgWidth + 2];
    		double temp2 = padding_img[ipos1 + 2 * (iImgWidth + 2)];
    		double temp3 = padding_img[ipos1 + 3 * (iImgWidth + 2)];
    
    		padding_img[ipos1] = 3 * temp1 - 3 * temp2 + temp3;
    	}
    
    
    	// 最后一行的值:倒数第二、第三、第四行的值的线性组合。
    	// 该部分验证无误。
    
    	for (int i = 1; i < iImgWidth+1; i++)
    	{
    		int ipos1 = i + (iImgHeight + 1)*(iImgWidth + 2);
    
    		double temp1 = padding_img[ipos1 - (iImgWidth + 2)];
    		double temp2 = padding_img[ipos1 - 2 * (iImgWidth + 2)];
    		double temp3 = padding_img[ipos1 - 3 * (iImgWidth + 2)];
    
    		padding_img[ipos1] = 3 * temp1 - 3 * temp2 + temp3;
    	}
    
    	// 第一列的值:第二列、第三列、第四列的值的线性组合。
    	// 该部分验证无误。
    	for (int i = 1; i < iImgHeight+1; i++)
    	{
    		int ipos1 = i * (iImgWidth + 2);
    		
    		double temp1 = padding_img[ipos1 + 1];
    		double temp2 = padding_img[ipos1 + 2];
    		double temp3 = padding_img[ipos1 + 3];
    
    		padding_img[ipos1] = 3 * temp1 - 3 * temp2 + temp3;
    	}
    
    	// 最后一列的值:倒数第二、第三、第四列的值的线性组合。
    	// 该部分验证无误。
    	for (int i = 1; i < iImgHeight+1; i++)
    	{
    		int ipos1 = (i + 1)*(iImgWidth + 2) - 1;
    
    		double temp1 = padding_img[ipos1 - 1];
    		double temp2 = padding_img[ipos1 - 2];
    		double temp3 = padding_img[ipos1 - 3];
    
    		padding_img[ipos1] = 3 * temp1 - 3 * temp2 + temp3;
    	}
    
    	// 后面4个点的组合方向均为列的方向。即ipos+1, ipos+2, ipos+3,或ipos-1, ipos-2, ipos-3.
    
    	// 左上角的点。
    	padding_img[0] = 3 * padding_img[1] - 3 * padding_img[2] + padding_img[3];
    
    	// 右上角的点。
    	padding_img[iImgWidth + 1] = 3 * padding_img[iImgWidth] - 3 * padding_img[iImgWidth - 1] + padding_img[iImgWidth - 2];
    
    	// 左下角的点。
    
    	int pos_left_bottom = (iImgHeight + 1)*(iImgWidth + 2);
    	padding_img[pos_left_bottom] = 3 * padding_img[pos_left_bottom + 1] - 3 * padding_img[pos_left_bottom + 2] + padding_img[pos_left_bottom + 3];
    
    	// 右下角的点。
    
    	int pos_right_bottom = (iImgHeight + 2)*(iImgWidth + 2) - 1;
    	padding_img[pos_right_bottom] = 3 * padding_img[pos_right_bottom - 1] - 3 * padding_img[pos_right_bottom - 2] + padding_img[pos_right_bottom - 3];
    
    	
    	// padding结束之后,进行插值操作。首先要把原图的ipos对应到新图的ipos。
    
    	int height = (ipos + 1) / iImgWidth;
    
    	int width = (ipos + 1) - height*iImgWidth;
    
    	// 在新图中的位置。
    
    	int new_ipos = width + (height+1) * (iImgWidth + 2);
    
    
    	// x方向卷积
    	double dx_2 = dx*dx;
    	double dx_3 = dx*dx*dx;
    	double a4 = (-dx_3 + 2 * dx_2 - dx) / 2;
    	double a5 = (3 * dx_3 - 5 * dx_2 + 2) / 2;
    	double a6 = (-3 * dx_3 + 4 * dx_2 + dx) / 2;
    	double a7 = (dx_3 - dx_2) / 2;
    
    
    
    	double a8 = a4*padding_img[new_ipos - 1 - (iImgWidth + 2)] + a5*padding_img[new_ipos - (iImgWidth + 2)] + a6 * padding_img[new_ipos + 1 - (iImgWidth + 2)] + a7 * padding_img[new_ipos + 2 - (iImgWidth + 2)];
    	double a9 = a4*padding_img[new_ipos - 1] + a5*padding_img[new_ipos] + a6 * padding_img[new_ipos + 1] + a7 * padding_img[new_ipos + 2];
    	double a10 = a4*padding_img[new_ipos - 1 + (iImgWidth + 2)] + a5*padding_img[new_ipos + (iImgWidth + 2)] + a6 * padding_img[new_ipos + 1 + (iImgWidth + 2)] + a7 * padding_img[new_ipos + 2 + (iImgWidth + 2)];
    	double a11 = a4*padding_img[new_ipos - 1 + 2 * (iImgWidth + 2)] + a5*padding_img[new_ipos + 2 * (iImgWidth + 2)] + a6 * padding_img[new_ipos + 1 + 2 * (iImgWidth + 2)] + a7 * padding_img[new_ipos + 2 + 2 * (iImgWidth + 2)];
    	
    
    
    	// y方向卷积
    	double dy_2 = dy*dy;
    	double dy_3 = dy*dy*dy;
    	double a12 = (-dy_3 + 2 * dy_2 - dy) / 2;
    	double a13 = (3 * dy_3 - 5 * dy_2 + 2) / 2;
    	double a14 = (-3 * dy_3 + 4 * dy_2 + dy) / 2;
    	double a15 = (dy_3 - dy_2) / 2;
    
    	double gray_value;
    	gray_value = a8*a12 + a9*a13 + a10*a14 + a11*a15;
    
    	return gray_value;
    
    
    }
    
    
    int main(int argc, char **argv)
    {
    
    	// imageData为图像数据,unsigned char * 型
    
    	Mat image = imread("F:\\img\\image\\result1.jpg", 0);
    	int image_size = image.cols * image.rows;
    	unsigned char* imageData = new unsigned char[image_size];
    
    	int a = 0;
    	for (int i = 0; i<image.rows; i++)
    	{
    		for (int j = 0; j<image.cols; j++)
    		{
    			imageData[a] = image.at<uchar>(i, j);
    			a++;
    		}
    	}
    
    
    
    	int iImgHeight = image.rows;
    	int iImgWidth = image.cols;
    
    	// 进行多次随机试验。
    
    	for (int i = 0; i < 1000; i++)
    	{
    
    		// x是列方向,y是行方向,在cv::Mat做输入的函数中,起始点为(1,1)点。
    
    
    
    		// 生成随机位置。
    		int x = rand() % (iImgWidth - 1) + 1;
    		int y = rand() % (iImgHeight - 1) + 1;
    
    		// 对应回原图像下的ipos。
    		int ipos = (y - 1)*(iImgWidth)+(x - 1);
    
    
    		// 生成随机的dx, dy.
    		int N = 10000;
    		double dx = rand() % (N + 1) / (float)(N + 1);;
    		double dy = rand() % (N + 1) / (float)(N + 1);;
    
    
    		// 基于unsigned char * 数据的插值结果。
    		double temp1 = CubicPolynomial(imageData, iImgWidth, iImgHeight, dx, dy, ipos);
    
    		// 基于cv::Mat 数据的插值结果。
    		double temp2 = CubicPolynomial(image, dx, dy, x, y);
    
    		double difference = abs(temp2 - temp1);
    
    		cout << "The difference is : " << difference << endl;
    
    
    	}
    
    
    	system("pause");
    	return 0;
    }
    

    四、Matlab代码

    function Value = CubicInterpoly(y,x,img)
        uw = floor(x);
        vw = floor(y);
        pV = zeros(16,1);
        W = zeros(16,2);
        
        pV(1) = img(vw-1,uw-1);
        W(1,:) = BiCubic(y,x,vw-1,uw-1);
        pV(2) = img(vw-1,uw);
        W(2,:) = BiCubic(y,x,vw-1,uw);
        pV(3) = img(vw-1,uw+1);
        W(3,:) = BiCubic(y,x,vw-1,uw+1);
        pV(4) = img(vw-1,uw+2);
        W(4,:) = BiCubic(y,x,vw-1,uw+2);
    
        pV(5) = img(vw,uw-1);
        W(5,:) = BiCubic(y,x,vw,uw-1);
        pV(6) = img(vw,uw);
        W(6,:) = BiCubic(y,x,vw,uw);
        pV(7) = img(vw,uw+1);
        W(7,:) = BiCubic(y,x,vw,uw+1);
        pV(8) = img(vw,uw+2);
        W(8,:) = BiCubic(y,x,vw,uw+2);
        
        pV(9) = img(vw+1,uw-1);
        W(9,:) = BiCubic(y,x,vw+1,uw-1);
        pV(10) = img(vw+1,uw);
        W(10,:) = BiCubic(y,x,vw+1,uw);
        pV(11) = img(vw+1,uw+1);
        W(11,:) = BiCubic(y,x,vw+1,uw+1);
        pV(12) = img(vw+1,uw+2);
        W(12,:) = BiCubic(y,x,vw+1,uw+2);
        
        pV(13) = img(vw+2,uw-1);
        W(13,:) = BiCubic(y,x,vw+2,uw-1);
        pV(14) = img(vw+2,uw);
        W(14,:) = BiCubic(y,x,vw+2,uw);
        pV(15) = img(vw+2,uw+1);
        W(15,:) = BiCubic(y,x,vw+2,uw+1);
        pV(16) = img(vw+2,uw+2);
        W(16,:) = BiCubic(y,x,vw+2,uw+2);
        
        Value = 0;
        for i=1:16
            Value = Value + pV(i)*W(i,1)*W(i,2);
        end
    end
    
    function W = BiCubic(y,x,yi,xi)
        W = zeros(1,2);
        a = -0.5;
        distX = abs(x-xi);
        if(distX <=1)
            W(1) = (a+2)*distX^3-(a+3)*distX^2+1;
        elseif(distX > 1 && distX <2)
            W(1) = a*distX^3-5*a*distX^2+8*a*distX-4*a;
        else
            W(1) = 0;
        end
        distY = abs(y-yi);
        if(distY <=1)
            W(2) = (a+2)*distY^3-(a+3)*distY^2+1;
        elseif(distY > 1 && distY <2)
            W(2) = a*distY^3-5*a*distY^2+8*a*distY-4*a;
        else
            W(2) = 0;
        end
    end
    
    展开全文
  • Captain Dialog 2009-09-24 经过一次论坛的报告准备的确是让自己的软件设计思路清晰了不少,这几天一直忙着完成一个插值算法,突然发现,原来自己的数据管理方式已经很久没有审查了,今天大概画画数据流程图,发现...
  • MATLAB 插值

    千次阅读 2014-09-29 20:14:18
    MATLAB 插值   常用的多项式插值法: 1.拉格朗日插值 拉格朗日插值是簇插值的基本公式,由n+1个n次插值基函数构成,即n次插值多项式。 一般:
  • 利用Bézier曲线的端点插值性质,得到了构造三次插值样条曲线曲面的种改进的基函数——B基函数。由B基函数构造了C1形三次插值样条曲线;构造了C1双三次插值样条曲面
  • 拉格朗日插值、分段线性插值、三样条插值

    万次阅读 多人点赞 2018-08-30 21:20:05
    本篇主要介绍在三种插值方法:拉格朗日... 1.1基本原理:先构造基函数:   是多项式,满足 令 上式称为Lagrange插值多项式。 1.2用Matlab作Lagrange插值: matlab没有现成的lagrange函数,需...
  • 径向基函数工作原理(样条函数)

    千次阅读 2013-01-17 12:07:00
    =================================...有以下五种基函数: 薄板样条函数 张力样条函数 规则样条函数 高曲面函数 反高曲面函数 在不同的插值表面中,每种基函数都有不同的形状和结果。RBF 方法是样条函数的个特...
  • 内容结构指引插值法 | 拉格朗日插值 | 分段低次插值主要名词检索插值法 | 插值函数 | 插值节点 | 多项式插值 | 拉格朗日插值 | 插值基函数 | 拉格朗日插值多项式 | 插值余项 | 龙格高次插值病态性质 | 分段线性插值...
  • 类二最小支集样条小波插值研究,徐应祥,,以二最小支集样条小波为基函数,构造了类二最小支集样条小波插函数,仔细讨论了其计算过程和误差分析,最后给出个数值例子.
  • 期末考试知识点整理 1. Polynominterpolation  已知组离散数据 找到组多项式 使得上确界 尽可能小...可理解矩阵的列构成希尔伯特空间下的n+1组函数f(x) 在希尔伯特空间下用向量a表示。求出a向量,即...
  • 数字图像缩放之双三次插值

    千次阅读 2016-11-01 17:09:08
    基本原理:双三次插值种更加复杂的插值方式,它能创造出比双线性插值更平滑的图像边缘。缩放后图像中某个象素的象素值是由源图像相应像素附近的(4 x 4)个邻近象素值计算出来的,即通过基函数进行拟合...
  • 《数值分析》实验报告实验编号:实验六课题名称:分段三Hermite插值一、算法介绍给定的函数为f(x)=1/(25*x*x+1),将给定区间分成10分,得到11个节点:x[0],x[1],...,x[10],构造插值函数的基函数。当x在(x[0],x[1]...
  • 首先构造组带 2 个参数的七 Hermite 基函数; 然后基于该组基函数定义分段七 Hermite 参数样条曲 线, 并讨论样条曲线所带参数的选取方案; 最后研究对应的分段七 Hermite 样条插值函数, 并给出其插值余项及最...
  • 拉格朗日插值法 在数值分析复习()线性插值、抛物...就称这n+1个n次多项式为节点上的n次插值基函数。 引入记号: 拉格朗日插值多项式可变换为: 当n=1时,,为线性插值 当n=2时,,展开后可得抛物线插...
  • 算法来源:Cubic ...许多插值函数能够写成形式(其中是插值点,u是基函数(文章中叫插值核),h是采样间隔,是参数) 通过插值,用来近似。 cubic convolution interpolation 中插值核u定义为子区间(-2,-1
  • 实验题目:Hermite插值多项式相关知识:通过n+1个节点的次数不超过2n+1的Hermite插值多项式为:其中,Hermite插值基函数数据结构:三个维数组或个二维数组算法设计:(略)编写代码:(略)实验用例: 已知函数y=f(x...
  • B样条插值和误差分析

    万次阅读 2018-07-27 20:10:46
    前言:之前写写过篇B样条曲线,这篇是原文的深度扩展,是针对B样条曲线的种特殊情况,三B样条,讨论了其插值和误差分析,添加了一些个人总结。 思路:根据已知的型值点(就是给出的已知的数据点),采用均匀...
  • 1 数学建模与数学实验 插 值 2 实验目的 实验内容 2掌握用数学软件包求解插值问题 1了解插值的基本内容...6 返回 7 称为拉格朗日插值基函数 已知函数f(x)在n+1个点x0,x1,xn处的函数值为 y0,y1,yn 求n多项式函数Pn(x
  • 插值

    2019-03-19 16:35:00
    1、拉格朗日插值法 ①原理 对于平面上已知的n个点,可以找到个n-1多项式y=a0+a1x+a2x2+…+an-1xn-1,使得该多项式曲线经过这n个点。对于缺失的值,将对应...其中li(x)称为插值基函数: 拉格朗日插值公式...
  • 不同插值方法的比较

    2021-01-06 21:16:06
    不同插值方法的比较1.多项式插值2.分段插值 1.多项式插值 多项式插值:以个多项式的形式来刻画经过系列点的曲线。...该基函数个优点是当增加个新的插值节点 时,只需在原有基函数的基础上
  • BiCubic插值原理: 双三次插值又称立方卷积插值。三次卷积插值是种更加复杂的插值方式。...这种算法需要选取插值基函数来拟合数据,其最常用的插值基函数如图1所示,本次实验采用如图所示函数作为基函数。
  • 拉格朗日插值公式

    2008-10-08 19:35:00
    线性插值(一次插值) 已知函数f(x)在区间[xk ,xk+1 ]的端点上的函数值yk =f(xk ), yk+1 = f(xk+1 ),求一个一次函数y=P1 (x)使得yk =f(xk ),yk+1 =f(xk+1 ), 其几何意义是已知平面上两点(xk ,yk ),(xk+1 ,yk+1 ),求一...
  • 拉格朗日插值

    2020-02-05 19:16:30
    指的是在节点上给出节点基函数,然后做基函数的线性组合,组合系数为节点函数值的插值多项式。 线性插值也叫两点插值,已知函数y = f (x)在给定互异点x0, x1上的值为y0= f (x0),y1=f (x1)线性插值就是构造个...
  • 拉格朗日插值公式详解

    千次阅读 2013-10-22 22:04:53
    线性插值(一次插值)  已知函数f(x)在区间[xk ,xk+1 ]的端点上的函数值yk =f(xk ), yk+1 = f(xk+1 ),求一个一次函数y=P1 (x)使得yk =f(xk ),yk+1 =f(xk+1 ), 其几何意义是已知平面上两点(xk ,yk ...
  • 数值计算方法--插值

    2020-03-16 13:16:39
    拉格朗日插值:一种直接的一次性将已知条件全部用上的模拟。于是定义基函数使 每一个已知点对应一项基函数基函数:在此点函数值为1,其它点为0的函数。 形如: 每个基函数添加相应函数值为系数...

空空如也

空空如也

1 2 3 4
收藏数 77
精华内容 30
关键字:

一次插值基函数