OpenCV  4.10.0
开源计算机视觉
加载中...
搜索中...
没有匹配
| 类型定义 | 函数
表面对齐

详细描述

关于许可证和专利的说明

以下专利已针对软件中实现的方法颁发:"在3D场景中使用几何点对描述符和广义休哈夫变换识别和位姿确定3D对象",Bertram Heinrich Drost,Markus Ulrich,EP专利2385483(2012年11月21日),权利人:MVTec Software GmbH,81675慕尼黑(德国);"在3D场景中识别和位姿确定3D对象",Bertram Heinrich Drost,Markus Ulrich,US专利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匹配任务的算法状态高度基于[72],这是在这个领域中首先提出的主要实际方法之一。该方法由从深度图像或通用点云中随机提取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的投票和聚类来估计对象姿态。为了聚类姿态,按照投票数降序排列原始姿态假设。从最高投票数开始创建一个新的聚类。如果下一个姿态假设接近现有的一个聚类,则将该假设添加到该聚类中,并将聚类中心更新为聚类内姿态假设的平均值。如果下一个假设不接近任何现有聚类,则创建一个新的聚类。距离测试使用固定的平移和旋转阈值进行。平移计算和平均在三维欧几里得空间中进行,而旋转使用四元数表示进行。聚类后,按照总投票数的降序排列这些聚类,这决定了估计姿态的置信度。

然后使用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-like Voting Scheme

如图所示,在训练阶段从模型中提取了PPF(点对特征),量化和存储在散列表中,并进行索引。但是在运行时间,对场景进行了类似的操作,但是此次是对散列表进行相似度查找,而不是插入。此查找还可以让我们计算场景对的地面平面变换。在此之后,计算姿态的姿态分量简化为计算 \( \alpha = \alpha_m - \alpha_s \) 的差异。该分量携带了关于物体姿态的线索。对局部模型坐标矢量和 \(\alpha\) 进行Hough-like投票。每一场景点的最高姿态使我们能够恢复物体的姿态。

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 << “姿态:” << endl;
// 打印姿态
for (size_t i=0; i<results.size(); i++)
{
Pose3DPtr pose = results[i];
cout << "姿态结果 " << i << endl;
pose->printPose();
}
Ptr< Pose3D > Pose3DPtr
定义 pose_3d.hpp:59
@ pc
定义 container_avi.private.hpp:136

基于ICP的姿态注册

匹配过程以姿态的获得而结束。然而,由于匹配点的数量和错误的假设,姿态的平均化和等,这样的姿态非常容易受到噪声的影响,很多时候离完美很远。尽管该阶段的视觉结果很令人满意,但量化评估显示 \(~10\) 度的变化(误差),这是一个可接受的匹配水平。很多时候,要求可能设置在这个范围之外,需要细化计算出的姿态。

此外,在典型的RGBD场景和点云中,由于场景中的可见度问题,只能捕捉到模型不到一半的3D结构。因此,一种鲁棒性的姿态细化算法,能够快速且正确地将遮挡和部分可见的物体形状注册起来,并不是不切实际的愿望。

在这个时候,一个简单的选择就是使用众所周知的迭代最近点(ICP)算法。然而,基本ICP的使用会导致收敛速度慢、注册不良、对异常值敏感和无法注册部分形状。因此,它绝对不适合这个问题。因此,已经提出了许多变种。不同的变种对姿态估计过程的不同阶段做出了贡献。

ICP由6个阶段组成,我为每一个阶段提出的改进总结如下。

采样

为了提高收敛速度和计算时间,通常使用比模型实际具有的更少的点。然而,提取正确的点进行配准本身就是一个问题。直观的方法是均匀采样并希望得到一个合理的子集。更聪明的做法是尝试识别关键点,这些点被发现对配准过程有很大贡献。Gelfand等人利用协方差矩阵来限制特征空间,从而使用影响平移和旋转的点集。这是一种巧妙的子采样方法,我将在实现中可选使用。

对应点搜索

正如其名所示,这一步实际上是按最近点方式分配数据中的点和模型中的点。正确的分配将导致正确的姿态,错误的分配会严重影响结果。通常,在搜索最近邻时使用KD树来提高速度。然而,这不是一个最优保证,很多时候会导致错误的点被匹配。幸运的是,分配将在迭代过程中得到纠正。

为了克服一些局限性,Picky ICP(ICP [321])和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}}\))。

拒绝对配

拒绝是通过根据标准差的稳健估计的动态阈值进行的。换句话说,在每次迭代中,我找到Std. Dev.的MAD估计。我将这个表示为\(mad_i\)。我拒绝距离\(d_i>\tau mad_i\)的配对。这里的\(\tau\)是拒绝的阈值,默认设置为3。在上一阶段解释的Picky细化之前应用加权。

错误度量

如第[]所述,使用点到平面的线性化作为错误度量,如[172]中所述,这既加快了配准过程,又提高了收敛。

最小化

尽管提出了许多非线性优化器(如Levenberg Mardquardt),但由于上一步的线性化,姿态估计降低为解线性方程组。这正是我使用DECOMP_SVD选项的cv::solve做的。

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
// 这将为结果中包含的每个姿态执行注册
// 结果
icp.registerModelToScene(pc, pcTest, results);
// 结果现在包含了精炼的位姿

结果

本节致力于表面匹配(点对特征匹配及其随后的ICP精炼)的结果

使用ppf + icp对单个青蛙模型进行匹配

下面是Mian数据集中不同模型的匹配

Mian数据集中不同模型的匹配

您可以在YouTube这里查看视频。

完整示例

参数调整

曲面匹配模块始终将其参数相对于模型直径(平行于轴的轴外接矩形的直径)进行处理。这使得这些参数与模型大小无关。这就是为什么模型和场景云都进行了下采样,使得所有点的最小距离为 \(RelativeSamplingStep*DimensionRange\),其中 \(DimensionRange\) 是沿给定维度的距离。三个维度以相似的方式采样。例如,如果 \(RelativeSamplingStep\) 设置为0.05,模型直径为1米(1000毫米),则从对象表面采样的点将大约相隔50毫米。从另一个角度来看,如果采样 \(RelativeSamplingStep\) 设置为0.05,则最多可以生成 \(20x20x20 = 8000\) 个模型点(取决于模型如何填充体积)。因此,这将最多产生8000x8000对。实际上,由于模型不是在矩形棱柱上均匀分布的,预期点数要少得多。减小此值,结果将导致更多模型点,从而更准确地表示。然而,请注意,要计算的点对特征的数量现在按二次方速率增加,复杂度是O(N^2)。这对于32位系统来说尤其是一个问题,大模型很容易超过可用内存。通常,大多数应用中0.025 - 0.05范围内的值似乎是足够的,其中默认值为0.03。(注意,此参数与在[72]中显示的参数不同。在[72]中使用了均匀的立方体进行量化,并使用模型直径作为采样的参考。在我的实现中,立方体是矩形棱柱,每个维度独立量化。我不参考直径,而是沿着各个单独的维度。

从模型中删除异常值以预先准备一个理想的模型是非常明智的。这是因为,异常值会直接影响相对计算并降低匹配精度。

在运行时阶段,场景再次按上述方式由 \(RelativeSamplingStep\) 进行采样。然而,这次仅使用场景点的一部分作为参考。这部分由参数 \(RelativeSceneSampleStep\) 控制,其中 \(SceneSampleStep = (int)(1.0/RelativeSceneSampleStep)\)。换句话说,如果 \(RelativeSceneSampleStep = 1.0/5.0\),则下采样场景将再次按1/5的比例均匀采样到点数。此参数的最大值为1,增加此参数会增加稳定性,但会降低速度。再次强调,由于初始场景独立的相对采样,调整此参数并不是一个大问题。这只会成为问题时模型形状均匀占用体积或当模型形状在量化体积中集中在某个小地方时(例如,八叉树表示会有很多空单元格)。

\(RelativeDistanceStep\) 在哈希表中具有离散化步长的作用。点对特征被量化以映射到哈希表的桶中。这种离散化包括乘法和整型转换。理论上调整 \(RelativeDistanceStep\) 可以控制冲突率。请注意,哈希表上的冲突越多,估计的准确性越低。减小此参数会增加量化的影响,但开始将非相似点对分配到相同的桶中。增加它则会减弱将相似点对分组的能力。一般来说,因为在采样阶段,训练模型点是按距离控制的均匀选择的,由 \(RelativeSamplingStep\) 控制,所以期望 \(RelativeDistanceStep\) 等于此值。然而,这一次,当模型密集时,不建议减小此值。对于有噪声的场景,可以增加值以提高匹配的鲁棒性。

结构体  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](http://www.mathworks.com/matlabcentral/fileexchange/47152-icp-registration-using-efficient-variants-and-multi-resolution-scheme)。主要贡献来自:[更多...](../../dc/d9b/classcv_1_1ppf__match__3d_1_1ICP.html#details)
 
类  cv::ppf_match_3d::Pose3D
 允许存储姿态的类。该数据结构同时存储了四元数和矩阵形式。它支持 IO 功能以及各种辅助方法来处理姿态。更多...
 
类  cv::ppf_match_3d::PoseCluster3D
 当多个姿态(参见 Pose3D)组合在一起(参与相同的变换)时,就会发生姿态簇。此类是此类组的通用容器。可以存储、加载数据和对这些姿态进行 IO 操作。更多...
 
类  cv::ppf_match_3d::PPF3DDetector
 允许加载和匹配 3D 模型的类。典型用例:[更多...](../../db/d25/classcv_1_1ppf__match__3d_1_1PPF3DDetector.html#details)
 
结构体  THash
 结构体,用于存储散列表中的节点。更多...
 

类型别名

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)
 Compute the normals of an arbitrary point cloud computeNormalsPC3d uses a plane fitting approach to smoothly compute local normals. Normals are obtained through the eigenvector of the covariance matrix, corresponding to the smallest eigen value. If PCNormals is provided to be an Nx6 matrix, then no new allocation is made, instead the existing memory is overwritten.
 
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 文件,以可见红色点表示法向量的顶部。
 

类型定义文档

◆ KeyType

◆ Pose3DPtr

◆ PoseCluster3DPtr

函数文档

◆ 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>

Compute the normals of an arbitrary point cloud computeNormalsPC3d uses a plane fitting approach to smoothly compute local normals. Normals are obtained through the eigenvector of the covariance matrix, corresponding to the smallest eigen value. If PCNormals is provided to be an Nx6 matrix, then no new allocation is made, instead the existing memory is overwritten.

参数
[in]PC用于计算法线的三维点云。
[输出]PCNormals输出点云
[in]NumNeighbors在局部区域内考虑的邻居数量
[in]FlipViewpoint是否应将法线翻转到一个视图方向?
[in]视图点
返回
返回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姿态矩阵

参数
[输出]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(*)(uint hashfunc 
)

◆ 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  )
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模型文件