1. 程式人生 > >[CC]點雲密度計算

[CC]點雲密度計算

 

包括兩種計算方法:精確計算和近似計算(思考:local density=單位面積的點數 vs  local density =1/單個點所佔的面積)

每種方法可以實現三種模式的點雲密度計算,CC裡面的點雲端計算依賴於 給定的近鄰半徑所對應的最佳八叉樹層級 (通過findBestLevelForAGivenNeighbourhoodSizeExtraction()方法實現)

在GeometricalAnalysisTools類檔案中實現。

//volume of a unit sphere
static double s_UnitSphereVolume = 4.0 * M_PI / 3.0
;

 1.精確計算

 1 int GeometricalAnalysisTools::computeLocalDensity(    GenericIndexedCloudPersist* theCloud,
 2                                                     Density densityType,
 3                                                     PointCoordinateType kernelRadius,
 4                                                     GenericProgressCallback* progressCb/*
=0*/, 5 DgmOctree* inputOctree/*=0*/) 6 { 7 if (!theCloud) 8 return -1; 9 10 unsigned numberOfPoints = theCloud->size(); 11 if (numberOfPoints < 3) 12 return -2; 13 14 //compute the right dimensional coef based on the expected output
15 double dimensionalCoef = 1.0; 16 switch (densityType) 17 { 18 case DENSITY_KNN: 19 dimensionalCoef = 1.0; 20 break; 21 case DENSITY_2D: 22 dimensionalCoef = M_PI * (static_cast<double>(kernelRadius) * kernelRadius); 23 break; 24 case DENSITY_3D: 25 dimensionalCoef = s_UnitSphereVolume * ((static_cast<double>(kernelRadius) * kernelRadius) * kernelRadius); 26 break; 27 default: 28 assert(false); 29 return -5; 30 } 31 32 DgmOctree* theOctree = inputOctree; 33 if (!theOctree) 34 { 35 theOctree = new DgmOctree(theCloud); 36 if (theOctree->build(progressCb) < 1) 37 { 38 delete theOctree; 39 return -3; 40 } 41 } 42 43 theCloud->enableScalarField(); 44 45 //determine best octree level to perform the computation 46 unsigned char level = theOctree->findBestLevelForAGivenNeighbourhoodSizeExtraction(kernelRadius); 47 48 //parameters 49 void* additionalParameters[] = { static_cast<void*>(&kernelRadius), 50 static_cast<void*>(&dimensionalCoef) }; 51 52 int result = 0; 53 54 if (theOctree->executeFunctionForAllCellsAtLevel( level, 55 &computePointsDensityInACellAtLevel, 56 additionalParameters, 57 true, 58 progressCb, 59 "Local Density Computation") == 0) 60 { 61 //something went wrong 62 result = -4; 63 } 64 65 if (!inputOctree) 66 delete theOctree; 67 68 return result; 69 }
GeometricalAnalysisTools::computeLocalDensity
 1 //"PER-CELL" METHOD: LOCAL DENSITY
 2 //ADDITIONNAL PARAMETERS (2):
 3 // [0] -> (PointCoordinateType*) kernelRadius : spherical neighborhood radius
 4 // [1] -> (ScalarType*) sphereVolume : spherical neighborhood volume
 5 bool GeometricalAnalysisTools::computePointsDensityInACellAtLevel(    const DgmOctree::octreeCell& cell, 
 6                                                                     void** additionalParameters,
 7                                                                     NormalizedProgress* nProgress/*=0*/)
 8 {
 9     //parameter(s)
10     PointCoordinateType radius = *static_cast<PointCoordinateType*>(additionalParameters[0]);
11     double dimensionalCoef = *static_cast<double*>(additionalParameters[1]);
12     
13     assert(dimensionalCoef > 0);
14 
15     //structure for nearest neighbors search
16     DgmOctree::NearestNeighboursSphericalSearchStruct nNSS;
17     nNSS.level = cell.level;
18     nNSS.prepare(radius,cell.parentOctree->getCellSize(nNSS.level));
19     cell.parentOctree->getCellPos(cell.truncatedCode,cell.level,nNSS.cellPos,true);
20     cell.parentOctree->computeCellCenter(nNSS.cellPos,cell.level,nNSS.cellCenter);
21 
22     unsigned n = cell.points->size(); //number of points in the current cell
23     
24     //for each point in the cell
25     for (unsigned i=0; i<n; ++i)
26     {
27         cell.points->getPoint(i,nNSS.queryPoint);
28 
29         //look for neighbors inside a sphere
30         //warning: there may be more points at the end of nNSS.pointsInNeighbourhood than the actual nearest neighbors (neighborCount)!
31         unsigned neighborCount = cell.parentOctree->findNeighborsInASphereStartingFromCell(nNSS,radius,false);
32         //數目/體積
33         ScalarType density = static_cast<ScalarType>(neighborCount/dimensionalCoef);
34         cell.points->setPointScalarValue(i,density);
35 
36         if (nProgress && !nProgress->oneStep())
37         {
38             return false;
39         }
40     }
41 
42     return true;
43 }
computePointsDensityInACellAtLevel

 2. 近似計算

 1 int GeometricalAnalysisTools::computeLocalDensityApprox(GenericIndexedCloudPersist* theCloud,
 2                                                         Density densityType,
 3                                                         GenericProgressCallback* progressCb/*=0*/,
 4                                                         DgmOctree* inputOctree/*=0*/)
 5 {
 6     if (!theCloud)
 7         return -1;
 8 
 9     unsigned numberOfPoints = theCloud->size();
10     if (numberOfPoints < 3)
11         return -2;
12 
13     DgmOctree* theOctree = inputOctree;
14     if (!theOctree)
15     {
16         theOctree = new DgmOctree(theCloud);
17         if (theOctree->build(progressCb) < 1)
18         {
19             delete theOctree;
20             return -3;
21         }
22     }
23 
24     theCloud->enableScalarField();
25 
26     //determine best octree level to perform the computation
27     unsigned char level = theOctree->findBestLevelForAGivenPopulationPerCell(3);
28 
29     //parameters
30     void* additionalParameters[] = { static_cast<void*>(&densityType) };
31 
32     int result = 0;
33 
34     if (theOctree->executeFunctionForAllCellsAtLevel(    level,
35                                                         &computeApproxPointsDensityInACellAtLevel,
36                                                         additionalParameters,
37                                                         true,
38                                                         progressCb,
39                                                         "Approximate Local Density Computation") == 0)
40     {
41         //something went wrong
42         result = -4;
43     }
44 
45     if (!inputOctree)
46         delete theOctree;
47 
48     return result;
49 }
View Code
 1 //"PER-CELL" METHOD: APPROXIMATE LOCAL DENSITY
 2 //ADDITIONAL PARAMETERS (0): NONE
 3 bool GeometricalAnalysisTools::computeApproxPointsDensityInACellAtLevel(const DgmOctree::octreeCell& cell,
 4                                                                         void** additionalParameters,
 5                                                                         NormalizedProgress* nProgress/*=0*/)
 6 {
 7     //extract additional parameter(s)
 8     Density densityType = *static_cast<Density*>(additionalParameters[0]);
 9     
10     DgmOctree::NearestNeighboursSearchStruct nNSS;
11     nNSS.level                                = cell.level;
12     nNSS.alreadyVisitedNeighbourhoodSize    = 0;
13     nNSS.minNumberOfNeighbors                = 2;
14     cell.parentOctree->getCellPos(cell.truncatedCode,cell.level,nNSS.cellPos,true);
15     cell.parentOctree->computeCellCenter(nNSS.cellPos,cell.level,nNSS.cellCenter);
16 
17     unsigned n = cell.points->size();
18     for (unsigned i=0; i<n; ++i)
19     {
20         cell.points->getPoint(i,nNSS.queryPoint);
21 
22         //the first point is always the point itself!
23         if (cell.parentOctree->findNearestNeighborsStartingFromCell(nNSS) > 1)
24         {
25             double R2 = nNSS.pointsInNeighbourhood[1].squareDistd;
26 
27             ScalarType density = NAN_VALUE;
28             if (R2 > ZERO_TOLERANCE)
29             {
30                 switch (densityType)
31                 {
32                 case DENSITY_KNN:
33                     {
34                         //we return in fact the (inverse) distance to the nearest neighbor
35                         density = static_cast<ScalarType>(1.0 / sqrt(R2));
36                     }
37                     break;
38                 case DENSITY_2D:
39                     {
40                         //circle area (2D approximation)
41                         double circleArea = M_PI * R2;
42                         density = static_cast<ScalarType>(1.0 / circleArea);
43                     }
44                     break;
45                 case DENSITY_3D:
46                     {
47                         //sphere area
48                         double sphereArea =  s_UnitSphereVolume * R2 * sqrt(R2);
49                         density = static_cast<ScalarType>(1.0 / sphereArea);
50                     }
51                     break;
52                 default:
53                     assert(false);
54                     break;
55                 }
56             }
57             cell.points->setPointScalarValue(i,density);
58         }
59         else
60         {
61             //shouldn't happen! Apart if the cloud has only one point...
62             cell.points->setPointScalarValue(i,NAN_VALUE);
63         }
64 
65         if (nProgress && !nProgress->oneStep())
66         {
67             return false;
68         }
69     }
70 
71     return true;
72 }
computeApproxPointsDensityInACellAtLevel

 double R2 = nNSS.pointsInNeighbourhood[1].squareDistd;  //索引為1的點,表示最近鄰點。pi點與最近鄰點之間距離的平方。

相關推薦

[CC]密度計算

  包括兩種計算方法:精確計算和近似計算(思考:local density=單位面積的點數 vs  local density =1/單個點所佔的面積) 每種方法可以實現三種模式的點雲密度計算,CC裡面的點雲端計算依賴於 給定的近鄰半徑所對應的最佳八叉樹層級 (通過findBestLevelForAGiv

密度計算

double computeCloudResolution (const pcl::PointCloud<PointType>::ConstPtr &cloud) { double res = 0.0; int n_points = 0; int nres;

兩種三維密度聚類方法的研究與對比

轉載請說明出處: http://blog.csdn.net/zhubaohua_bupt/article/details/70194047 基於密度的點雲聚類演算法可以識別三維點雲物體,也可以對三維點雲去噪處理。 本文研究了兩種基於密度的點雲聚類方法,先簡單介紹一下兩種演

/網格模型的體積計算

pro nis top 方便 vol ref org splay 會有 點雲體積計算   有時用激光掃描設備掃描零件或者用無人機進行測量後會想知道它們的體積。比如下面的土堆:   如果掃描得到的數據是一系列三維點雲,那麽體積就比較難求,因為如何定義物體的邊界比較

[PCL]2 法向量計算NormalEstimation

參考:http://www.cnblogs.com/yhlx125/p/5137850.html  從GitHub的程式碼版本庫下載原始碼https://github.com/PointCloudLibrary/pcl,用CMake生成VS專案,檢視PCL的原始碼位於pcl_featu

由深度圖計算的原理

本文整理了兩種計算點雲資料的方法,其核心都是根據針孔成像原理而來。 一、ROS中的方法 首先,要了解下世界座標到影象的對映過程,考慮世界座標點M(Xw,Yw,Zw)對映到影象點m(u,v)的過程,如下圖所示: 參考針孔成像原理 其中u,v為影象座標系下的任意座標點。

的平滑與法線計算

需要平滑的情況: 1、用RGB-D鐳射掃描器等裝置掃描物體,尤其是比較小的物體時,往往會有測量誤差。這些誤差所造成的不規則資料如果直接拿來曲面重建的話,會使得重建的曲面不光滑或者有漏洞,而且這種不規則資料很難用前面我們提到過的統計分析等濾波方法消除; 2、後處理過程中,對同一個物體從不同方向

的基本幾何計算

1.計算法向量 原檔案 function normal = estimateNormal(data, tree, query, radius, min_neighbors) % ESTIMATENORMAL Given a point cloud and query point, estimate

[CC]區域生長演算法——分割

 基於CC寫的外掛,利用PCL中演算法實現: 1 void qLxPluginPCL::doRegionGrowing() 2 { 3 assert(m_app); 4 if (!m_app) 5 return; 6 7

計算的最小BBOX

參考1 參考2 #include <iostream> #include <pcl/io/pcd_io.h> #include <pcl/point_types.h> #include <pcl/visualizat

模型的局部曲面幾何資訊的提取(法向量的計算

估算法向量法向量是三維點雲資料具有的一個很重要的區域性特性,在點雲的許多處理中是必不可少的資訊。三維掃描獲取的初始取樣點集只記錄了各取樣點的空間三維座標,而不存在任何連線關係,求解法向量是處理點雲資料的第一步。在三維軟體中求解取樣點的法向量,一般要求建立點雲資料對應的網路模型

PCL中計算的法向量並顯示

// NormalEstimation.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <pcl/point_t

orientation_points_xld (Operator)----計算輪廓或多邊形的方向

計算點雲輪廓或點雲多邊形的方向(該點雲的順序不會考慮其中)①如果該XLD與自身相交或者如果自身相交能用一條線把其首尾相連,使用orientation_points_xld 運算元,可以使用 test_self_intersection_xld運算元測試該XLD能否自身相交②如

QT opengl 模仿CC~現在可以顯示彩色

那麼話不多說了啊,最近發現程式碼連結失效問題,那麼沒關係,全部原始碼已經分享到我置頂的文章上面了。 如果仍然發現失效問題(博主也是個白痴呢),請務必加我QQ 498771026 相信很多人用過CC,也就是CloudCompare。這款軟體對於點雲的讀取和顯示有點厲害。 我相

通過Kinect的深度影象資料計算三維

在可以透過 OpenNI 讀取到 Kinect 的深度、色彩資訊之後,其實就可以試著用這些資訊,來重建 3D 的環境做顯示了~不過實際上,在前面的範例中所讀到的深度資訊,都算是原始資料,而且座標軸也都是感應器二維影像的座標系統,如果要重建 3D 場景的話,這些資訊都還是需要換算的;所幸,OpenNI 在 D

VisualSFM+PMVS生成稠密

我的電腦 調用 span visual bit .cn 電腦 菜單 32bit 利用相機拍攝一個場景不同角度的圖片,使用VisualSFM能夠得到稀疏點雲,如果想要得到稠密點雲,可以在VisualSFM中加入PMVS的應用程序,PMVS會作為一個插件運行將稀疏點雲插成稠密的

原生計算基金會宣布 JFrog 為金牌會員

width factor 部署 認證 找到 style pos vmware rgb DevOps Expert 加入 CNCF 以進一步實現雲原生操作的最佳實踐。2017年12月4日 - 支持和集成 Kubernetes? 和 Prometheus? 等開源技術的雲原生計

PCL—分割(最小割算法)

number 作用 早就 有效 好的 介紹 不同的 優勢 bsp 1.點雲分割的精度   在之前的兩個章節裏介紹了基於采樣一致的點雲分割和基於臨近搜索的點雲分割算法。基於采樣一致的點雲分割算法顯然是意識流的,它只能割出大概的點雲(可能是杯子的一部分,但杯把兒肯定沒分割出來)

PCL—關鍵點檢測(rangeImage)低層次處理

數據結構 關系 n-1 -a 平面 邊緣提取 bubuko 數據 方式 博客轉載自:http://www.cnblogs.com/ironstark/p/5046479.html 關鍵點又稱為感興趣的點,是低層次視覺通往高層次視覺的捷徑,抑或是高層次感知對低層次處理手段的妥

處理中的一些後續問題。

一些事 才會 class 識別 空格 div 距離 出現 問題 1.在對點雲處理的步驟中,對深度沒有值的地方,對點的處理方法大部分是均為0。某些時候會出現問題,需要對這部分進行操作。(設置一個最遠的值,為了可以去掉障礙物,去不掉原因可能是 在障礙物所在的地方,在設置的最遠