開発中のOpenCV 3.0でPerfumeの3Dデータを表示する
OpenCV 3.0.0-dev Vizモジュール
OpenCV 3.0の開発ブランチを見ていたら,Vizという3D表示用のモジュールがあったので使ってみる.
3D表示には,Point Cloud Libraryとかでも使われているVTKというオープンソースのライブラリが使われている.
環境
Windows 7
Visual Studio Professinal 2012
OpenCV ハッシュ値:59cab94fc7a43ad3a39414232fd34d23815b8547
VTKのバージョン:5.10.1(6.0.0だとうまく出来なかった.出来た人教えてください)
Perfumeの3Dデータ表示
Perfume official global websiteで公開されている,Perfumeの3次元スキャンデータを表示するプログラムを作った.ファイルフォーマットはOBJファイルのものを選択.
#include <opencv2/viz.hpp> #include <opencv2/viz/widget_accessor.hpp> #include <vtkPolyDataMapper.h> #include <vtkActor.h> #include <vtkOBJReader.h> using namespace cv; using namespace std; // Objファイルから3Dデータを読み込み可能なウィジェット class WObj : public viz::Widget3D { public: WObj(const string& filename) { // OBJファイルを読み込むクラスの生成 vtkSmartPointer<vtkOBJReader> reader = vtkSmartPointer<vtkOBJReader>::New(); reader->SetFileName(filename.c_str()); reader->Update(); // mapperにOBJファイルからデータを取り込む vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New(); mapper->SetInputConnection(reader->GetOutputPort()); // actorの設定 vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New(); actor->SetMapper(mapper); // ウィジェットにactorをセットする viz::WidgetAccessor::setProp(*this, actor); } }; int main() { // 表示用ウィンドウの生成 viz::Viz3d perfumeWindow("Creating Widgets"); // Perfumeのウィジェットを生成 string filename1 = "Perfume_Global_Site_Project_003\\model1.obj"; string filename2 = "Perfume_Global_Site_Project_003\\model2.obj"; string filename3 = "Perfume_Global_Site_Project_003\\model3.obj"; WObj objAchan(filename1), objNocchi(filename2), objKashiyuka(filename3); // Perfumeのウィジェットをウィンドウに表示 perfumeWindow.showWidget("Achan", objAchan); perfumeWindow.showWidget("Nocchi", objNocchi); perfumeWindow.showWidget("Kashiyuka", objKashiyuka); // 軸を表示 Affine3dcloud_pose = Affine3f().translate(Vec3f(-500.0f,-400.0f,-60.0f)); perfumeWindow.showWidget("Coordinate Widget", viz::WCoordinateSystem(200), cloud_pose); // 表示のスタート perfumeWindow.spin(); }
VTKの書き方をほぼそのまま使える.実行すると下の画像ような感じで,かしゆか,あーちゃん,のっちが表示される.
視点の移動
視点を移動したり,ウィジェットを移動・回転したりできるので,適当に視点移動をさせてみた.上のコードの「perfumeWindow.spin();」を以下のコードに置き換える.
float angle = 0.0; while(!perfumeWindow.wasStopped()) { angle += CV_PI * 0.01f; // カメラの姿勢を生成 Point3f cam_pos(100+2000*cos(angle),500,3000*sin(angle)); Point3f cam_focal_point(3.0f,3.0f,2.0f) Point3f cam_y_dir(0.0f,1.0f,0.0f); Affine3f cam_pose = viz::makeCameraPose(cam_pos, cam_focal_point, cam_y_dir); // 視点をセット perfumeWindow.setViewerPose(cam_pose); perfumeWindow.spinOnce(1, true); }
実行すると,下の動画のようにウィンドウ内の表示が動く.