pcl::PointCloudやEigenを含むvectorをresizeするとエラーが発生する場合の対処
C++行列演算ライブラリ「Eigen」を含む構造体などのstd::vectorは、下記のページで説明されているような工夫が必要となる。
Eigen: Using STL Containers with Eigen
例えばこんなコードが書ける。
#include <vector> #include <Eigen/Core> #include <Eigen/StdVector> struct Hoge { Eigen::Vector4f v; EIGEN_MAKE_ALIGNED_OPERATOR_NEW }; void main() { std::vector<Hoge, Eigen::aligned_allocator<Eigen::Vector4f>> hoges; hoges.resize(4); }
だが、Visual Studio 2010またはそれ以前のバージョンのIDEを使用していると、上記コードではvectorのresizeをすると、コンパイル時に次のようなエラーが発生する。
3>c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\vector(870): error C2719: '_Val': __declspec(align('16')) の仮引数は配置されません。
そのような場合の対処方法。PCLの Users mailing list ではVSのC++のvectorインクルードファイルを次のように修正すればよいと書かれていた。
I solved this issue by changing the signature of resize() funtion from Microsoft Visual Studio 10.0/VC/include/vector like this:
from:
void resize(size_type _Newsize, _Ty _Val)to:
void resize(size_type _Newsize, _Ty &_Val)Hope this helps!
http://www.pcl-users.org/point-cloud-h-alignment-issue-td4021525.html
ただ、個人的には編集可能な状態で渡すのは気持ち悪いので下記のように変更した。これでもちゃんと動作する。
void resize(size_type _Newsize, const _Ty &_Val)
ちなみに Visual Studio 2013 のvectorファイルを見てみたが下記のように書かれていたので、上記の問題は起こらないと思う。
void resize(size_type _Newsize, const value_type& _Val)
VeloViewで出力した点群データ(CSV)をPCLで読み込む
Velodyne社のLIDAR「HDL-32e」や「HDL-64e」用のViewerにVeloViewというものがあります。VeloViewでは点群データをCSV形式でエクスポートできます。そのCSVデータをpcl::PointCloudとして読み込むコードのメモ。
CSVデータの1行目は、カラム名が出力されていて下記のようになっています。
- Points:0
- Points:1
- Points:2
- intensity
- laser_id
- azimuth
- distance_m
- timestamp
今回のコードはpcl::PointXYZIの形式で、intensityにはレーザの反射強度が入ります。
#include <fstream> #include <pcl/pcl_base.h> #include <pcl/point_cloud.h> int loadPointCloudFromCSV(const std::string &file_path, pcl::PointCloud<pcl::PointXYZI> &cloud) { std::ifstream ifs(file_path, std::ios::in); if(!ifs) return 1; // File open failed std::string buf; std::getline(ifs, buf); // Skip first line ("Points:0","Points:1","Points:2","intensity","laser_id","azimuth","distance_m","timestamp") while(ifs && std::getline(ifs, buf)) { std::vector<std::string> v; boost::algorithm::split(v, buf, boost::is_any_of(",")); if(v.size() < 4) continue; pcl::PointXYZI p; p.x = std::atof(v[0].c_str()); p.y = std::atof(v[1].c_str()); p.z = std::atof(v[2].c_str()); p.intensity = std::atof(v[3].c_str()); cloud.push_back(p); } return 0; }
PCLVisualizerでポイントクラウドの透明度を反映させて描画する方法
pcl::PointXYZRGBAというタイプのポイントクラウドを作り、アルファ値(a)を0にしてもPCLVisualizerで透明にならないなぁと思っていたのですが、カラーハンドラーを設定すればちゃんと透明度に合わせて描画されることに気づきました。
以下、サンプル
#include <pcl/point_types.h> #include <pcl/point_cloud.h> #include <pcl/visualization/pcl_visualizer.h> int main(int argc, char** argv) { pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZRGBA>); // 適当なポイントクラウドを作成 cloud->width = 256; cloud->height = 128; cloud->points.resize (cloud->width * cloud->height); for(int i = 0, y = 0; y < cloud->height; y++) { for(int x = 0; x < cloud->width; x++, i++) { pcl::PointXYZRGBA &p = cloud->points[i]; p.x = x; p.y = y; p.z = 0.0; p.r = 255; p.g = static_cast<float>(y) / cloud->height * 255; p.b = 0; p.a = static_cast<float>(x) / cloud->width * 255; } } // 表示 int vp[2]; pcl::visualization::PCLVisualizer viewer("Viewer"); pcl::visualization::PointCloudColorHandlerRGBAField<pcl::PointXYZRGBA> rgba(cloud); viewer.createViewPort(0.0, 0.0, 0.5, 1.0, vp[0]); viewer.createViewPort(0.5, 0.0, 1.0, 1.0, vp[1]); viewer.addPointCloud(cloud, "cloud_without_color_handler", vp[0]); // 透明度が反映されない viewer.addPointCloud(cloud, rgba, "cloud_with_color_handler", vp[1]); // 透明度が反映される viewer.addText("Without color handler", 10, 10, "text_without_color_handler", vp[0]); viewer.addText("With color handler", 10, 10, "text_with_color_handler", vp[1]); viewer.spin(); return 0; }
実行したときの画像がこちら
【PCL入門】 Point Cloud Library のインストール
今回はPCLを使えるようにするまでを紹介します。
続きを読むWindows 8 で HSP3 アプリを終了時にランタイムエラーが発生する場合の対処
昔 Windows Vista / 7 向けに作ったHSP3製アプリケーションを Windows 8 で動かすと、終了時に "Microsoft Visual C++ Runtime Library Runtime Error" が出る場合があることに気づきました。
同じ症状で困っている人もいるみたい。
なお私の場合は、onexitで別ラベルへ飛ばした後、endを実行するところでランタイムエラーが起こってしまうので原因が不明でした。
と、ここで下記情報を発見:
oncmdで飛んだ先のラベルの中だと普通のエラーがランタイムエラーになってしまうそうです。
この情報を元に下記のコードを試しに実行してみたところ、onexitでも同じようにランタイムエラーが起こることがわかりました。
onexit goto *quit *main wait 10 goto *main *quit mes "quit" error = 1 / 0 // 本来は「Error 19 : 0で除算しました」になる end
ということで、解決策として下記のようにコードを改造しました。
onexit gosub *quit quitFlag = 0 *main if quitFlag : goto *terminate wait 10 goto *main *quit quitFlag = 1 return *terminate mes "quit" error = 1 / 0 // 「Error 19 : 0で除算しました」 end
変更点は次の通り:
- onexitで飛んだ先のラベル内では終了するというフラグだけを立てる
- mainループの中で、常にフラグをチェック
- フラグを元にonexit外のラベルから終了処理ラベルにジャンプ
かっこ悪いですが、これならちゃんと Error 19 になります。
ちなみに、先に述べた拙作アプリにこの改造を行ったところ、endで何のエラーも起こらず終了してくれるようになりました。
とりあえず Windows 8 でランタイムエラーが出るようになったら、まずはこんな風に改造してみるのがいいかもしれません。
VS2013 で FLANN 1.8.4 をビルド
VS2013 での FLANN 1.8.4 のビルドのメモ。
あるヘッダファイルを修正しないとうまくビルドできなかった。
環境
- Windows 7 Professional x64
- Microsoft Visual Studio Premium 2013
エラー内容
error C2228: '.serialize' : 左側がクラス、構造体、共用体ではありません。
修正箇所
- 上記のサイトを参考に、serialization.h内の92行目あたりに3行追加
// declare serializers for simple types BASIC_TYPE_SERIALIZER(char); BASIC_TYPE_SERIALIZER(unsigned char); BASIC_TYPE_SERIALIZER(short); BASIC_TYPE_SERIALIZER(unsigned short); BASIC_TYPE_SERIALIZER(int); BASIC_TYPE_SERIALIZER(unsigned int); BASIC_TYPE_SERIALIZER(long); BASIC_TYPE_SERIALIZER(unsigned long); BASIC_TYPE_SERIALIZER(float); BASIC_TYPE_SERIALIZER(double); BASIC_TYPE_SERIALIZER(bool); #ifdef _MSC_VER // 追加 BASIC_TYPE_SERIALIZER(unsigned __int64); // 追加 #endif // 追加
最終的なビルド手順
- FLANNのソースコードをダウンロード・解凍。今回はC:\FLANN下に解凍した。
- src/cpp/flann/util/serialization.hを上述の通り修正
- cmake して Visual Studio で開けるソリューションファイルを作成
- スタートメニューからCMake (cmake-gui) を起動
- 必要事項を入力して "Configure" を押す
- "Where is the source code:" に "C:\FLANN"
- "Where to build the binaries:" に "C:\FLANN\build" (どこでもいい)
- 何か設定が必要であればする
- 今回は特に何もしない
- "Generate" を押す
- C:\FLANN\build に作成された flann.sln を管理者権限で開く
- 下記のINSTALLで、ビルドしたファイルをProgram Files下にコピーするのに管理者権限が必要
- INSTALLしなくていいなら flann.sln は普通に開いてよい
- 先に Visual Studio 2013 を管理者権限で開いてから flann.sln を開くとよい
- 下記のINSTALLで、ビルドしたファイルをProgram Files下にコピーするのに管理者権限が必要
- メニュー「ビルド」→「バッチビルド」をクリック
- 次の4つにチェックを入れて「ビルド」を押す
- ALL_BUILD (Debug)
- ALL_BUILD (Release)
- INSTALL (Debug)
- INSTALL (Release)