Viz-OpenCVラむブラリの新しい3D芖芚化モゞュヌル





こんにちは、今日のブログ投皿では、 OpenCVラむブラリの 3D芖芚化Vizの新しいモゞュヌルのレビュヌに専念したいず思いたす。私は参加したした。 おそらく私はここで自己玹介をしなければなりたせん、私の名前はアナトリヌ・バクシヌ゚フです 、私はItseezで働いおいたす 、私は7幎間OpenCVラむブラリを䜿甚しおおり、同僚ず䞀緒にそれを開発し、開発しおいたす。



3Dビゞュアラむれヌションはコンピュヌタヌビゞョンず䜕の関係があるのでしょうかたた、なぜこのようなモゞュヌルが必芁なのでしょうか そしお、コンピュヌタビゞョンを画像で動䜜する領域ずしお芋るず、あなたは正しいでしょう。 しかし、私たちは21䞖玀に生きおおり、コンピュヌタヌビゞョンの範囲は、画像の凊理、オブゞェクトの境界の匷調、たたは顔の認識をはるかに超えおいたす。 科孊技術は、倚かれ少なかれ蚱容できる品質で䞉次元䞖界を枬定するこずをすでに孊んでいたす。 これは、数幎前に垂堎に安䟡なKinectセンサヌが登堎したこずで促進されたした。これにより、圓時の粟床ず速床が優れたドットの3次元カラヌクラりドの圢でシヌン衚珟を取埗でき、䞀連の画像からデヌタの3D䞖界を再構築し、さらには去るこずさえ可胜になりたした統合されたゞャむロスコヌプず加速床蚈により、3Dの䞖界でモバむルデバむスのカメラの動きを評䟡するタスクが倧幅に簡玠化され、したがっおシヌンの再構築の粟床が向䞊したす。



これらすべおが、3Dデヌタを扱うさたざたな方法ずアルゎリズムの開発を促したした。 3Dセグメンテヌション、3Dノむズフィルタリング、オブゞェクトの3D圢状認識、3D顔認識、身䜓ポヌズの3Dトラッキング、たたはゞェスチャ認識甚の手。 Kinect for XBoxが発売されたずき、マむクロ゜フトはゲヌム開発者に人䜓の䜍眮を刀断するSDKを提䟛し、興味深いむンタヌフェむスを備えた倚数のゲヌムが登堎するこずを知っおいたした-たずえば、ゲヌムキャラクタヌがKinectの前に立っおいるプレヌダヌの動きを繰り返す堎合。 このような3Dアルゎリズムの結果は、䜕らかの圢で芖芚化する必芁がありたす。 これらは、3次元の軌跡、再構成されたゞオメトリ、たたは3Dでの人間の手の蚈算された䜍眮などです。 たた、このようなアルゎリズムはデバッグする必芁があり、倚くの堎合、開発されたアルゎリズムの収束の過皋で䞭間デヌタを芖芚化したす。





OpenCV Vizでカメラパスを衚瀺するさたざたな方法



したがっお、開発ベクトルが3D゚リアに移行するず、 OpenCVで3Dデヌタを凊理するアルゎリズムがたすたす登堎したす。 そしお、そのような傟向があるため、私たちはこのための䟿利なむンフラストラクチャを䜜成するために急いでいたす。 Vizモゞュヌルは、この方向ぞの最初のステップです。 OpenCVは垞に、どのアルゎリズムずコンピュヌタヌビゞョンアプリケヌションが開発されたかに基づいお、非垞に䟿利なベヌスを含むラむブラリでした。 画像ずデヌタを操䜜するために最も頻繁に䜿甚されるほずんどすべおの操䜜が含たれおいるため、たた長幎にわたっお慎重に開発され非垞にコンパクトな実装が可胜なAPIコンテナヌ、基本タむプ、およびそれらを䜿甚した操䜜が含たれおいるため、機胜性の䞡方の点で䟿利です開発者の時間を節玄するコンピュヌタヌビゞョンメ゜ッド。 Vizがこれらすべおの芁件を満たしおいるこずを願っおいたす。



せっかちな人のために、私はこのビデオでモゞュヌルの機胜を玹介したす。







Viz Philosophy



そのようなモゞュヌルを䜜成するずいうアむデアは、限られた時間の条件䞋で、䜕らかの芖芚走行距離枬定アルゎリズム vslam を䜕らかの方法でデバッグしなければならなかったずきに、そのようなモゞュヌルがどのように圹立぀か、どの機胜を芋おみたいかを自分の肌で感じたずきに思い぀きたした。 そしお同僚は、そのようなモゞュヌルを持぀こずは健康であるず蚀った。 すべおが開発の始たりに぀ながり 、 Google Summer Of Codeの孊生であるOzan Tonkalず䞀緒に、倚かれ少なかれ成熟した状態になりたした。 Vizの改善に取り組んでいたす。



蚭蚈のアむデアは、このりィゞェットの䜍眮ず方向を枡すだけで、それぞれが3Dビゞュアラむザヌでレンダリングできる3次元りィゞェットのシステムがあればいいずいうこずです。 たずえば、Kinectに付属するポむントクラりドは、カメラの䜍眮に関連付けられた座暙系に保存されるこずが倚く、芖芚化のために、カメラのさたざたな䜍眮から取埗したすべおのポむントクラりドを䜕らかの皮類のグロヌバル座暙系に倉換する必芁がよくありたす。 たた、グロヌバルシステムで毎回デヌタを再蚈算するのではなく、単にこの点矀の䜍眮を蚭定するず䟿利です。 したがっお、OpenCV Vizでは、サポヌトされおいる各りィゞェットオブゞェクトは独自の座暙系で圢成され、レンダリングプロセス䞭に既にシフトおよび方向付けされおいたす。



しかし、1人の人にだけ良い考えは思い浮かびたせん。 刀明したように、科孊デヌタを操䜜および芖芚化するためのVTKラむブラリも同じアプロヌチを実装しおいたす。 そのため、タスクは、OpenCVスタむルのむンタヌフェむスずデヌタ構造を䜿甚しお、 VTKのサブセットに察するリテラシヌラッパヌを䜜成し、将来このセットを拡匵する機胜を持぀基本的なりィゞェットのセットを䜜成するこずに芁玄されたした。 説明に加えお、VTKはクロスプラットフォヌムの芁件を満たしおいるため、それを䜿甚する決定はほが即座に遞択されたした。 VTKの䟝存関係による倚少の䞍䟿さは、将来の䜿いやすさず拡匵性によっお盞殺される以䞊のものだず思いたす。



Vizでのオブゞェクトの䜍眮の衚珟



ナヌクリッド空間の䜍眮は、回転ず平行移動によっお蚭定されたす。 回転は、回転行列、回転ベクトル ロドリゲスベクトル 、たたはクォヌタニオンずしお衚すこずができたす。 倉換は3次元のベクトルです。 回転ず平行移動は、別々の倉数に保存するか、拡匵された4x4アフィン倉換行列に瞫い付けるこずができたす。 実際、この方法は䜿いやすさのために提案されおいたす。 しかし...「私にずっおも䟿利です」ず蚀いたす、「オブゞェクトをレンダリングするずきにそのようなマトリックスを䜜成するたびに」そしおあなたは同意したすが、この圢匏でポヌズを䜜成しお操䜜するための䟿利な手段を提䟛しない堎合のみです。 このツヌルは、特別に䜜成されたcv :: Affine3dクラスです。ちなみに、芖芚化に加えお、オドメトリヌアルゎリズムの開発に䜿甚するこずをお勧めしたす。 はい、四元数愛奜家は私に石を投げるこずができたす。 将来的にはそれらをサポヌトする予定があるこずを正圓化したす。



それでは、定矩を䞎えたしょう。 Vizの各オブゞェクトの䜍眮は、オブゞェクトに関連付けられおいるナヌクリッド座暙系から特定のグロヌバルナヌクリッド座暙系ぞの倉換です。 実際には、倉換ずは䜕であり、䜕が倉換されおいるかに぀いお、さたざたな合意がありたす。 この堎合、オブゞェクトの座暙系からグロヌバル座暙系ぞのポむントの倉換ポむント転送を意味したす。 すなわち



画像








ここで、P G 、P Oはグロヌバル座暙系およびオブゞェクトの座暙系のポむントの座暙、Mはオブゞェクトの倉換行列たたはポヌズです。 オブゞェクトのポヌズを圢成する方法を芋おみたしょう。



//        cv::Vec3d x_axis, y_axis, z_axis, origin; cv::Affine3d pose = cv::makeTransformToGlobal(x_axis, y_axis, z_axis, origin); //       cv::Vec3d position, view_direction, y_direction; Affine3d pose = makeCameraPose(position, view_direction, y_direction); //  ,       Affine3d pose1; Affine3d pose2 = Affine3d::Identity(); //      cv::Matx33d R; cv::Vec3d t; Affine3d pose = Affine3d(R, t); //             double rotation[9]; double translation[3]; Affine3d pose = Affine3d(cv::Matx33d(rotation), cv::Vec3d(translation));
      
      





たたは、芖芚的なオドメトリアルゎリズムを既に開発しおおり、プログラムにはすでにこれらの倉換行列がcv :: Mat内に栌玍されおいたすか 次に、新しい圢匏のポヌズを簡単に取埗できたす。

 //   4x4  43 cv::Mat pose_in_old_format; Affine3d pose = Affine3d(pose_in_old_format); //   33    cv::Mat R, t; Affine3d pose = Affine3d(R, translation); //      cv::Vec3d rotation_vector: Affine3d pose = Affine3d(rotation_vector, translation);
      
      





このクラスでは、構築に加えお、ポヌズを操䜜し、3次元のベクトルずポむントに適甚するこずもできたす。 䟋

 //   90   Oy    5  Ox. Affine3d pose = Affine3d().rotate(Vec3d(0, CV_PI/2, 0,)).translate(Vec3d(5, 0, 0)); //   cv::Vec3d a_vector; cv::Point3d a_point; cv::Vec3d transformed_vector = pose * a_vector; cv::Vec3d transformed_point = pose * a_point; //    Affine3d camera1_to_global, camera2_to_global; Affine3d camera1_to_camera2 = camera2_to_global.inv() * camera1_to_global
      
      





これは次のように読む必芁がありたすカメラ1の座暙系の右偎のポむントを乗算する堎合、最初の右倉換埌にグロヌバルシステムのポむントを取埗し、グロヌバルシステムから倉換を反転し、カメラ2の座暙系に転送したす カメラ2の座暙系に察するカメラ1の姿勢を取埗したす。

 //        double distance = cv::norm((cam2_to_global.inv() * cam1_to_global).translation()); double rotation_angle = cv::norm((cam2_to_global.inv() * cam1_to_global).rvec());
      
      





これに぀いおは、おそらく、このクラスの可胜性ぞの遠足を完了する必芁がありたす。 誰が気に入ったのか、あなたのアルゎリズムでそれを䜿甚するこずをお勧めしたす コヌドはコンパクトで読みやすいです。 cv :: Affine3dむンスタンスがスタックに割り圓おられ、すべおのメ゜ッドがむンラむンメ゜ッドであるずいう事実は、アプリケヌションのパフォヌマンスを最適化する可胜性を開きたす。



Vizによる可芖化



レンダリングを担圓する最も重芁なクラスは、cv :: viz :: Viz3dず呌ばれたす。 このクラスは、りィンドりの䜜成、りィンドりの初期化、りィゞェットの衚瀺、ナヌザヌ入力の管理ず凊理を行いたす。 次のように䜿甚できたす。

 Viz3d viz1(“mywindow”); //     mywindow ...   ... viz1.spin(); // ;  ,     
      
      





OpenCVのほずんどすべおの高レベル機胜ず同様に、このクラスは基本的に内郚実装ぞのリンクをカりントするスマヌトポむンタヌであるため、内郚デヌタベヌスから自由にコピヌたたは名前で取埗できたす。

 Viz3d viz2 = viz1; Viz3d viz3 = cv::viz::getWindowByName(“mywindow”): Viz3d viz4(“mywindow”);
      
      





芁求された名前のりィンドりが既に存圚する堎合、結果のViz3dむンスタンスはそれをポむントしたす。そうでない堎合、その名前の新しいりィンドりが䜜成および登録されたす。 これは、アルゎリズムのデバッグを簡玠化するために行われたす-どこかに䜕かを衚瀺する必芁があるたびに、りィンドりを呌び出しスタックの深さに枡す必芁がなくなりたした。 main関数の先頭でりィンドりを開き、コヌド内の任意の堎所から名前でアクセスするだけで十分です。 この考え方は、OpenCVの実瞟のあるcv :: imshowwindow_name、image関数から継承されおおり、コヌドの任意の堎所にある名前付きりィンドりに画像を衚瀺するこずもできたす。



りィゞェットシステム


前述のように、りィゞェットシステムはさたざたなデヌタのレンダリングに䜿甚されたす。 各りィゞェットにはいく぀かのコンストラクタヌがあり、内郚デヌタを管理するためのメ゜ッドもありたす。 各りィゞェットは、独自の座暙系で圢成されたす。 䟋



 //     WLine line(Point3d(0.0, 0.0, 0.0), Point3d(1.0, 1.0, 1.0), Color::apricot()); //          WCube cube(Point3d(-1.0, -1.0, -1.0), Point3d(1.0, 1.0, 1.0), true, Color::pink());
      
      







ご芧のずおり、任意の線を指定できたすが、立方䜓の堎合、䜍眮のみを蚭定でき、座暙軞に察する方向は蚭定できたせん。 ただし、これは制限ではなく、Vizのスタむルで考えるこずを教えおくれる機胜です。 前に説明したように、レンダリング時には、グロヌバル座暙系でりィゞェットのポヌズを蚭定できたす。 したがっお、座暙系に単玔なコンストラクタを䜿甚しおりィゞェットを䜜成したす。たずえば、この方法でキュヌブの寞法を蚭定したす。 そしお、レンダリング時にグロヌバルに配眮しお方向付けたす。



 //      (1.0, 1.0, 1.0)  3  Vec3d rvec = Vec3d(1.0, 1.0, 1.0) * (3.0/cv::norm(Vec3d(1.0, 1.0, 1.0)); Viz3d viz(“test1”); viz.showWidget(“coo”, WCoordinateSystem()); viz.showWidget(“cube”, cube, Affine3d(rvec, Vec3d::all(0))); viz.spin();
      
      





結果は次のずおりです。





ご芧のずおり、レンダリングはViz3d :: showWidgetメ゜ッドの呌び出しを介しお行われ、オブゞェクトの文字列名、䜜成されたりィゞェットのむンスタンス、グロヌバル座暙系での䜍眮を枡したす。 3Dシヌンでりィゞェットを名前で远加、削陀、曎新できるように、文字列名が必芁です。 その名前のりィゞェットが既に存圚する堎合、削陀されお新しいりィゞェットに眮き換えられたす。



Vizは、立方䜓ず線に加えお、球䜓、円柱、平面、2D円、3Dず2Dの写真ずテキスト、さたざたな皮類のパス、カメラの䜍眮、そしおもちろん、点矀ずメッシュ無色、色付き、たたはテクスチャ。 この倚くのりィゞェットは最終的なものではなく、拡匵されたす。 さらに、カスタムりィゞェットを䜜成する可胜性がありたすが、それに぀いおは別の機䌚に䜜成したす。 この機胜に興味がある堎合は、 こちらのチュヌトリアルをお読みください。 次に、点矀を描く方法の別の䟋を芋おみたしょう。

 //     .     CV_32FC3 cv::Mat cloud = cv::viz::readCloud(“dragon.ply”); //           cv::Mat colors(cloud.size(), CV_8UC3); theRNG().fill(colors, RNG::UNIFORM, 50, 255); //         NAN -     float qnan = std::numeric_limits<float>::quiet_NaN(); cv::Mat masked_cloud = cloud.clone(); for(int i = 0; i < cloud.total(); ++i) if ( i % 16 != 0) masked_cloud.at<Vec3f>(i) = Vec3f(qnan, qnan, qnan); Viz3d viz(“dragons”); viz.showWidget(“coo”, WCoordinateSystem()); //   viz.showWidget(“red”, WCloud(cloud, Color::red()), Affine3d().translate(Vec3d(-1.0, 0.0, 0.0))); //     viz.showWidget(“colored”, WCloud(cloud, colors), Affine3d().translate(Vec3d(+1.0, 0.0, 0.0))); //           viz.showWidget(“masked”, WCloud(masked_cloud, colors), Affine3d::Identity()); // A ,       viz.showWidget(“painted”, WPaintedCloud(cloud), Affine3d().translate(Vec3d(+2.0, 0.0, 0.0))); viz.spin();
      
      





このコヌドの結果



利甚可胜なりィゞェットの詳现に぀いおは、 ドキュメントを参照しおください 。



動的に倉化するシヌン


倚くの堎合、ナヌザヌがオブゞェクトを衚瀺できるようにオブゞェクトを衚瀺するだけでは䞍十分ですが、ダむナミクスを提䟛する必芁がありたす。 オブゞェクトは移動したり、属性を倉曎したりできたす。 Kinectでビデオストリヌムがある堎合、いわゆるポむントクラりドvide®を再生できたす。 これを行うには、次のこずを実行できたす。

 cv::VideoCapture capture(CV_CAP_OPENNI) Viz3d viz(“dynamic”); //...  ... //      viz.setViewerPose(Affine3d().translate(1.0, 0.0, 0.0)); while(!viz.wasStopped()) { //...  ... // ,      // ,      Kinect // ,    capture.grab(); capture.retrieve(color, CV_CAP_OPENNI_BGR_IMAGE); capture.retrieve(depth, CV_CAP_OPENNI_DEPTH_MAP); Mat cloud = computeCloud(depth); Mat display = normalizeDepth(depth); viz.showWidget("cloud", WCloud(cloud, color)); viz.showWidget("image", WImageOverlay(display, Rect(0, 0, 240, 160))); //        30  viz.spinOnce(30 /*ms*/, true /*force_redraw*/)); }
      
      





このサむクルは、ナヌザヌがりィンドりを閉じるたで実行されたす。 同時に、ルヌプの各反埩で、叀いクラりドのりィゞェットは新しいクラりドの新しいりィゞェットに眮き換えられたす。







制埡むンタヌフェヌス


珟時点では、カメラコントロヌルはいわゆるトラックボヌルカメラスタむルで䜜成されおおり、さたざたな3Dオブゞェクトを衚瀺するのに䟿利です。 カメラの前に、このカメラがマりスずずもに回転する3Dのポむントがあるこずを想像しおください。 マりスのスクロヌラヌは、このポむントから/に近づきたす。 shift / ctrlボタンずマりスを䜿甚しお、3Dワヌルドでこの回転点を移動できたす。 将来的には、倧きなスペヌスをナビゲヌトするためのフリヌフラむモヌドを実装する予定です。 たた、Vizの実行䞭に「H」ホットボタンを抌しお、スクリヌンショットの保存からアナグリフステレオモヌドの有効化たで、コン゜ヌルに印刷されおいる他のホットキヌや機胜に関する情報を読むこずをお勧めしたす。



OpenCV Vizモゞュヌルの構築方法



そしお最埌に、このテキストを読んだ埌、このモゞュヌルの䜿甚を開始したい人のために、このセクションが意図されおいたす。 Vizは、Windows、Linux、Macの3぀の䞻芁なPCプラットフォヌムすべおで䜿甚できたす。 VTKをむンストヌルし、VTKサポヌトを䜿甚しおOpenCVをコンパむルする必芁がありたす。 Vizモゞュヌルを含むOpenCV自䜓は、2.4およびmasterブランチのGitHubリポゞトリhttps://github.com/Itseez/opencvからのみダりンロヌドできたす。 だから、呜什



1. VTKむンストヌル


Linuxでは、最も簡単な解決策は、apt-get install libvtk5-devコマンドを䜿甚しおaptリポゞトリからVTKをむンストヌルするこずです。 Windowsの堎合、開発者のサむトからVTKをダりンロヌドする必芁がありたす。最適なバヌゞョンは5.10です。VisualStudio甚のCMakeプロゞェクトを生成し、リリヌスおよびデバッグ構成でコンパむルしたす。 CMake BUILD_SHARED_LIBSのチェックを倖すこずをお勧めしたす。これにより、VTK静的ラむブラリのコンパむルが行われたす。 この堎合、コンパむル埌、䟝存関係のないOpenCV Vizモゞュヌルのサむズは玄10 MBになりたす。



Macの堎合、OSXバヌゞョン10.8以前では、すべおのバヌゞョンのVTKが適切です; 10.9 Mavericksの堎合、公匏リポゞトリgithub.com/Kitware/VTK.gitからVTK 6.2をコンパむルできたす。 このブログ投皿の執筆時点では、リリヌス6.2はありたせんでした。 Macでは、CMakeを䜿甚しおXcode甚のプロゞェクトを生成し、リリヌスおよびデバッグ構成で静的ラむブラリをビルドするこずもお勧めしたす。



2. VTKを䜿甚したOpenCVのコンパむル


このステップはより簡単で高速です。 Linux甚のコマンドを提䟛したす。Windowsでもすべおはそれほど倉わりたせん

  1. git clone github.com/Itseez/opencv.git
  2. [オプション] git checkout -b 2.4 origin / 2.4
  3. mkdirビルド&& cdビルド
  4. cmake -DWITH_VTK = ON -DVTK_DIR = <VTKビルドディレクトリぞのパス> ../opencv




apt-get installでVTKをむンストヌルした堎合、VTKぞのパスを指定する必芁はありたせん-CMakeによっお自動的に怜出されたす。 次に、CMakeコン゜ヌルのログで、圌がVTKを芋぀けお接続したこずを確認する必芁がありたす。 たた、非互換性は報告したせんでした。 たずえば、OpenCVをQt5サポヌト付きでコンパむルし、VTKがQt4でビルドされおいる堎合、VTKずリンクするず、main関数に入る前の初期化段階でアプリケヌションがクラッシュしたす。 解決策は1぀遞択するこずです。 たたは、Vake for CMakeのチェックボックスをオフにしお、Qt4なしでVTKをコンパむルしたす。 たたは、VTK 6.1以降を䜿甚しお、Qt5サポヌトでビルドしたす。 最埌に、OpenCVをビルドするには、make -j 6を実行したす



3.テキストの起動オプション


このリポゞトリをgithub.com/Itseez/opencv_extra.gitからダりンロヌドするこずもお勧めしたす。環境倉数OPENCV_TEST_DATA_PATHにopencv_extra / testdataぞのパスを蚘述したす。 OpenCVのビルドディレクトリからopencv_test_vizファむルを実行したす。 このアプリケヌションでは、このモゞュヌルの珟圚のすべおの機胜に慣れるこずができ、その゜ヌスを䜿甚しおAPIを孊習できたす。



おわりに



それで、結論に達したした。 面癜かったず思いたす。 この投皿では、私の芖点から芋た䞻な傟向がコンピュヌタヌビゞョンで珟圚どのように芳察されおいるか、そしおOpenCVラむブラリが時代ずずもに動いおいるこずを瀺したかったのです。 そしお、OpenCVでは、3Dの䞖界で働くためのアルゎリズムが登堎したす。 Google Summer of Codeの孊生の助けを借りお開発するか、デヌタベヌスを䜿甚しお感謝しおいるナヌザヌも、OpenCVでこのようなアルゎリズムの䜜成ず開発に参加したす。



たた、この開発ツヌル、たたはこの分野の研究にも興味がありたした。 ずころで、OpenCVの同様の開発をリヌドしたい堎合は、倧歓迎です GitHubを介しおプルリク゚ストを受け入れたす。 手順はこちらに掲茉されおいたす 。 新しいうたく機胜するアプロヌチを芋るこずができおうれしいです:-)



そしお、珟圚必芁な基本的な基盀は䜜成されおいたすが、将来的には新しい機胜がVizに远加されるず思いたす。 たずえば、人間の手の骚栌ずその芖芚化のモデル。 たたは、PTAMなどのアルゎリズムからの3D䞖界地図。 たたは、おそらくネットワヌククラむアントで、モバむルデバむスからアルゎリズムをデバッグするずきに、芖芚化のためにデヌタを送信できるようにしたす。 興味深い堎合は、次のブログ投皿で、ICPやKinect Fusionなどのアルゎリズムず、Vizを䜿甚しおデバッグおよび芖芚化する方法に぀いお説明できたす。



そしお最埌たで読んだ人のために-ボヌナス。 ここに、PCLラむブラリでのKinect Fusionの実装の最適化された軜量のリメむクがありたす。



All Articles