前提・実現したいこと
点群の位置合わせを行うICPアルゴリズムを自分で実装しようと考えています。
二つの点群の対応する点の距離を求めたいのですが、なかなかうまくいきません。
なにかアドバイスをいただけると助かります。
発生している問題・エラーメッセージ
main内、while(doesConverged(... 内 weight.push_back(pow(..... の文 invalid use of ‘boost::detail::sp_array_access<pcl::PointCloud<pcl::PointXYZ> >::type {aka void}’
該当のソースコード
C++
1constexpr double PI = 3.14159265358979; 2constexpr double CONVERGE_THRESHOLD = 1.0; 3 4double degreeToRadian(double degree){ 5 return degree * (PI / 180); 6} 7 8float FindClosestPoint(pcl::PointCloud<pcl::PointXYZ>::Ptr source, pcl::KdTreeFLANN<pcl::PointXYZ> &targetTree,std::vector<int> &closestPoints){ 9 std::vector<float> distanceOfClosestPoints; 10 //sourceの各点からもっとも近い点を探すループ 11 for(auto p:*source){ 12 std::vector<int> tmp_i; 13 std::vector<float> tmp_f; 14 targetTree.nearestKSearch(p,1,tmp_i,tmp_f); 15 closestPoints.push_back(tmp_i[0]); 16 distanceOfClosestPoints.push_back(tmp_f[0]); 17 } 18 19 float sum=0; 20 for(float d:distanceOfClosestPoints){ 21 sum += d; 22 } 23 return sum; 24} 25 26bool doesConverged(pcl::PointCloud<pcl::PointXYZ>::Ptr source, pcl::PointCloud<pcl::PointXYZ> target, Eigen::Affine3d trans){ 27 pcl::PointCloud<pcl::PointXYZ> closest; 28 29 pcl::PointCloud<pcl::PointXYZ> transed; 30 pcl::transformPointCloud(*source,transed,trans); 31 float Sum_Distance = 0; 32 33 for(size_t i = 0;i = transed.size ();i++) 34 { 35 Sum_Distance += pow( (target[i].x - transed[i].x) * (target[i].x - transed[i].x) + (target[i].y - transed[i].y) * (target[i].y - transed[i].y) + (target[i].z - transed[i].z) * (target[i].z - transed[i].z), 0.5 ); 36 } 37 return Sum_Distance <= CONVERGE_THRESHOLD; 38} 39 40struct CostFunc 41{ 42 CostFunc(const pcl::PointNormal source, const pcl::PointNormal target, const bool w) 43 : source_(source), target_(target), w_(w) {} 44 45 template <typename T> 46 bool operator()(const T *const p, T *residual, const bool w) 47 { 48 T x = T(source_.x); 49 T y = T(source_.y); 50 T z = T(source_.z); 51 52 pcl::PointXYZ Tb; 53 Tb.x = p[0]*x+p[1]*y+p[2]*z+p[3]; 54 Tb.y = p[4]*x+p[5]*y+p[6]*z+p[7]; 55 Tb.z = p[8]*x+p[9]*y+p[10]*z+p[11]; 56 57 residual[0] = T(w?1:0)*T(sqrt(pow( (target_.x - Tb.x)*(target_.x - Tb.x) + (target_.y - Tb.y) * (target_.y - Tb.y) + (target_.z - Tb.z) * (target_.z - Tb.z), 0.5 ))); 58 return true; 59 } 60 61 private: 62 pcl::PointNormal source_; 63 pcl::PointNormal target_; 64 double w_; 65}; 66 67Eigen::Matrix3d minimizeTransform(pcl::PointCloud<pcl::PointXYZ>::Ptr source,pcl::PointCloud<pcl::PointXYZ>::Ptr target,std::vector<int> &closest,std::vector<bool> &weight){ 68 Eigen::Matrix3d matrix; 69 ceres::Problem problem; 70 std::vector<double> param(9, INITIAL_SURFACE_PARAMETER); 71 for (int i = 0; i < target->size(); ++i) 72 { 73 ceres::CostFunction *cost = 74 new ceres::AutoDiffCostFunction<CostFunc, 1, 9>(new CostFunc(source->at[i], target->at(closest[i]), weight[i])); 75 problem.AddResidualBlock(cost, NULL, param.data()); 76 } 77 //最適化のためのオプションを設定 78 ceres::Solver::Options options; 79 options.linear_solver_type = ceres::DENSE_QR; 80 options.minimizer_progress_to_stdout = PRINT_SOLVER_PROGRESS; 81 //最適化過程の情報保持用 82 ceres::Solver::Summary summary; 83 //最適化開始 84 ceres::Solve(options, &problem, &summary); 85 86 matrix << param[0],param[1],param[2], 87 param[3],param[4],param[5], 88 param[6],param[7],param[8]; 89 return matrix; 90 } 91 92int main(){ 93 const double Dmax = 0.1; 94 pcl::PointCloud<pcl::PointXYZ>::Ptr sourceCloud(new pcl::PointCloud<pcl::PointXYZ>); 95 pcl::PointCloud<pcl::PointXYZ>::Ptr targetCloud(new pcl::PointCloud<pcl::PointXYZ>); 96 Eigen::Affine3d affine; 97 98 //点群(PCD)の読み込み 99 pcl::io::loadPCDFile("raw_1.pcd", *sourceCloud); //ファイル名は仮 100 pcl::io::loadPCDFile("raw_2.pcd", *targetCloud); //ファイル名は仮 101 102 std::vector<int> closestPoints(sourceCloud->size()); 103 104 pcl::KdTreeFLANN<pcl::PointXYZ> tTree; 105 tTree.setInputCloud(targetCloud); 106 107 // アフィン行列の初期化 108 Eigen::Translation<double, 3> offset(0,0,0); 109 //offset = (0,0,0);// 平行移動量 110 Eigen::Quaternion<double> rot( 111 // 回転量 112 Eigen::AngleAxisd(degreeToRadian(0), Eigen::Vector3d::UnitX()) * 113 Eigen::AngleAxisd(degreeToRadian(0), Eigen::Vector3d::UnitY()) * 114 Eigen::AngleAxisd(degreeToRadian(0), Eigen::Vector3d::UnitZ())); 115 116 affine = offset * rot; 117 118 while(doesConverged(sourceCloud,*targetCloud,affine)){ 119 pcl::PointCloud<pcl::PointXYZ>::Ptr transedCloud; 120 pcl::transformPointCloud(*sourceCloud,*transedCloud,affine); 121 std::vector<bool> weight; 122 FindClosestPoint(transedCloud, tTree,closestPoints); 123 for(int i = 0; i <= transedCloud->size(); i++){ 124 weight.push_back(pow((targetCloud[closestPoints[i]].x - transedCloud[i].x) * (targetCloud[closestPoints[i]].x - transedCloud[i].x) + (targetCloud[closestPoints[i]].y - transedCloud[i].y) * (targetCloud[closestPoints[i]].y - transedCloud[i].y) + (targetCloud[closestPoints[i]].z - transedCloud[i].z) * (targetCloud[closestPoints[i]].z - transedCloud[i].z), 0.5 ) <= 0.1); 125 } 126 affine = minimizeTransform(sourceCloud,targetCloud, closestPoints, weight); 127 } 128} 129
試したこと
以前投稿した時に発生していたエラーは、関数の型を修正することで自己解決しました。
補足情報(FW/ツールのバージョンなど)
開発環境
ubuntu 16.04
visual studio code
C++
使用ツール
point cloud library
Ceres Solver
Eigen
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/09/30 02:09
2019/09/30 02:21 編集
2019/09/30 13:39