2013-04-16 201 views
3

我正在尋找一個C++相當於Matlab的griddata函數或任何2D全局插值方法。在C++中等效的Matlab griddata

我有一個使用Eigen 3的C++代碼。我將有一個包含x,y和z值的特徵向量,以及兩個與Matlab中由Meshgrid產生的特徵向量等效的特徵向量。我想將矢量中的z值插入由Meshgrid等價物定義的網格點(它將延伸過原始點的外部一點,因此需要進行較小的外插)。

我並不太在意準確性 - 它不需要完美。然而,我不能接受NaN作爲解決方案 - 插值必須在網格上的任何位置進行計算,而不管數據間隙如何。換句話說,留在凸包內不是一種選擇。

我不想從頭開始寫插值,但如果有人想指向我相當好(和明確)的食譜,我會給它一個鏡頭。這不是寫的最可恨的事情(至少在算法意義上),但我不想重新發明輪子。

實際上,我擁有的是分散的地形位置,我希望定義一個名義上跟隨地形下方一定距離的直線網格,以供以後使用。一旦我有了節點,我就會很好。

我的研究至今:

這裏的問題問:MATLAB functions in C++產生了密切的答案,但遺憾的是該建議是不是免費的(SciMath)。

我已經嘗試瞭解通用映射工具中使用的插值函數,並獲得頭痛的獎勵。

我簡要介紹了網格算法庫(GrAL)。如果有人有評論,我將不勝感激。

Eigen有一個不受支持的插值軟件包,但它似乎只是曲線(不是曲面)。

編輯:VTK具有matplotlib功能。據推測,爲了顯示目的,必須在某處使用插值。有誰知道這是否可以訪問和使用?

謝謝。

+1

你看過freemat嗎? – PopcornKing

+0

我沒有 - 這不是我正在尋找的東西,但它非常接近。謝謝! –

+0

啊,不幸的是,事實證明griddata/interp2/etc沒有在FreeMat中實現。很近! –

回答

3

這可能有點晚,但希望它可以幫助某人。方法1)Octave:如果你來自Matlab,有一種方法是直接將gnu Matlab clone Octave嵌入到C++程序中。我沒有太多經驗,但可以直接從cpp文件調用八度庫函數。

例如,看這裏。 http://www.gnu.org/software/octave/doc/interpreter/Standalone-Programs.html#Standalone-Programs

griddata包含在八度的幾何包中。方法2)PCL:他們這樣做的方式是使用點雲庫(http://www.pointclouds.org)和VoxelGrid。您可以根據需要設置x和y bin大小,然後設置一個非常大的z bin大小,從而爲每個x,y bin獲取一個z值。值得注意的是,x,y和z值是平均進入倉的點的質心,而不是倉中心(這也是爲什麼它適用於此)。所以你需要在完成時按摩x,y值:

例如: //在逗號分隔值列表(x,y,z)中讀取 FILE * fp; fp = fopen(「points.xyz」,「r」);

//store them in PCL's point cloud format 
pcl::PointCloud<pcl::PointXYZ>::Ptr basic_cloud_ptr (new pcl::PointCloud<pcl::PointXYZ>); 

int numpts=0; 
double x,y,z; 
while(fscanf(fp, "%lg, %lg, %lg", &x, &y, &z)!=EOF) 
{ 
pcl::PointXYZ basic_point; 
basic_point.x = x; basic_point.y = y; basic_point.z = z; 
basic_cloud_ptr->points.push_back(basic_point); 
} 
fclose(fp); 
basic_cloud_ptr->width = (int) basic_cloud_ptr->points.size(); 
basic_cloud_ptr->height = 1; 

// create object for result 
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>()); 

// create filtering object and process 
pcl::VoxelGrid<pcl::PointXYZ> sor; 
sor.setInputCloud (basic_cloud_ptr); 
//set the bin sizes here. (dx,dy,dz). for 2d results, make one of the bins larger 
//than the data set span in that axis 
sor.setLeafSize (0.1, 0.1, 1000); 
sor.filter (*cloud_filtered); 

因此,cloud_filtered現在是一個點雲,每個點包含一個點。然後,我只需製作一個二維矩陣,並通過點雲將點分配給它們的x,y箱,如果我想要一個圖像等,就像griddata所產生的一樣。它工作得很好,比大數據集的matlab網格數據快得多。