Konvertieren Sie PCL-Punktwolkendaten in Eigen::Map
Anforderungen : Verstehen Sie die Funktionsparameter von getMatrixXfMap() und die damit verbundene Verwendung, die verwendet werden können, wenn das Punktwolkenprogramm eine CUDA-Übertragung durchführt.
Referenz :
PCL-Punktwolke und Eigen::Map-Konvertierung
1. Funktionsbeschreibung:
1.1 Beschreibung der Vorteile
Das Punktwolken-Datenpunktformat wird zur Berechnung in ein Matrixformat konvertiert. Wenn der Wert direkt zugewiesen wird, wird der Speicherplatz erneut geöffnet, was für große Datenpunktwolken nicht realistisch ist.
Verwenden Sie also Eigen::Map für die Speicherzuordnung 节省内存空间,加快处理速度
.
1.2 Funktionsprototyp
// pcl/point_cloud.h文件中
inline Eigen::Map<Eigen::MatrixXf, Eigen::Aligned, Eigen::OuterStride<> >
getMatrixXfMap (int dim, int stride, int offset)
Hinweis :
Ab pcl1.4.0 muss die Eigenmatrix zeilenmajor sein, um die Effizienz des Algorithmus in PCL zu verbessern.
Im Originaltext: Durch korrekte Zuordnung der PointCloud-Struktur zu Eigen::Map im Verhältnis 1:1, d. h.: 点云中的点数 = 矩阵中的行数,点维度 = 矩阵中的列数
.
Die in dieser Arbeit gewonnenen Schlussfolgerungen widersprechen denen des Originaltextes, 点云中的点数 = 矩阵中的列,点维度 = 矩阵中的行数
, wie getMatrixXfMap(4,4,0) kann xyzi-Punktwolkendaten in eine 4*size
Punktwolkenmatrix von konvertieren.
1.3 Parameterbeschreibung
- Parameter 1:
dim
Die Dimension, die jeder Punkt berücksichtigen muss - Parameter 2:
stride
, die Anzahl der in jedem Punkt enthaltenen Werte - Parameter 3:
offset
Die Anzahl der Sprünge ab der Startposition jedes Punkts
1.4 Konkrete Beispiele
- Erstellen Sie eine neue Punktwolke, und die x-, y-, z- und i-Werte der Punktwolke werden entsprechend dem Indexwert zugewiesen, was zum Drucken und Anzeigen praktisch ist.
pcl::PointCloud<pcl::PointXYZI>::Ptr cloud_test(new pcl::PointCloud<pcl::PointXYZI>);
for (int i = 0; i < 10; i++) {
pcl::PointXYZI p;
p.x = i;
p.y = i;
p.z = i;
p.intensity = i;
cloud_test->points.push_back(p);
}
2) Verwenden Sie die Konvertierungsfunktion, um die xyz-Koordinatenwerte zu extrahieren
auto pc_matrix = cloud_test->getMatrixXfMap(3,8,0);
Erläuterung: Warum (3,8,0)?
Da jeder Punkt drei Dimensionen von xyz annimmt, nimmt das erste Dim also 3 an. Der dritte Offsetwert beginnt beim ersten x, daher ist der dritte Parameteroffset = 0.
Warum nimmt der zweite Wert 8 an?
Am Anfang kann es Zweifel geben, da jeder Punkt xyzi ist, der 4 Gleitkommazahlen enthält, die 4 sein sollten. Wenn wir uns jedoch die Organisationsform der Struktur pcl::PointXYZI wie folgt ansehen, finden wir diese Daten [3] ist kein Intensitätswert, stattdessen wird 1,0f zugewiesen.
Schauen Sie sich außerdem EIGEN_ALIGN16 an und stellen Sie fest, dass eine 16-Byte-Ausrichtung verwendet wird und eine Gleitkommazahl float 4 Bytes belegt. Das heißt, diese 8 Gleitkommazahlen sind jeweils x,y,z,data[3]=1.0f, data[4]=intensity,data[5] ,data[6] ,data[7]
. (wobei data[5], data[6], data[7] nicht zugewiesen sind)
// PointXYZI结构体
struct PointXYZI : public _PointXYZI
{
inline PointXYZI (const _PointXYZI &p)
{
x = p.x; y = p.y; z = p.z; data[3] = 1.0f;
intensity = p.intensity;
}
}
// EIGEN_ALIGN16 16字节对齐
struct EIGEN_ALIGN16 _PointXYZI
{
PCL_ADD_POINT4D; // This adds the members x,y,z which can also be accessed using the point (which is float[4])
union
{
struct
{
float intensity;
};
float data_c[4];
};
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
- Extrahieren Sie die Intensitätsmatrix mithilfe der Konvertierungsfunktion
auto trans_cloudi = cloud_test->getMatrixXfMap(1,8,4);
4) Drucken Sie die Werte von pc_matrix und trans_cloudi aus, um eine 4*10-Matrix zu erhalten.
Ergebnisse:
Sie können die Matrixdimensionen auch über Attribute anzeigen, wie folgt:
auto col = pc_matrix.row(0).size(); // 10
auto row = pc_matrix.col(0).size(); // 3
auto intensity_col = trans_cloudi.row(0).size(); // 10