OpenCV 4.13.0
開源計算機視覺庫 (Open Source Computer Vision)
正在載入...
正在搜尋...
未找到匹配項
表面匹配

詳細說明

關於許可證和專利的注意事項

本軟體中體現的方法已獲得以下專利:“使用幾何點對描述符和廣義霍夫變換識別和確定3D場景中3D物件姿態”,Bertram Heinrich Drost, Markus Ulrich, 歐洲專利2385483(2012年11月21日),受讓人:MVTec Software GmbH, 81675 慕尼黑(德國);“識別和確定3D場景中3D物件姿態”,Bertram Heinrich Drost, Markus Ulrich, 美國專利8830229(2014年9月9日),受讓人:MVTec Software GmbH, 81675 慕尼黑(德國)。其他專利正在申請中。欲瞭解更多詳情,請聯絡 MVTec Software GmbH (info@.nosp@m.mvte.nosp@m.c.com)。

請注意,這些專利(以及可能的其他專利)施加的限制獨立存在,並可能與本許可授予的自由相沖突,本許可指的是程式的版權,而非其實現的任何方法的專利。要合法使用和重新分發此程式,必須同時遵守版權法和專利法,本許可的目的不是誘導您侵犯任何專利或其他財產權主張,或質疑任何此類主張的有效性。如果您重新分發或使用該程式,則本許可僅保護您免受版權侵犯。它不保護您免受專利侵犯。因此,在您對本程式進行任何操作之前,請確保您不僅在版權方面,而且在專利法方面都獲得了許可。

請注意,本許可也不應被理解為一種保證。如果您根據本許可使用該程式,但與專利法相沖突,這並不意味著如果您因專利侵權而被起訴,許可方將退還您所遭受的任何損失。

表面匹配簡介

具有3D結構感知能力的相機及類似裝置越來越普及。因此,利用深度和強度資訊匹配3D物體(或部件)對計算機視覺至關重要。應用範圍從工業控制到指導視障人士的日常行動。在距離影像中進行識別和姿態估計的任務旨在透過將查詢的3D自由曲面物體與獲取的資料庫進行匹配來識別並定位它。

從工業角度來看,使機器人能夠自動定位和拾取箱子中隨機放置和定向的物體是工廠自動化中的一個重要挑戰,它取代了繁瑣和繁重的體力勞動。一個系統應該能夠識別和定位具有預定義形狀的物體,並以抓取機器人拾取它所需的精度估計位置。這就是視覺引導機器人技術發揮作用的地方。類似的工具也能夠引導機器人(甚至人類)透過非結構化環境,從而實現自動化導航。這些特性使得從點雲進行3D匹配成為普遍的必需品。在此背景下,我將介紹OpenCV中利用3D特徵實現3D物體識別和姿態估計算法。

透過3D特徵實現表面匹配演算法

為實現3D匹配任務的演算法狀態主要基於 [76],這是該領域最早也是主要的實用方法之一。該方法包括從深度影像或通用點雲中隨機提取3D特徵點,對其進行索引,然後在執行時高效地查詢它們。只考慮3D結構,並使用一個簡單的雜湊表進行特徵查詢。

雖然我完全意識到利用CAD模型的良好結構可以實現智慧點取樣,但我現在將擱置這一點,以尊重方法的通用性(通常對於此類演算法,不需要在CAD模型上進行訓練,點雲就足夠了)。下面是整個演算法的概述

演算法概述

如前所述,該演算法依賴於點對特徵的提取和索引,其定義如下:

\[\bf{{F}}(\bf{{m1}}, \bf{{m2}}) = (||\bf{{d}}||_2, <(\bf{{n1}},\bf{{d}}), <(\bf{{n2}},\bf{{d}}), <(\bf{{n1}},\bf{{n2}}))\]

其中 \(\bf{{m1}}\) 和 \(\bf{{m2}}\) 是模型(或場景)上選定的兩個特徵點, \(\bf{{d}}\) 是差向量, \(\bf{{n1}}\) 和 \(\bf{{n2}}\) 是 \(\bf{{m1}}\) 和 \(\bf{m2}\) 處的法線。在訓練階段,此向量被量化並索引。在測試階段,從場景中提取相同的特徵並與資料庫進行比較。透過一些技巧,例如分離旋轉分量,姿態估計部分也可以變得高效(有關更多詳細資訊,請查閱參考文獻)。採用類似Hough的投票和聚類來估計物體姿態。為了聚類姿態,原始姿態假設按投票數量降序排列。從最高投票中建立一個新簇。如果下一個姿態假設與現有簇之一接近,則將該假設新增到該簇中,並將簇中心更新為簇內姿態假設的平均值。如果下一個假設不接近任何簇,則建立一個新簇。鄰近性測試使用固定的平移和旋轉閾值進行。平移的距離計算和平均在3D歐幾里得空間中執行,而旋轉的距離計算和平均使用四元數表示。聚類後,簇按總投票數量降序排列,這決定了估計姿態的置信度。

此姿態透過 \(ICP\) 進一步細化,以獲得最終姿態。

上面介紹的 PPF 主要依賴於 3D 向量之間角度的魯棒計算。儘管論文中沒有報道,但這樣做的幼稚方法 ( \(\theta = cos^{-1}({\bf{a}}\cdot{\bf{b}})\) 在數值上仍然不穩定。更好的方法是使用反切線,例如

\[<(\bf{n1},\bf{n2})=tan^{-1}(||{\bf{n1} \wedge \bf{n2}}||_2, \bf{n1} \cdot \bf{n2})\]

給定PPF的物體姿態粗略計算

我總結一下以下符號

點對特徵的變換首先透過從第一個點找到變換 \(T_{m\rightarrow g}\),然後將相同的變換應用於第二個點來計算。將每個點及其法線變換到地面,在與新點對進行比較時,我們只剩下需要找到一個角度。

我們現在可以簡單地開始寫

\[(p^i_m)^{'} = T_{m\rightarrow g} p^i_m\]

其中

\[T_{m\rightarrow g} = -t_{m\rightarrow g}R_{m\rightarrow g}\]

注意,這只不過是一個堆疊變換。平移分量 \(t_{m\rightarrow g}\) 為

\[t_{m\rightarrow g} = -R_{m\rightarrow g}p^i_m\]

旋轉分量為

\[\theta_{m\rightarrow g} = \cos^{-1}(n^i_m \cdot {\bf{x}})\\ {\bf{R_{m\rightarrow g}}} = n^i_m \wedge {\bf{x}}\]

以軸角格式。注意粗體表示向量形式。在此變換之後,模型的特徵向量被註冊到X地面,並且相對於 \(x=0\) 的角度被稱為 \(\alpha_m\)。類似地,對於場景,它被稱為 \(\alpha_s\)。

類似Hough的投票方案

如概述所示,在訓練階段,從模型中提取PPF(點對特徵),量化,儲存在雜湊表中並建立索引。然而,在執行時,對輸入場景執行類似操作,不同之處在於,這次是對雜湊表執行相似性查詢,而不是插入。此查詢還允許我們為場景對計算到地面的變換。此時,姿態的旋轉分量計算簡化為計算差值 \(\alpha=\alpha_m-\alpha_s\)。此分量攜帶有關物體姿態的線索。在區域性模型座標向量和 \(\alpha\) 上執行類似Hough的投票方案。為每個場景點獲得的最高姿態允許我們恢復物體姿態。

PPF匹配的原始碼

// pc是載入的模型點雲
// (Nx6),pcTest是載入的場景點雲
// (Mx6)
ppf_match_3d::PPF3DDetector detector(0.03, 0.05);
detector.trainModel(pc);
vector<Pose3DPtr> results;
detector.match(pcTest, results, 1.0/10.0, 0.05);
cout << "Poses: " << endl;
// 列印姿態
for (size_t i=0; i<results.size(); i++)
{
Pose3DPtr pose = results[i];
cout << "Pose Result " << i << endl;
pose->printPose();
}
Ptr< Pose3D > Pose3DPtr
定義 pose_3d.hpp:59
@ pc
定義 container_avi.private.hpp:138

透過ICP進行姿態配準

匹配過程隨著姿態的獲得而終止。然而,由於多重匹配點、錯誤假設、姿態平均等,這樣的姿態非常容易受到噪聲影響,並且許多時候遠非完美。儘管在該階段獲得的視覺結果令人滿意,但定量評估顯示約 \(~10\) 度的變化(誤差),這是一個可接受的匹配水平。許多時候,要求可能遠遠超出這個範圍,並且期望能夠細化計算出的姿態。

此外,在典型的RGBD場景和點雲中,由於場景中的可見性,3D結構只能捕獲模型的一半以下。因此,一個魯棒的姿態細化演算法,能夠快速準確地配準被遮擋和部分可見的形狀,並非不切實際的願望。

此時,一個簡單的選擇是使用眾所周知的迭代最近點演算法。然而,使用基本的 ICP 會導致收斂緩慢、配準不良、對異常值敏感以及無法配準部分形狀。因此,它絕對不適合該問題。出於這個原因,已經提出了許多變體。不同的變體對姿態估計過程的不同階段做出了貢獻。

ICP 由 \(6\) 個階段組成,我為每個階段提出的改進總結如下。

取樣

為了提高收斂速度和計算時間,通常使用比模型實際點數少的點。然而,取樣正確的點進行配準本身就是一個問題。簡單的方法是均勻取樣,並希望能獲得一個合理的子集。更聰明的方法試圖識別關鍵點,這些關鍵點被發現對配準過程有很大貢獻。Gelfand 等人利用協方差矩陣來限制特徵空間,以便使用一組同時影響平移和旋轉的點。這是一種聰明的子取樣方法,我將在實現中選擇性地使用它。

對應搜尋

顧名思義,這一步實際上是資料點和模型點以最近點方式進行賦值。正確的賦值將導致正確的姿態,而錯誤的賦值會嚴重降低結果。通常,KD樹用於搜尋最近鄰,以提高速度。然而,這並不能保證最優性,並且很多時候會導致錯誤的點匹配。幸運的是,賦值會在迭代過程中得到糾正。

為了克服一些限制,Picky ICP [327] 和 BC-ICP(使用雙唯一對應關係的 ICP)是兩種眾所周知的方法。Picky ICP 首先以老式方式找到對應關係,然後在結果對應的點對中,如果多個場景點 \(p_i\) 被分配給同一個模型點 \(m_j\),它會選擇對應於最小距離的 \(p_i\)。另一方面,BC-ICP 首先允許多個對應關係,然後透過建立雙唯一對應關係來解決賦值。它還定義了一種新穎的無對應關係異常值,這本身就簡化了異常值識別過程。

為了參考,兩種方法都使用了。因為 P-ICP 速度稍快,且效能損失不明顯,它將成為對應關係細化中的首選方法。

對對進行加權

在我的實現中,我目前不使用加權方案。但常見的方法包括法線相容性* ( \(w_i=n^1_i\cdot n^2_j\)) 或對距離較大的點對分配較低的權重 ( \(w=1-\frac{||dist(m_i,s_i)||_2}{dist_{max}}\))。

對對進行拒絕

拒絕使用基於標準差的魯棒估計的動態閾值。換句話說,在每次迭代中,我都會找到標準差的 MAD 估計值。我將其表示為 \(mad_i\)。我拒絕距離 \(d_i>\tau mad_i\) 的對。這裡 \(\tau\) 是拒絕閾值,預設設定為 \(3\)。加權在 Picky 細化之前應用,如前一階段所述。

誤差度量

如 [CITEREF_koklimlow][178] 中所述,使用點到平面誤差度量的線性化,這既加快了配準過程,又提高了收斂性。

最小化

儘管提出了許多非線性最佳化器(例如 Levenberg-Marquardt),但由於上一步中的線性化,姿態估計簡化為求解一個線性方程組。這正是我使用 cv::solve 和 DECOMP_SVD 選項所做的。

ICP演算法

在描述了以上步驟之後,我在此總結了 ICP 演算法的佈局。

透過點雲金字塔實現高效ICP

雖然迄今為止提出的變體能夠很好地處理一些異常值和不良初始化,但它們需要大量的迭代。然而,多解析度方案可以透過允許配準從粗糙級別開始並傳播到更低和更精細的級別來幫助減少迭代次數。這種方法既提高了效能又增強了執行時效率。

搜尋透過多個級別,以分層方式進行。配準從模型的一組非常粗略的樣本開始。迭代地,點被加密和搜尋。在每次迭代之後,先前估計的姿態被用作初始姿態並使用 ICP 進行細化。

視覺化結果

合成數據結果

在所有結果中,姿態由PPF初始化,其餘設定為: \([\theta_x, \theta_y, \theta_z, t_x, t_y, t_z]=[0]\)

使用ICP進行姿態細化的原始碼

ICP icp(200, 0.001f, 2.5f, 8);
// 使用之前宣告的pc和pcTest
// 這將為results中包含的每個姿態執行配準
// 執行配準
icp.registerModelToScene(pc, pcTest, results);
// results現在包含細化後的姿態

結果

本節專門介紹表面匹配(點對特徵匹配和隨後的 ICP 細化)的結果。

單個青蛙模型使用ppf + icp 的幾次匹配

下面展示了 Mian 資料集中不同模型的匹配結果。

Mian 資料集中不同模型的匹配

您可以點選 此處 在 YouTube 上觀看影片。

完整示例

引數調整

只要可能,表面匹配模組會將其引數相對於模型直徑(軸平行邊界框的直徑)進行處理。這使得引數與模型大小無關。這就是為什麼模型和場景雲都被子取樣,使得所有點之間的最小距離為 \(RelativeSamplingStep*DimensionRange\),其中 \(DimensionRange\) 是沿給定維度上的距離。所有三個維度都以類似方式取樣。例如,如果 \(RelativeSamplingStep\) 設定為 0.05 且模型直徑為 1m (1000mm),則從物體表面取樣的點之間的距離大約為 50mm。從另一個角度看,如果取樣 RelativeSamplingStep 設定為 0.05,則最多生成 \(20x20x20 = 8000\) 個模型點(取決於模型如何填充體積)。因此,這導致最多 8000x8000 對。在實踐中,由於模型並非均勻分佈在矩形稜柱上,預計點數會少得多。減小此值會導致更多的模型點,從而獲得更準確的表示。然而,請注意,要計算的點對特徵的數量現在呈二次增加,因為複雜度為 O(N^2)。這對於 32 位系統來說尤其是一個問題,因為大型模型很容易超出可用記憶體。通常,0.025 - 0.05 範圍內的值對於大多數應用程式來說似乎足夠,預設值為 0.03。(請注意,此引數與 [76] 中介紹的引數存在差異。在 [76] 中,使用均勻長方體進行量化,並使用模型直徑作為取樣的參考。在我的實現中,長方體是一個矩形稜柱,每個維度獨立量化。我不從直徑而是從各個維度獲取參考。

從模型中去除異常值並初步準備一個理想模型將是非常明智的。這是因為,異常值會直接影響相對計算並降低匹配精度。

在執行時階段,場景再次透過 \(RelativeSamplingStep\) 進行取樣,如上所述。然而這次,只有一部分場景點被用作參考。這部分由引數 \(RelativeSceneSampleStep\) 控制,其中 \(SceneSampleStep = (int)(1.0/RelativeSceneSampleStep)\)。換句話說,如果 \(RelativeSceneSampleStep = 1.0/5.0\),則子取樣場景將再次均勻取樣到原始點數的 1/5。此引數的最大值為 1,增加此引數也會增加穩定性,但會降低速度。同樣,由於初始場景無關的相對取樣,微調此引數並不是一個大問題。只有當模型形狀均勻佔據一個體積,或者當模型形狀集中在量化體積內的一個微小位置時(例如,八叉樹表示會有太多空單元格),這才會成為一個問題。

\(RelativeDistanceStep\) 作為雜湊表上的離散化步驟。點對特徵被量化以對映到雜湊表的桶中。這種離散化涉及乘法和轉換為整數。理論上,調整 RelativeDistanceStep 控制碰撞率。請注意,雜湊表上的碰撞越多,估計的準確性就越低。減小此引數會增加量化的影響,但會開始將不相似的點對分配到相同的桶中。然而,增加此引數會削弱對相似點對進行分組的能力。通常,由於在取樣階段,訓練模型點以由 RelativeSamplingStep 控制的距離均勻選擇,因此 RelativeDistanceStep 預計等於此值。但同樣,0.025-0.05 範圍內的值是合理的。然而,這次,當模型密集時,不建議減小此值。對於嘈雜的場景,可以增加此值以提高匹配對嘈雜點的魯棒性。

結構體  hashnode_i
 
結構體  hashtable_int
 
類  cv::ppf_match_3d::ICP
 此類實現了迭代最近點 (ICP) 演算法的一個非常高效且魯棒的變體。任務是將 3D 模型(或點雲)與一組帶噪聲的目標資料進行配準。這些變體是我經過某些測試後組合而成的。任務是能夠快速匹配混亂場景中的部分、帶噪聲的點雲。您會發現我強調的是效能,同時保持準確性。此實現基於 Tolga Birdal 在此處的 MATLAB 實現:http://www.mathworks.com/matlabcentral/fileexchange/47152-icp-registration-using-efficient-variants-and-multi-resolution-scheme 主要貢獻來自:更多...
 
類  cv::ppf_match_3d::Pose3D
 類,允許儲存姿態。資料結構儲存四元數和矩陣形式。它支援IO功能以及各種輔助方法來處理姿態。 更多...
 
類  cv::ppf_match_3d::PoseCluster3D
 當多個姿態(參見 Pose3D)組合在一起(貢獻於相同的變換)時,就會出現姿態簇。此類是此類姿態組的通用容器。可以儲存、載入和對這些姿態執行 IO。更多...
 
類  cv::ppf_match_3d::PPF3DDetector
 類,允許載入和匹配 3D 模型。典型用法: 更多...
 
結構體  THash
 結構體,儲存雜湊表中的一個節點。 更多...
 

型別定義 (Typedefs)

typedef uint cv::ppf_match_3d::KeyType
 
typedef Ptr< Pose3Dcv::ppf_match_3d::Pose3DPtr
 
typedef Ptr< PoseCluster3Dcv::ppf_match_3d::PoseCluster3DPtr
 

函式

Mat cv::ppf_match_3d::addNoisePC (Mat pc, double scale)
 
void cv::ppf_match_3d::computeBboxStd (Mat pc, Vec2f &xRange, Vec2f &yRange, Vec2f &zRange)
 
int cv::ppf_match_3d::computeNormalsPC3d (const Mat &PC, Mat &PCNormals, const int NumNeighbors, const bool FlipViewpoint, const Vec3f &viewpoint)
 計算任意點雲的法線。computeNormalsPC3d 使用平面擬合方法平滑計算區域性法線。法線透過協方差矩陣的特徵向量獲得,該特徵向量對應於最小特徵值。如果提供 PCNormals 作為 Nx6 矩陣,則不會進行新的記憶體分配,而是覆蓋現有記憶體。
 
void cv::ppf_match_3d::destroyFlann (void *flannIndex)
 
void cv::ppf_match_3d::getRandomPose (Matx44d &Pose)
 
hashtable_intcv::ppf_match_3d::hashtable_int_clone (hashtable_int *hashtbl)
 
hashtable_intcv::ppf_match_3d::hashtableCreate (size_t size, size_t(*hashfunc)(uint))
 
void cv::ppf_match_3d::hashtableDestroy (hashtable_int *hashtbl)
 
void * cv::ppf_match_3d::hashtableGet (hashtable_int *hashtbl, KeyType key)
 
hashnode_icv::ppf_match_3d::hashtableGetBucketHashed (hashtable_int *hashtbl, KeyType key)
 
int cv::ppf_match_3d::hashtableInsert (hashtable_int *hashtbl, KeyType key, void *data)
 
int cv::ppf_match_3d::hashtableInsertHashed (hashtable_int *hashtbl, KeyType key, void *data)
 
void cv::ppf_match_3d::hashtablePrint (hashtable_int *hashtbl)
 
hashtable_intcv::ppf_match_3d::hashtableRead (FILE *f)
 
int cv::ppf_match_3d::hashtableRemove (hashtable_int *hashtbl, KeyType key)
 
int cv::ppf_match_3d::hashtableResize (hashtable_int *hashtbl, size_t size)
 
int cv::ppf_match_3d::hashtableWrite (const hashtable_int *hashtbl, const size_t dataSize, FILE *f)
 
void * cv::ppf_match_3d::indexPCFlann (Mat pc)
 
Mat cv::ppf_match_3d::loadPLYSimple (const char *fileName, int withNormals=0)
 載入PLY檔案。
 
static uint cv::ppf_match_3d::next_power_of_two (uint value)
 向上取整到下一個2的冪。
 
Mat cv::ppf_match_3d::normalizePCCoeff (Mat pc, float scale, float *Cx, float *Cy, float *Cz, float *MinVal, float *MaxVal)
 
void cv::ppf_match_3d::queryPCFlann (void *flannIndex, Mat &pc, Mat &indices, Mat &distances)
 
void cv::ppf_match_3d::queryPCFlann (void *flannIndex, Mat &pc, Mat &indices, Mat &distances, const int numNeighbors)
 
Mat cv::ppf_match_3d::samplePCByQuantization (Mat pc, Vec2f &xrange, Vec2f &yrange, Vec2f &zrange, float sample_step_relative, int weightByCenter=0)
 
Mat cv::ppf_match_3d::samplePCUniform (Mat PC, int sampleStep)
 
Mat cv::ppf_match_3d::samplePCUniformInd (Mat PC, int sampleStep, std::vector< int > &indices)
 
Mat cv::ppf_match_3d::transformPCPose (Mat pc, const Matx44d &Pose)
 
Mat cv::ppf_match_3d::transPCCoeff (Mat pc, float scale, float Cx, float Cy, float Cz, float MinVal, float MaxVal)
 
void cv::ppf_match_3d::writePLY (Mat PC, const char *fileName)
 將點雲寫入PLY檔案。
 
void cv::ppf_match_3d::writePLYVisibleNormals (Mat PC, const char *fileName)
 用於除錯目的,將點雲寫入PLY檔案,法向量的尖端顯示為可見的紅點。
 

型別定義文件 (Typedef Documentation)

◆ KeyType

◆ Pose3DPtr

◆ PoseCluster3DPtr

函式文件 (Function Documentation)

◆ addNoisePC()

Mat cv::ppf_match_3d::addNoisePC ( Mat pc,
double scale )
Python
cv.ppf_match_3d.addNoisePC(pc, scale) -> retval

#include <opencv2/surface_matching/ppf_helpers.hpp>

向輸入點雲新增給定尺度的均勻噪聲

引數
[in]pc輸入點雲(CV_32F 系列)。
[in]scale輸入噪聲的比例。比例越大,輸出噪聲越大

◆ computeBboxStd()

void cv::ppf_match_3d::computeBboxStd ( Mat pc,
Vec2f & xRange,
Vec2f & yRange,
Vec2f & zRange )

◆ computeNormalsPC3d()

int cv::ppf_match_3d::computeNormalsPC3d ( const Mat & PC,
Mat & PCNormals,
const int NumNeighbors,
const bool FlipViewpoint,
const Vec3f & viewpoint )
Python
cv.ppf_match_3d.computeNormalsPC3d(PC, NumNeighbors, FlipViewpoint, viewpoint[, PCNormals]) -> retval, PCNormals

#include <opencv2/surface_matching/ppf_helpers.hpp>

計算任意點雲的法線。computeNormalsPC3d 使用平面擬合方法平滑計算區域性法線。法線透過協方差矩陣的特徵向量獲得,該特徵向量對應於最小特徵值。如果提供 PCNormals 作為 Nx6 矩陣,則不會進行新的記憶體分配,而是覆蓋現有記憶體。

引數
[in]PC要計算法線的輸入點雲。
[out]PCNormals輸出點雲
[in]NumNeighbors在區域性區域中要考慮的鄰居數量
[in]FlipViewpoint法線是否應翻轉到視角方向?
[in]viewpoint
返回
成功時返回 0

◆ destroyFlann()

void cv::ppf_match_3d::destroyFlann ( void * flannIndex)

◆ getRandomPose()

void cv::ppf_match_3d::getRandomPose ( Matx44d & Pose)
Python
cv.ppf_match_3d.getRandomPose(Pose) -> None

#include <opencv2/surface_matching/ppf_helpers.hpp>

生成一個隨機的 4x4 姿態矩陣

引數
[out]Pose隨機姿態

◆ hashtable_int_clone()

hashtable_int * cv::ppf_match_3d::hashtable_int_clone ( hashtable_int * hashtbl)

◆ hashtableCreate()

hashtable_int * cv::ppf_match_3d::hashtableCreate ( size_t size (大小),
size_t(* hashfunc )(uint) )

◆ hashtableDestroy()

void cv::ppf_match_3d::hashtableDestroy ( hashtable_int * hashtbl)

◆ hashtableGet()

void * cv::ppf_match_3d::hashtableGet ( hashtable_int * hashtbl,
KeyType key )

◆ hashtableGetBucketHashed()

hashnode_i * cv::ppf_match_3d::hashtableGetBucketHashed ( hashtable_int * hashtbl,
KeyType key )

◆ hashtableInsert()

int cv::ppf_match_3d::hashtableInsert ( hashtable_int * hashtbl,
KeyType key,
void * data (資料) )

◆ hashtableInsertHashed()

int cv::ppf_match_3d::hashtableInsertHashed ( hashtable_int * hashtbl,
KeyType key,
void * data (資料) )

◆ hashtablePrint()

void cv::ppf_match_3d::hashtablePrint ( hashtable_int * hashtbl)

◆ hashtableRead()

hashtable_int * cv::ppf_match_3d::hashtableRead ( FILE * f)

◆ hashtableRemove()

int cv::ppf_match_3d::hashtableRemove ( hashtable_int * hashtbl,
KeyType key )

◆ hashtableResize()

int cv::ppf_match_3d::hashtableResize ( hashtable_int * hashtbl,
size_t size (大小) )

◆ hashtableWrite()

int cv::ppf_match_3d::hashtableWrite ( const hashtable_int * hashtbl,
const size_t dataSize,
FILE * f )

◆ indexPCFlann()

void * cv::ppf_match_3d::indexPCFlann ( Mat pc)

◆ loadPLYSimple()

Mat cv::ppf_match_3d::loadPLYSimple ( const char * fileName,
int withNormals = 0 )
Python
cv.ppf_match_3d.loadPLYSimple(fileName[, withNormals]) -> retval

#include <opencv2/surface_matching/ppf_helpers.hpp>

載入PLY檔案。

引數
[in]fileName要讀取的PLY模型
[in]withNormals輸入PLY是否包含法線資訊,以及是否應該載入的標誌
返回
成功載入時返回矩陣

◆ next_power_of_two()

static uint cv::ppf_match_3d::next_power_of_two ( uint value (值))
inlinestatic

◆ normalizePCCoeff()

Mat cv::ppf_match_3d::normalizePCCoeff ( Mat pc,
float scale,
float * Cx,
float * Cy,
float * Cz,
float * MinVal,
float * MaxVal )

◆ queryPCFlann() [1/2]

void cv::ppf_match_3d::queryPCFlann ( void * flannIndex,
Mat & pc,
Mat & indices,
Mat & distances )

◆ queryPCFlann() [2/2]

void cv::ppf_match_3d::queryPCFlann ( void * flannIndex,
Mat & pc,
Mat & indices,
Mat & distances,
const int numNeighbors )

◆ samplePCByQuantization()

Mat cv::ppf_match_3d::samplePCByQuantization ( Mat pc,
Vec2f & xrange,
Vec2f & yrange,
Vec2f & zrange,
float sample_step_relative,
int weightByCenter = 0 )
Python
cv.ppf_match_3d.samplePCByQuantization(pc, xrange, yrange, zrange, sample_step_relative[, weightByCenter]) -> retval

#include <opencv2/surface_matching/ppf_helpers.hpp>

使用均勻步長取樣點雲

引數
[in]pc輸入點雲
[in]xrange模型邊界框的X分量(最小值和最大值)
[in]yrange模型邊界框的Y分量(最小值和最大值)
[in]zrange模型邊界框的Z分量(最小值和最大值)
[in]sample_step_relative點雲的取樣方式是所有點之間都有一定的最小距離。這個最小距離透過引數sample_step_relative相對確定。
[in]weightByCenter量化資料點的貢獻可以根據到原點的距離進行加權。此引數啟用/停用加權的使用。
返回
取樣點雲

◆ samplePCUniform()

Mat cv::ppf_match_3d::samplePCUniform ( Mat PC,
int sampleStep )

◆ samplePCUniformInd()

Mat cv::ppf_match_3d::samplePCUniformInd ( Mat PC,
int sampleStep,
std::vector< int > & indices )

◆ transformPCPose()

Mat cv::ppf_match_3d::transformPCPose ( Mat pc,
const Matx44d & Pose )
Python
cv.ppf_match_3d.transformPCPose(pc, Pose) -> retval

#include <opencv2/surface_matching/ppf_helpers.hpp>

使用給定的齊次 4x4 姿態矩陣(雙精度)變換點雲

引數
[in]pc輸入點雲(CV_32F 系列)。預期每行有 3 或 6 個元素的點雲。如果提供了法線,它們也會被旋轉以與整個變換相容
[in]Pose4x4 姿態矩陣,但以行主序線性化。
返回
變換後的點雲

◆ transPCCoeff()

Mat cv::ppf_match_3d::transPCCoeff ( Mat pc,
float scale,
float Cx,
float Cy,
float Cz,
float MinVal,
float MaxVal )

◆ writePLY()

void cv::ppf_match_3d::writePLY ( Mat PC,
const char * fileName )
Python
cv.ppf_match_3d.writePLY(PC, fileName) -> None

#include <opencv2/surface_matching/ppf_helpers.hpp>

將點雲寫入PLY檔案。

引數
[in]PC輸入點雲
[in]fileName要寫入的PLY模型檔案

◆ writePLYVisibleNormals()

void cv::ppf_match_3d::writePLYVisibleNormals ( Mat PC,
const char * fileName )
Python
cv.ppf_match_3d.writePLYVisibleNormals(PC, fileName) -> None

#include <opencv2/surface_matching/ppf_helpers.hpp>

用於除錯目的,將點雲寫入PLY檔案,法向量的尖端顯示為可見的紅點。

引數
[in]PC輸入點雲
[in]fileName要寫入的PLY模型檔案