0

我正在開發PCL(點雲庫)項目。其中的一部分需要我剪輯點雲,爲此我需要知道給定點雲的最小和最大座標。此預定義函數減慢我的程序性能

PCL提供了一個預定義的函數,稱爲getminmax3d()。我試過了,它運行良好,唯一的問題是,當我輸入一個大的點雲文件時,需要很長時間。我對getminmax3d()做了我自己的定義,它花費的時間較少。我不明白爲什麼這兩個行爲是這樣的。

我嘗試了5個點雲數據文件。在所有情況下,使用預定義函數的程序與我定義的程序相比需要很長時間。

下面是代碼:
先執行 - 它使用預定義的函數getminmax3d()

#include <iostream> 
#include <pcl/io/pcd_io.h> 
#include <pcl/point_types.h> 
#include <pcl/common/common.h> 

int main (int, char**) 
{ 
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud; 
    cloud = pcl::PointCloud<pcl::PointXYZ>::Ptr (new pcl::PointCloud<pcl::PointXYZ>); 
    pcl::io::loadPCDFile<pcl::PointXYZ> ("your_pcd_file.pcd", *cloud); 
    pcl::PointXYZ minPt, maxPt; 
    pcl::getMinMax3D (*cloud, minPt, maxPt); 
    std::cout << "Max x: " << maxPt.x << std::endl; 
    std::cout << "Max y: " << maxPt.y << std::endl; 
    std::cout << "Max z: " << maxPt.z << std::endl; 
    std::cout << "Min x: " << minPt.x << std::endl; 
    std::cout << "Min y: " << minPt.y << std::endl; 
    std::cout << "Min z: " << minPt.z << std::endl; 
    return (0); 
} 

第二實現 - 該源代碼使用一個用戶定義的函數定義,以取代getminmax3d的功能()

#include <iostream> 
#include <pcl/io/pcd_io.h> 
#include <pcl/point_types.h> 
#include <pcl/common/time.h> 

int main (int argc, char** argv) 
{ 
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>); 
    if (pcl::io::loadPCDFile<pcl::PointXYZ> ("rhino.pcd", *cloud) == -1) //* load the file 
    { 
    PCL_ERROR ("Couldn't read file rhino.pcd \n"); 
    return (-1); 
    } 
    float min_x = cloud->points[0].x, min_y = cloud->points[0].y, min_z = cloud->points[0].z, max_x = cloud->points[0].x, max_y = cloud->points[0].y, max_z = cloud->points[0].z; 
    pcl::StopWatch watch; 
    for (size_t i = 1; i < cloud->points.size(); ++i){ 
     if(cloud->points[i].x <= min_x) 
      min_x = cloud->points[i].x; 
     else if(cloud->points[i].y <= min_y) 
      min_y = cloud->points[i].y; 
     else if(cloud->points[i].z <= min_z) 
      min_z = cloud->points[i].z; 
     else if(cloud->points[i].x >= max_x) 
      max_x = cloud->points[i].x; 
     else if(cloud->points[i].y >= max_y) 
      max_y = cloud->points[i].y; 
     else if(cloud->points[i].z >= max_z) 
      max_z = cloud->points[i].z; 
    } 
    pcl::console::print_highlight ("Time taken: %f\n", watch.getTimeSeconds()); 
    std::cout << "Min x: " << min_x <<"\t"; 
    std::cout << "Max x: " << max_x << std::endl; 
    std::cout << "Min y: " << min_y <<"\t"; 
    std::cout << "Max y: " << max_y << std::endl; 
    std::cout << "Min z: " << min_z <<"\t"; 
    std::cout << "Max z: " << max_z << std::endl; 
    return (0); 
} 

我試過以下5個點雲文件的兩個程序。
Armadillo Bunny Dragon Buddha Rhino

結果而獲得:
TTF:耗時因子
TTF = 15意味着用戶定義比預定義的功能快約15倍。通過對兩種實施平均進行10次試驗來測量ttf值。

PCD file Filetype File size ttf 
Rhino.pcd XYZ  2.57 MB  15.260 
Bun_zipper XYZCI  1.75 MB  17.422 
Armadillo XYZ  5.26 MB  15.847 
Dragon_vrip XYZ  14.7 MB  17.013 
Happy_vrip XYZ  18.0 MB  14.981 

我想知道爲什麼預定義函數需要更多時間?我想減少我的程序源代碼行。我一直認爲使用標準頭文件和它們的功能可以提供最好的性能,但在這種情況下,它似乎失敗了。

This is where you can find standard definition. 請有誰幫我找出爲什麼第二次執行需要更少的時間(約15次),即使getminmax3d()的標準定義與我的類似。

+0

您的意思是http://docs.pointclouds.org/1.7.2/a02405.html#ga3166f09aafd659f69dc75e63f5e10f81作爲文檔鏈接嗎?你的示例代碼調用函數的3參數版本,但你鏈接到一個有很多參數的代碼 –

+0

記錄良好的問題,upvoted。關於「我一直相信使用標準頭文件和它們的功能可以給你最好的性能」:它並不總是這樣。通常,標準函數必須處理對特定情況無用或者過於籠統,或者使用較舊編譯器版本進行編譯的較差情況,其中較不積極的優化設置或針對較舊處理器的優化。在這種情況下重新編寫針對您特定需求的版本可能是一種有效的可能性(只要您的版本正確執行=))。 –

+0

@ M.M OOPS ....讓我再次找到它。 –

回答

1

pcl::getMinMax3D有一個非常低效的實現。要搜索的最小和最大點它執行以下操作:

Eigen::Array4f min_p, max_p; 
min_p.setConstant (FLT_MAX); 
max_p.setConstant (-FLT_MAX); 
for (size_t i = 0; i < cloud.points.size(); ++i) 
{ 
    // ... (check the validity of the point if it is not a dense cloud) 

    pcl::Array4fMapConst pt = cloud.points[i].getArray4fMap(); 
    min_p = min_p.min (pt); 
    max_p = max_p.max (pt); 
} 

如果你檢查的getArray4fMap()功能:

typedef Eigen::Map<Eigen::Array4f, Eigen::Aligned> Array4fMap; 

inline pcl::Array4fMap getArray4fMap() const { 
    return (pcl::Array4fMap(data)); 
} 

對於在雲中的每個點是構建Eigen::Map,然後比較它違背了當前的最低點和最高點。這是非常低效的。