ICP变换矩阵平移和旋转

时间:2018-07-31 23:30:27

标签: c++ math matrix point-cloud-library point-clouds

我有一辆带有不错的IMU和声纳的车辆。我正在使用点云库线性ICP对声纳点云进行精细配准。我想将ICP转换的结果与IMU数据进行比较,但是我不了解如何从最终的同类4x4转换矩阵中提取转换。

类似的questionother sources我发现所有人都说翻译只是表格中的第4列。

我遇到的问题是我无法获得用于转换的值,似乎旋转分量越大,获得的值越荒谬,这导致我无法简单地提取最后一列。滚动,俯仰和偏航值在合理范围内并具有一定的道理,但在任何方向上的偏移都不能超过1米。矩阵在应用时确实按预期运行,因此我知道矩阵是正确的,只是我不理解如何解释或提取x,y,z线性平移。

测量原始云的质心和最终云的质心之间的距离会得出更加合理的结果,但是我不知道这是否可以接受。似乎有点骇人听闻。

代码:

myCloud::Ptr      target, source, output;  // PCL clouds
myPoint           cInit, cRough, cFinal;   // centroid points
Eigen::Matrix4f   estimation, icpResult, finalTransform;   // transforms

// load vectors of sonar data into point clouds
target = pointVector_to_pointCloud(verbose, tgtPoints);
source = pointVector_to_pointCloud(verbose, srcPoints);

pcl::computeCentroid(*source, cInit);

// x, y, z offsets come from a previous rough alignment
Eigen::Affine3f fromIMU(Eigen::Translation3f(x, y, z));
estimation = fromIMU.matrix();
pcl::transformPointCloud(*cloud, *cloud, estimation);

pcl::computeCentroid(*source, cRough);

// create new empty cloud in the output pointer, set up ICP
output.reset(new myCloud);
icp.setInputSource(source);
icp.setInputTarget(target);

/**** Set ICP parameters, omitted ****/

icp.align(*output);
icpResult = icp.getFinalTransformation();
finalTransform = estimation * icpResult;

pcl::computeCentroid(*source, cFinal);

// Output Results
Eigen::Affine3f roughT(estimation);
Eigen::Affine3f fineT(icpResult);
float tx, ty, tz, rx, ry, rz;
pcl::getTranslationAndEulerAngles(roughT, tx, ty, tz, rx, ry, rz);
std::cerr << "********* ICP RESULTS **********\n";
std::cerr << "Rough Transform Matrix:\n" << transform << endl;
std::cerr << "Translation (x, y, z)       : " << tx << ", " << ty << ", " << tz << endl;
std::cerr << "Rotation (roll, pitch, yaw) : " << rx << ", " << ry << ", " << rz << endl;

pcl::getTranslationAndEulerAngles(fineT, tx, ty, tz, rx, ry, rz);
std::cerr << "\nFine Transform Matrix:\n" << icpResult << endl;
std::cerr << "Translation (x, y, z)       : " << tx << ", " << ty << ", " << tz << endl;
std::cerr << "Rotation (roll, pitch, yaw) : " << rx << ", " << ry << ", " << rz << endl << endl;

std::cerr << "\nFinal Transformation Matrix:\n" << finalTransform << endl;

std::cerr << "\n\tCentroid after Rough Alignment: " << cRough << " ... Distance From Start: " << pcl::geometry::distance(cInit, cRough) << endl;
std::cerr << "\tCentroid after ICP: " << cFinal << " ... Distance From Start: " << pcl::geometry::distance(cInit, cFinal) << endl;

输出(对于一个示例数据集):

********* INSIDE ICP TRANSFORM STATS **********
Rough Transform Matrix:
        1         0         0  0.612095
        0         1         0 -0.211855
        0         0         1         0
        0         0         0         1
Translation (x, y, z)       : 0.612095, -0.211855, 0
Rotation (roll, pitch, yaw) : 0, -0, 0

Fine Transform Matrix:
   0.999992 -0.00257317  0.00361636     2.92558
 0.00256172    0.999995  0.00328003     2.66182
-0.00362478 -0.00327113    0.999988   0.0578782
          0           0           0           1
Translation (x, y, z)       : 2.92558, 2.66182, 0.0578782
Rotation (roll, pitch, yaw) : -0.00327116, 0.00362479, 0.00256174

Final Transformation Matrix: 
   0.999992 -0.00257317  0.00361636     3.53767
 0.00256172    0.999995  0.00328003     2.44996
-0.00362478 -0.00327113    0.999988   0.0578782
          0           0           0           1

Centroid after Rough Alignment: (8.8218,9.12704,-807.301 - 0,126,255) ... Distance From Start: 0.647709
Centroid after ICP: (8.8068,9.1658,-807.3 - 0,126,255) ... Distance From Start: 0.621667

1 个答案:

答案 0 :(得分:0)

此问题的答案与数据来源有关。测深数据以正数表示,即一个点以上的海水米。但是收集数据的车辆正在海平面上方飞行10-30米。

要正确转换数据,请执行以下操作:

  • 转换为车辆参考系
  • 执行ICP并获取矩阵
  • 如果需要,将数据转换回测深仪框架

这可能需要附加的车辆数据来知道如何转换为车架,例如传感器位置和车辆本身的偏移量。

转换为车辆参考系,