🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

2657閲覧

二つの点群の対応する点間の距離を求めたいです。

wakasagi

総合スコア7

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

1クリップ

投稿2019/09/21 14:21

編集2019/09/30 02:09

前提・実現したいこと

点群の位置合わせを行う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

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

該当行にtypoがありませんか? .x とすべき箇所が x になっているように見えます。

c++

1weight.push_back( 2 pow( 3 (targetCloud[closestPoints[i]].x - transedCloud[i].x) * (targetCloud[closestPoints[i]]x - transedCloud[i].x) + // ★ 4 (targetCloud[closestPoints[i]].y - transedCloud[i].y) * (targetCloud[closestPoints[i]].y - transedCloud[i].y) + 5 (targetCloud[closestPoints[i]].z - transedCloud[i].z) * (targetCloud[closestPoints[i]].z - transedCloud[i].z) 6 , 0.5 ) 7 <= 0.1 8 );

コーディングの話になりますが、1行に情報を詰め込み過ぎですね。途中計算式を一時変数にいれるか、せめて改行を入れたほうが良いと思います。

投稿2019/09/30 01:47

yohhoy

総合スコア6191

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

wakasagi

2019/09/30 02:09

回答ありがとうございます。コーディングについてのアドバイスもありがとう御座います。たしかに詰め込み過ぎで見難いです。参考にさせていただきます。 すいません書き損じでした。実際のコードでは .x となっていました。ご指摘ありがとうございます。
yohhoy

2019/09/30 02:21 編集

1行に詰め込んでいる計算式をバラすことで、エラーメッセージ「invalid use of ‘~’」がどのタイミングで出ているかも追いやすくなるかと思います。 ついでに、質問文のエラーメッセージも過度に省略しない方がよいですね。情報が欠落しているように思えます。
wakasagi

2019/09/30 13:39

ありがとうございます。おかげさまで該当のエラーを修復できました。 今後は積極的に改行していこうと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問