Matlab矩陣填充--Matlab interp2


    Matlab interp2 為Matlab的矩陣填充函數,

填充關系:

x=1:11;  
y=1:13;  
x1=1:0.1:12;  
y1=1:0.1:14;  

[x2,y2]=meshgrid(x1,y1); 
t1=interp2(x,y,t,x2,y2,'cubic');

意義:

進行十倍差值,使用雙三次插值 方法。


用指定的算法method 計算二維插值:
’linear’:雙線性插值算法(缺省算法);
’nearest’:最臨近插值;
’spline’:三次樣條插值;
’cubic’:雙三次插值。book.iLoveMatlab.cn


相關知識

    參考鏈接:http://blog.sina.com.cn/s/blog_5cd733a50100o4d8.html

    在生產和科學實驗中,自變量 與因變量 間的函數關系有時不能寫出解析表達式,而只能得到函數在若干點的函數值或導數值,或者表達式過於復雜而需要較大的計算量。當要求知道其它點的函數值時,需要估計函數值在該點的值。
    為了完成這樣的任務,需要構造一個比較簡單的函數,使函數在觀測點的值等於已知的值,或使函數在該點的導數值等於已知的值,尋找這樣的函數有很多方法。根據測量數據的類型有以下兩類處理觀測數據的方法。
(1)測量值是准確的,沒有誤差,一般用插值。
(2)測量值與真實值有誤差,一般用曲線擬合。

在MATLAB中,無論是插值還是擬合,都有相應的函數來處理。


一、插值

1、一維插值
已知離散點上的數據集 ,即已知在點集X= 上的函數值Y=,構造一個解析函數(其圖形為一曲線)通過這些點,並能夠求出這些點之間的值,這一過程稱為一維插值。
MATLAB命令:yi=interp1(X, Y, xi, method)
該命令用指定的算法找出一個一元函數 ,然后以 給出處的值。xi可以是一個標量,也可以是一個向量,是向量時,必須單調,method可以下列方法之一:
‘nearest’:最近鄰點插值,直接完成計算;
‘spline’:三次樣條函數插值;
‘linear’:線性插值(缺省方式),直接完成計算;
‘cubic’:三次函數插值;
對於[min{xi},max{xi}]外的值,MATLAB使用外推的方法計算數值。
例1:已知某產品從1900年到2010年每隔10年的產量為:75.995, 91.972, 105.711, 123.203,131.699, 150.697, 179.323, 203.212, 226.505, 249.633, 256.344,267.893,計算出1995年的產量,用三次樣條插值的方法,畫出每隔一年的插值曲線圖形,同時將原始的數據畫在同一圖上。
解:程序如下

year=1900:10:2010;
product=[75.995, 91.972, 105.711, 123.203, 131.699, 150.697,179.323, 203.212, 226.505, 249.633, 256.344, 267.893]
p1995=interp1(year,product,1995)
x=1900:2010;
y=interp1(year,product,x,'cubic');
plot(year,product,'o',x,y);
計算結果為:

p1995=252.9885。


2、二維插值

    已知離散點上的數據集 ,即已知在點集 上的函數值,構造一個解析函數(其圖形為一曲面)通過這些點,並能夠求出這些已知點以外的點的函數值,這一過程稱為二維插值。
    MATLAB函數:
    Zi=interp2(X,Y,Z,Xi,Yi,method)

    該命令用指定的算法找出一個二元函數 ,然后以 給出 處的值。返回數據矩陣 ,Xi,Yi是向量,且必須單調,和meshgrid(Xi,Yi)是同類型的。

    method可以下列方法之一:
‘nearest’:最近鄰點插值,直接完成計算;
‘spline’:三次樣條函數插值;
‘linear’:線性插值(缺省方式),直接完成計算;
‘cubic’:三次函數插值;

例2:已知1950年到1990年間每隔10年,服務年限從10年到30年每隔10年的勞動報酬表如下:
表:某企業工作人員的月平均工資(元)
年份 1950 1960 1970 1980 1990
服務年限
10 150.697 179.323 203.212 226.505 249.633
20 169.592 195.072 239.092 273.706 370.281
30 187.652 250.287 322.767 426.730 598.243

試計算1975年時,15年工齡的工作人員平均工資。

解:程序如下:

years=1950:10:1990;
service=10:10:30;
wage=[150.697 169.592 187.652
179.323 195.072 250.287
203.212 239.092 322.767
226.505 273.706 426.730
249.633 370.281 598.243];
mesh(service,years,wage) %繪原始數據圖
w=interp2(service,years,wage,15,1975); %求點(15,1975)處的值

計算結果為:235.6288


例3:設有數據x=1,2,3,4,5,6,y=1,2,3,4,在由x,y構成的網格上,數據為:
12,10,11,11,13,15
16,22,28,35,27,20
18,21,26,32,28,25
20,25,30,33,32,20
求通過這些點的插值曲面。
:程序為:

x=1:6;
y=1:4;
t=[12,10,11,11,13,15
16,22,28,35,27,20
18,21,26,32,28,25;
20,25,30,33,32,20]
subplot(1,2,1)
mesh(x,y,t)
x1=1:0.1:6;
y1=1:0.1:4;
[x2,y2]=meshgrid(x1,y1);
t1=interp2(x,y,t,x2,y2,'cubic');
subplot(1,2,2)
mesh(x1,y1,t1);

結果如下圖。


作業:已知某處山區地形選點測量坐標數據為:
x=0 0.5 1 1.5 2 2.5 3 3.5 4 4.5 5
y=0 0.5 1 1.5 2 2.5 3 3.5 4 4.5 5 5.5 6
海拔高度數據為:
z=89 90 87 85 92 91 96 93 90 87 82
92 96 98 99 95 91 89 86 84 82 84
96 98 95 92 90 88 85 84 83 81 85
80 81 82 89 95 96 93 92 89 86 86
82 85 87 98 99 96 97 88 85 82 83
82 85 89 94 95 93 92 91 86 84 88
88 92 93 94 95 89 87 86 83 81 92
92 96 97 98 96 93 95 84 82 81 84
85 85 81 82 80 80 81 85 90 93 95
84 86 81 98 99 98 97 96 95 84 87
80 81 85 82 83 84 87 90 95 86 88
80 82 81 84 85 86 83 82 81 80 82
87 88 89 98 99 97 96 98 94 92 87

1、 畫出原始數據圖;
2、 畫出加密后的地貌圖,並在圖中標出原始數據

x=1:11;  
y=1:13;  
t=[
89, 90, 87, 85, 92, 91, 96, 93 ,90 ,87, 82,
92 ,96 ,98 ,99 ,95 ,91, 89, 86 ,84, 82 ,84,
96 ,98 ,95 ,92 ,90, 88 ,85 ,84, 83, 81, 85,
80 ,81, 82, 89, 95 ,96 ,93 ,92, 89, 86, 86,
82 ,85, 87, 98, 99, 96, 97 ,88 ,85 ,82, 83,
82 ,85 ,89 ,94, 95, 93, 92, 91, 86 ,84, 88,
88 ,92, 93, 94, 95, 89 ,87 ,86, 83, 81, 92,
92 ,96 ,97 ,98, 96, 93, 95, 84, 82, 81, 84,
85 ,85, 81, 82, 80 ,80, 81, 85, 90, 93, 95,
84 ,86 ,81 ,98 ,99 ,98, 97, 96, 95, 84, 87,
80, 81, 85 ,82, 83 ,84 ,87 ,90, 95 ,86, 88,
80, 82, 81 ,84, 85 ,86, 83, 82, 81, 80, 82,
87 ,88 ,89 ,98 ,99, 97 ,96, 98, 94, 92, 87]  
subplot(1,2,1)  
mesh(x,y,t)  
x1=1:0.1:12;  
y1=1:0.1:14;  
[x2,y2]=meshgrid(x1,y1);  
t1=interp2(x,y,t,x2,y2,'cubic');  
subplot(1,2,2)  
mesh(x1,y1,t1);  

結果如下圖:



二、使用opencv取代


使用opencv改寫,函數為:

//使用OpenCV方法進行插值
//使用opencv resize函數
//Matlab函數!//function zi = interp2(varargin)

//varargin[0]:  Src AxisX
//varargin[1]:  Src AxisY
//varargin[2]:  SrcData
//varargin[3]:  Dst AxisX
//varargin[4]:  Dst AxisY
//method: interpolation method
Eigen::MatrixXf CIcSearchM::interp2Cv(
	std::vector<Eigen::MatrixXf> &varargin,
	int  method)
{
	assert(varargin.size() >=   5);

	Eigen::MatrixXf zi;
	if (0 ==varargin[0].size() ||	0 ==varargin[1].size()
		|| 0 ==varargin[3].size() ||	0 ==varargin[4].size())
	{
		zi.resize(0,0);
		return zi;
	} 
	else
	{
		zi.resize(varargin[3].size() , varargin[4].size());

		if (varargin[2].rows()!= zi.rows() ||  varargin[2].cols()!=zi.cols()  )
		{
			zi.resize(0,0);
			return zi;
		} 
		else
		{
			//Eigen::MatrixXf Mat; 
			cv::Mat Img;
			cv::Mat ImgRe(zi.rows(),zi.cols(),CV_32F);
			m_Slamer.copyCvMat( varargin[3], Img);
			cv::resize( Img, ImgRe,ImgRe.size(),0,0,method );
			m_Slamer.copyCvMat( ImgRe, zi);
		}

	}

	return zi;
}

使用方法:

		std::vector<Eigen::MatrixXf>  varargin;
		varargin.push_back(u_fea);
		varargin.push_back(v_fea);
		varargin.push_back(patch_p_f); 
		varargin.push_back(u_pred_imak_dist);;
		varargin.push_back(v_pred_imak_dist );;
		patch_pred = this->interp2Cv( varargin,CV_INTER_CUBIC);

void cvResize( const CvArr* src, CvArr* dst, int interpolation=CV_INTER_LINEAR );src輸入圖像.dst輸出圖像.interpolation插值方法:

  • CV_INTER_NN - 最近鄰插值,
  • CV_INTER_LINEAR - 雙線性插值 (缺省使用)
  • CV_INTER_AREA - 使用象素關系重采樣。當圖像縮小時候,該方法可以避免波紋出現。當圖像放大,類似於 CV_INTER_NN 方法..
  • CV_INTER_CUBIC - 立方插值.

函數 cvResize 將圖像 src 改變尺寸得到與 dst 同樣大小。若設定 ROI,函數將按常規支持 ROI.



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM