粗大メモ置き場

個人用,たまーに来訪者を意識する雑記メモ

WindowsでSudoの代わりになrunasについて(管理者権限でプログラム実行)

Windowsコマンドプロンプトの使い勝手がすこぶる悪いのはご存知かと思われますが,
管理者権限で実行するのにもいちいち苦労します。

Powershellを介して呼び出す

Powershellとは要は賢いコマンドプロンプトのことのようです。詳しい仕様はよく知りません。

以下のように打つことでsudo (command)を代替できます。長い!

powershell -command "Start-Process -Verb runas (command)"

ただ,問題として2つ以上の引数を与えるとエラーを起こします。
暇な時に解決策を見つけるようにします。。。

lusrmgr.msc からadministratorを有効化(未検証)

デフォルトではそもそもスーパーユーザがいませんので有効にします。
Windows 管理者権限でコマンド実行 – がとらぼ

Homeボタンでlusrmgr.mscを検索実行すると次のようなウインドウが出ます。
f:id:ossyaritoori:20171024220052p:plain

  • ユーザをクリック
  • Administratorをダブルクリック
  • Administratorを無効化を解除,保存

f:id:ossyaritoori:20171024221514p:plain

この後にパスワードを変更したりするそうです。

複雑性とは何か

「複雑性」についてなんか書けとの課題があり、
Principles of Systems Scienceの5章を読むことになったので
要約メモします。図は著作権とかありそうだし省略。

Principles of Systems Science (Understanding Complex Systems)

Principles of Systems Science (Understanding Complex Systems)

5-1:イントロ

一重に複雑系といっても様々な解釈がある。
本書はHerbert Simonの言説に則って紹介する。

5-2:複雑系の特徴

  • 系の振る舞いが予測不可能である事
  • 理解するのにそれなりの労力を必要とする事
  • 簡単に系を記述できない事

Surpriseがあることというのが重要な条件である。
Surpriseがあるということは予測が建てられる、すなわち我々が系についてある程度の理解が可能であるというのを前提にしている。
一方で我々の理解に基づく予測から"Surprise"な結果を示すので「複雑」な系だ。という解釈のようである。

したがって複雑性を数値化する際にはこの「驚愕性」を指標にするのが最も直感的であるとも言っている。

5-2-1:複雑系の勘所

人間が直感的に捉える複雑系の持つ特徴として

  • 様々な要素から成り立っていて
  • そのそれぞれが相互作用をもたらしていて
  • 個としての性質と集合としての性質を併せ持つ

ということが述べられている。

人間のこうした勘は複雑系の理解の礎にはなるが、どのような、という点で曖昧であるため勘の域を出ない。

5-2-2:系としての複雑性の定義

結論から言うと階層構造がいかに深いかという点において複雑性を捉えることができる。

構造的複雑性

ここから具体例が述べられている。

例えば、人間関係を複雑系と見立てるなら、個々の人間が最小の構成要素、人間一人一人の関係性がその一つ上の階層の構成要素、といった風に前の小さな階層の要素がより大きな階層の要素になるという系が考えうる。
構成要素が多様であるほど、その関係性が多様であるほど系はより複雑になる。

ただし、これらの規模のみが複雑性を定義するのではない。
生物の例を見ていくと、体が大きく構成細胞数の多い生物ほど「複雑」であるのかというとそういうわけでもないだろう。
また、これらの構造は必ずしも下層の大きなピラミッド型ではなくその逆もありうる。
例えば、現在普及している計算機の最も基本的な部品は非常に単純な論理回路たちである一方で、結果として生まれてくるソフトウェアなどは膨大な種類ある。

機能的複雑性

こちらに関しては非常に説明しづらい。
各要素の関係性は一定ではなく、しかし一方で流れなど一定の法則があるという感じのことを言っている。

前章との対比で、プログラミングで言う所の構造体ではなくClassのメンバ関数について言及したようであるがいまいち自分はピンときていない。


5-3:他の視点から見た複雑性

5-3-1:アルゴリズム

コンピュータ科学の分野ではしばしば「時間」が複雑性の物差しに使われる。
問題の規模に対して解決にかかる時間が多項式時間で終わらないものをNon-Polinominal、すなわちNP困難な問題がしばしば先程定義したような構造的な複雑性を持ちうることが説明されている。

アルゴリズム構築において、問題を小さな部分問題にとりわけてそれらの組み合わせとして解決を測るという手段はまさにSimonsの言う所の構造的複雑性を有しているとも言える。

5-3-2:振る舞いの複雑性

例えばみんな大好き「セルオートマトン」などがあげられる。余談だが筆者が初めてアルゴリズムという者に触れたのがこの話題である。
詳しくはとりあえずWikipedia等を参照されたい。
セル・オートマトン - Wikipedia

個々は簡単な要素(例えば0と1の状態を保存する)であるセルに隣接するセル同士の相互作用を設定することで全体として様々な複雑な挙動を示すというのがこの概要であり、複雑系ではこれを「創発」と呼ぶ。

フラクタルもこれと似たような性質をもち、単純な数学的規則性を繰り返し適用することでとても複雑な図形を作り出すといったことが知られている。

5-4:複雑性に対する追加考察

  • Disorganized と Organizedされた複雑性
  • 潜在的な複雑性と実現された複雑性

Disorganizedとは例から汲み取るに、要素同士の相互関係が固定されていないというのが重要な要件のようだ。密閉した空間に気体を入れた際の系とエントロピーの関係が具体例として挙げられている。

複雑性が潜在的か実現されたかもやはり要素同士の関係性に密接に関わっており、
関係性が流動的である限り、そしてその関係性の取りうる選択肢が多いほどその系はまだ見ぬ複雑性を有しているということになるだろう。

5-5:複雑性の限界

限界というよりはデメリットということが述べられている。
複雑であるということはある種の脆弱性を秘めており、少しの変化で系が崩壊する可能性があることが示されている。

5-5-1:要素の不全

細胞の自己増殖を例として考えると、自身を構成する要素であるタンパク質の生成に何らかの問題があった場合、細胞は容易に死に至るといったようなことがあげられる。

5-5-2:プロセスの入出力の不全

系への入出力に異変があった場合に系の不全が引き起こされることについて書いてある。

5-5-3:系の不全:カスケード

カスケードとは以前のプロセスの結果が次のプロセスの入力になるような連続したプロセスの事を言っている。
人間の細胞は日々自己複製を繰り返しており、複製された細胞が次に自己をまた複製するといったプロセスが存在する。

したがってどこかの段階で不全があった場合プロセスの全体の流れが崩壊を起こすといった例がある。
すなわちこれは生物における老いである。

5-6 :まとめ

複雑性を理解するにはその要素、関係性、挙動の全てに着目する必要があり、未だに我々はそれらをうまく定義する術を持たない。
でも実世界の事象は全てこのような複雑性の中にあり、これらを理解する術を模索すべきと締めくくられる。

所感

この章だけを読んでもあまり複雑性というものについて体系的に理解した気分にはなれなかった。あと途中で面倒になって結構雑に読んだ。
現象を個々の要素に分解しそれらの関係性を追求するという科学の基本的思考法が幾つかの具体例とともに載っている点は教養として良いと思ったので
興味がある方は読んで見ると良いかもしれない。

しかしこれらの思考法も実際に自分の問題にこの観点を適用するなどしないとより深い理解は得られないだろう。そのための宿題なのだろうが。

Rplidarをjetson TX1,2で使う(要Kernel Build)

メモ記事なのでざっくりと.である口調で.

Rplidar

SLAMTECH社の出しているLIDAR.
周囲の距離情報を10hzで400点(0.9°ずつ)出力してくれるすぐれものである.

安価?な割に性能がよくROSでWrapperもきちんと作られているため非常に使い勝手が良い.

f:id:ossyaritoori:20171014102112p:plain:w300

難点は重心が偏っているため回転時に振動を起こしてしまうというもの.
それくらいは頑張って欲しかった.

Rplidar with ROS

ROSのWrapperもあるので簡単にRVizなどで出力可能.
すごいぞ〜かっこいいぞ〜〜!!

f:id:ossyaritoori:20171014101824p:plain

jetsonで運営するにあたっての問題

jetsonで使いたいのだが,これには周知の問題があり,USB通信のCP201xに対応するドライバがjetsonのtegaraには入っていないのである.(よくわかってない)
従ってドライバを認識するためにカーネルを再ビルドする必要が有る.

ここの動画が詳しいので割と障壁は低そうに見えた...が.
www.jetsonhacks.com

空き容量が「3GB」必要なのである.
TX1の使用可能容量は14Gくらいで,Ubuntuまわりで6G,Cudaまわりで3G,ROS周りで2G,Opencvまわりで1G...ん?
はい.容量が足りません.

NVIDIAの強マンとやりとりしたところ「クロスコンパイル」を勧められたが,,,
https://devtalk.nvidia.com/default/topic/1000764/jetson-tx1/rplidar-and-jetson-tx1/?offset=12#5214215

ミスったらどうするんだろう...的な不安で一歩踏み出せていないです.
はぁ困った.

なお,こちらの記述が大いに参考になりそうなのでいつか試す.いつか.
Cross Compile Custom Linux Kernel for the Tegra TX1 · GitHub

追記:TX2で使ってみました。

カーネルビルドについてはこちらを参照。
Build Kernel and ttyACM Module - NVIDIA Jetson TX2 - JetsonHacks

CP201xというUARTの通信ドライバが必要らしいです。
具体的な手順に関しては次の記事の中段くらいのカーネルコンパイルの章でお話します。
ossyaritoori.hatenablog.com

ソースのダウンロード

以下のリポジトリからダウンロードしてcatkin_makeします。
GitHub - robopeak/rplidar_ros

USB機器のSUDOなしアクセス

以下のコマンドを実行後logout で反映されます。

sudo gpasswd -a ユーザ名 dialout

販促

できることなら誰か買って重心の偏りを補正する方法を考えて欲しいものです.

ROSでGPUを有効にしたOpenCVを使用する

前回の記事でOpencvをcudaのサポート込でコンパイルしたわけですが今度はこれをROSで使えるように教えこまないといけません.

ここで問題になるのがOpencv with cudaとRosのOpencv3パッケージの競合です.
自分でコンパイルした方を使いたいのですが,ROSの方にはcv_bridgeを始めとする超重要パッケージもあるので片方を消すわけにも行かない...

以下の記事にもあるように割と根深い問題です.
qiita.com

Step1. findpackageで正しいpathを指定する。

はじめにfindpackageの部分をいじって、OPENCV_LIB等に正しいPATHを認識させます。

cmakelistのfindpackageがどこを見ているのかチェック

ガチの初心者&雰囲気で理解しているので間違っていたらコメントください.
CMakeListでははじめに
findpackage()を呼んでインクルードしたいパッケージのPathを探すようです.
その後,そのPathを用いて目的のソースとライブラリを関連付けます.

${FUGA}の中身を確認するには?

次のような文をprintfよろしく書き連ねることでcmakeをするときにWarning文として出力できます.
多分正攻法ではない気がしますがとにかく動きます.WARNINGをつけているのは該当箇所に黄色い見出しがついて見やすくなるからです。

MESSAGE(WARNING "prefix ${CMAKE_PREFIX_PATH}")    
MESSAGE(WARNING "version ${OpenCV_VERSION}")
MESSAGE(WARNING "install path ${OpenCV_INSTALL_PATH}") 
MESSAGE(WARNING "config path ${OpenCV_CONFIG_PATH}") # look at the output of this message
MESSAGE(WARNING "include dirs ${OpenCV_INCLUDE_DIRS}")
MESSAGE(WARNING "libs ${OpenCV_LIBS}")

OpenCVのPathを指定する

私はcmakeとかLinuxとかガチガチの初心者でしたのでcmakeの中身についてメモをば.
以下のような文を足すことで確かにCmakeにOpencvのデフォルトパッケージの位置を教えることができます.

find_package(OpenCV 3 REQUIRED
NO_MODULE 
PATHS /usr/local 
NO_DEFAULT_PATH)

cmakeとcatkin_makeで結果が違うんだけど!?

そうして試してみると,ある時cmakeでコンパイルした時とcatkin_makeでコンパイルした時で結果が違うことにきづきました.

どうもcatkin_makeでは前回のBuildに依存しているようで,一度Buildとdevelフォルダを消し飛ばす必要があります.
How to tell Catkin_make to use opencv with gpu? - ROS Answers: Open Source Q&A Forum

develをまるごと消すとdarknet_rosとかに不都合が生じるのできちんとバックアップをとっておくように!

そうして再コンパイルしてこの事件は解決...かにおもわれました.

STEP2. catkin_LIBRARIESとの競合解決

問題提起

上記の方法で、
結局ソースコードと正しいOpencvとを関連付けることができませんでした.

原因は最後のLinkに有ると思っています.

target_link_libraries(my_function ${OpenCV_LIBS} ${catkin_LIBRARIES})

このCatkin_librariesがある$catkin_develを見たところ,以下のpathが紛れておりバッチリROSのOpencvを参照していたからです.

/opt/ros/kinetic/include/opencv-3.2.0-dev

ということは,現状次の解決策はROSのOpencvとBuildしたOpencvのうち,被っている箇所のどちらかを吹き飛ばすか,先にBuildした方のOpencvのPathを先に解決させることが考えられます.(小学生並みの希望的観測)

が,どっちもやり方がよくわかんないので誰かおしえてください〜〜〜ってなっているのが現在の状況.

追記:catkin_librariesからROSのopencvを追い出す

cmakeの変数はどれも文字列として扱う事ができるので、そこからROSのOpencvに相当するところだけを頑張って置換する事ができます。

書き方の例は

string(REPLACE "StringYouWantReplace" "ReplacedString" LIBafter "${LIBbefore}" )

こんな感じ。

私の場合、catkin_LIBRARIESからOpencv関連を全てを消し飛ばすのが最も有効でした。
なお、cv_bridge等のパッケージはOpencv2準拠で別枠らしいのでこの方法では支障をきたすことはありません。

string(REPLACE "/opt/ros/kinetic/lib/libopencv_calib3d3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_core3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_features2d3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_flann3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_highgui3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_imgcodecs3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_imgproc3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_ml3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_objdetect3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_photo3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_shape3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_stitching3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_superres3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_video3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_videoio3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_videostab3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_viz3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_aruco3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_bgsegm3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_bioinspired3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_ccalib3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_cvv3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_datasets3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_dpm3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_face3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_fuzzy3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_hdf3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_line_descriptor3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_optflow3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_phase_unwrapping3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_plot3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_reg3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_rgbd3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_saliency3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_stereo3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_structured_light3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_surface_matching3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_text3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_xfeatures2d3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_ximgproc3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_xobjdetect3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_xphoto3.so.3.2.0;" "" catkin_LIBRARIES "${catkin_LIBRARIES}")

フォーラムでクソ長い質問をしたかいがありました。
How to tell Catkin_make to use opencv with gpu? - ROS Answers: Open Source Q&A Forum

テスト用ソース、サンプルプロジェクト

cmakelistsをどう書くと動いたり動かなかったりするのか調べるのに使ったサンプルプロジェクト。良ければどうぞ。
GitHub - YoshiRi/ros_opencv_conflict: Immitate ROS opencv version confliction

未解決問題

  • 何故か色々いじっているうちにimage_pipelineのstereo_image_procが激遅になってしまって非常に悲しい。
  • OpenCVをCudaでコンパイルしたバージョンがROSのバージョンよりも遅い現象がある。OpenCLを有効化していないせい?

user profile overview - OpenCV Q&A Forum

小技集

catkin_make -DOpenCV_INCLUDE_DIRS=/opt/opencv/include

みたいな感じでBuild時に教えることができますが,雑に試した結果はうまく行っていません.

あと、知らなかったんですが

catkin_make --only PROJECT

ってやれば一つのプロジェクトだけコンパイルできるんですね...
これ使えば他との競合を考えずにコンパイルできたかもしれない。

OpenCV バージョン指定

cmakelistで

SET(OCV_VERSION "3.1")
find_package(OpenCV ${OCV_VERSION})

と書けば該当するOpencvを指定できますね。
これも有効な方法でしょう。

checkPackage("OPENCV_CORE" "Error statement")
と打つことで、該当パッケージが入っているのか確認できるのもグッドポイント。

保存用データ

ros-kinetic-oepncv3のライブラリ

opencv_calib3d;opencv_core;opencv_features2d;opencv_flann;opencv_highgui;opencv_imgcodecs;opencv_imgproc;opencv_ml;opencv_objdetect;opencv_photo;opencv_shape;opencv_stitching;opencv_superres;opencv_video;opencv_videoio;opencv_videostab;opencv_viz;opencv_aruco;opencv_bgsegm;opencv_bioinspired;opencv_ccalib;opencv_cvv;opencv_datasets;opencv_dpm;opencv_face;opencv_fuzzy;opencv_hdf;opencv_line_descriptor;opencv_optflow;opencv_phase_unwrapping;opencv_plot;opencv_reg;opencv_rgbd;opencv_saliency;opencv_stereo;opencv_structured_light;opencv_surface_matching;opencv_text;opencv_xfeatures2d;opencv_ximgproc;opencv_xobjdetect;opencv_xphoto

ビルドしたライブラリ

opencv_xphoto;opencv_xobjdetect;opencv_ximgproc;opencv_xfeatures2d;opencv_tracking;opencv_text;opencv_surface_matching;opencv_structured_light;opencv_stereo;opencv_sfm;opencv_saliency;opencv_rgbd;opencv_reg;opencv_plot;opencv_optflow;opencv_line_descriptor;opencv_hdf;opencv_fuzzy;opencv_face;opencv_dpm;opencv_dnn;opencv_datasets;opencv_cvv;opencv_ccalib;opencv_bioinspired;opencv_bgsegm;opencv_aruco;opencv_videostab;opencv_videoio;opencv_video;opencv_superres;opencv_stitching;opencv_shape;opencv_photo;opencv_objdetect;opencv_ml;opencv_imgproc;opencv_imgcodecs;opencv_highgui;opencv_flann;opencv_features2d;opencv_cudev;opencv_cudawarping;opencv_cudastereo;opencv_cudaoptflow;opencv_cudaobjdetect;opencv_cudalegacy;opencv_cudaimgproc;opencv_cudafilters;opencv_cudafeatures2d;opencv_cudacodec;opencv_cudabgsegm;opencv_cudaarithm;opencv_core;opencv_calib3d

Build OpenCV for GPU version in Jetson TX1

容量に関する問題

OpenCVソースコードからフルでコンパイルするには容量が4GB必要になります。
16GBの容量のTX1にそれは非常に厳しい...

外部メモリ上でのビルド

似たような状況がRaspberryPiにもあるようで、そちらの記事を参照しました。
PkLab - Install OpenCV 3.2 Python/C++ on Raspberry PI

USBをLinuxファイルシステムとして認識させてその上でコンパイルします。

USBの中身のフォーマット

とにかくUSBの中身をLinuxで見れるext2等のフォーマットへと変える必要があります。

sudo fdisk -l

で中身を確認しながらパーティションをクリアできるとありましたが、
私の場合うまく行かなかったので以下のサイトに準拠してフォーマットしました。
How to format a USB flash drive? - Ask Ubuntu


マウント

私の場合/dev/sda1が対象のUSBのデバイス名なので

sudo mkfs -t ext2 /dev/sda1

これでLinuxファイルシステムとしてフォーマットして
次のコマンドでUSBメモリの中身をLinuxファイルシステムから確認する事ができるようになります。

mkdir ~/usbmem
sudo mount /dev/sda1 ~/usbmem

Opencvのダウンロードとコンパイル

大部分はOpenCV: Building OpenCV for Tegra with CUDAを参考にしています。

ソースのダウンロードと所々の修正は[参考文献1]を。
その後contrib moduleをダウンロードするところは[参考文献2]を参照しています。
SIFTとかも使いたいですからね。

git clone https://github.com/opencv/opencv.git
git cherry-pick 10896
git cherry-pick cdb9c
git cherry-pick 24dbb
cd opencv-3.1.0
git clone --depth 1 https://github.com/Itseez/opencv_contrib.git opencv_contrib
cd opencv_contrib
git fetch origin --tags --depth 1
git checkout 3.1.0

Dependencyの解決

依存するパッケージをインストールします。

sudo apt-add-repository universe
sudo apt-get update
sudo apt-get install \
    libglew-dev \
    libtiff5-dev \
    zlib1g-dev \
    libjpeg-dev \
    libpng12-dev \
    libjasper-dev \
    libavcodec-dev \
    libavformat-dev \
    libavutil-dev \
    libpostproc-dev \
    libswscale-dev \
    libeigen3-dev \
    libtbb-dev \
    libgtk2.0-dev \
    pkg-config

準備していない人はPython環境もちゃんと準備しましょう。(下は2.7用)

sudo apt-get install python-dev python-numpy python-py python-pytest

Cmake と make

追記:完全に参考文献1に準拠し直しました。

cmake .. -DWITH_OPENGL:BOOL=ON -DWITH_QT:BOOL=ON -DWITH_CUDA:BOOL=ON -DCUDA_ARCH_BIN="5.2" -DCUDA_ARCH_PTX="5.2" -DCMAKE_BUILD_TYPE=RelWithDebugInfo -DCMAKE_INSTALL_PREFIX=/usr/local -DBUILD_TESTS:BOOL=OFF -DBUILD_PERF_TESTS:BOOL=OFF -DWITH_FFMPEG:BOOL=OFF -DENABLE_NEON:BOOL=ON -DBUILD_EXAMPLES:BOOL=ON -DINSTALL_C_EXAMPLES:BOOL=OFF -DINSTALL_PYTHON_EXAMPLES:BOOL=ON -DOPENCV_EXTRA_MODULES_PATH=../opencv_contrib/modules
以下古いバージョン(不具合あり)

多分どれかがおかしい...
Cmakeですが、参考文献1と2をあわせた手法を取っています。>||
mkdir build && cd build
cmake .. \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/usr \
-DBUILD_PNG=OFF \
-DBUILD_TIFF=OFF \
-DBUILD_TBB=OFF \
-DBUILD_JPEG=OFF \
-DBUILD_JASPER=OFF \
-DBUILD_ZLIB=OFF \
-DBUILD_EXAMPLES=OFF \
-DBUILD_opencv_java=OFF \
-DBUILD_opencv_python2=ON \
-DBUILD_opencv_python3=OFF \
-DENABLE_PRECOMPILED_HEADERS=OFF \
-DWITH_OPENCL=OFF \
-DWITH_OPENMP=OFF \
-DWITH_FFMPEG=ON \
-DWITH_GSTREAMER=OFF \
-DWITH_GSTREAMER_0_10=OFF \
-DWITH_CUDA=ON \
-DWITH_GTK=ON \
-DWITH_VTK=OFF \
-DWITH_TBB=ON \
-DWITH_1394=OFF \
-DWITH_OPENEXR=OFF \
-DCUDA_TOOLKIT_ROOT_DIR=/usr/local/cuda-8.0 \
-DCUDA_ARCH_BIN=5.3 \
-DCUDA_ARCH_PTX="" \
-DINSTALL_C_EXAMPLES=OFF\
-DINSTALL_TESTS=OFF \
-DOPENCV_EXTRA_MODULES_PATH=../opencv_contrib/modules
|

  • DCMAKE_INSTALL_PREFIX を /sur/localにするか迷う...(よくわかっていない)


次にmakeします。

make -j4 VERBOSE=1

このVERBOSE=1を入れることでエラーが出た時の詳細が出て進めやすくなります。
(エラー出る前提)
よく出たエラーについては下を参照。

make install

最後のこのコマンドでmakeした結果の実行ファイルなどをローカルのPATHの通ったLibなどにコピーします。
(間違っていたら教えてください)

make install

時々sudoでやっているサイトを見るのだけれどどっちが正しいのだろう?うまく行かなかったらsudoで。

sudo ldconfigを行う場合もあるそうな。

エラー集

当然出まくるエラー。

hdf5.h : No such file or directory

もしhdf5.hがあるのにこのエラーが出るなら
Pythonがhdf5を探せていないのが原因。

modules/python/common.cmake の最後の行に以下の2文を追加。

find_package(HDF5)
include_directories(${HDF5_INCLUDE_DIRS})

can't find hdf5.h when build caffe · Issue #156 · NVIDIA/DIGITS · GitHub
build error for python bindings with opencv_contrib modules · Issue #6016 · opencv/opencv · GitHub

onlineMIL.hpp でのエラー

In file included from /home/ubuntu/usbmem/opencv/opencv_contrib/modules/tracking/include/opencv2/tracking/tracker.hpp:48:0,
                 from /home/ubuntu/usbmem/opencv/build/modules/python2/pyopencv_generated_include.h:49,
                 from /home/ubuntu/usbmem/opencv/modules/python/src2/cv2.cpp:12:
/home/ubuntu/usbmem/opencv/opencv_contrib/modules/tracking/include/opencv2/tracking/onlineMIL.hpp:57:23: error: expected unqualified-id before ‘>’ token
 #define  sign(s)  ((s > 0 ) ? 1 : ((s<0) ? -1 : 0))

この場合、同様の定義が他のcppファイルで使われているのが原因。
error building ```opencv_contrib/modules/tracking/include/opencv2/tracking/tracker.hpp``` · Issue #618 · opencv/opencv_contrib · GitHub

onlineMIL.hppにある次の文をカットして
src/omlineMIL.cppへとペーストする。

#define  sign(s)  ((s > 0 ) ? 1 : ((s<0) ? -1 : 0))

cuda_gl_interop.hに関するエラー

/usr/local/cuda-8.0/includes にある同盟ファイルの GL/gl.hのインクルード周りを次のように変更。

//#if defined(__arm__) || defined(__aarch64__)
//#ifndef GL_VERSION
//#error Please include the appropriate gl headers before including cuda_gl_interop.h
//#endif
//#else
#include <GL/gl.h>
//#endif

Webカメラから画像が取れない?

謎。v4l2周りのエラーということはわかっているのだが...。謎。

テスト

Python

python

import cv2
cv2.__version__
print(cv2.getBuildInformation())

Cpp

以下の通りでコンパイル可能。

g++ -ggdb XXXX.cpp -o XXXX `pkg-config --cflags --libs opencv`

ソースの削除について

基本的にsudo make installを済ませたらもとのOpencvのフォルダに用はないです。
jetsonは容量がカツカツなので中でコンパイルした人はデリート推奨。
私は怖いのでまるっとドライブにバックアップしました。
stackoverflow.com

実行の際のコツ(最初に空の関数を呼び出す)

Opencvでは初回の関数呼び出し時にGPUを初期化する的な動作があるため,
実行する際にはとても時間がかかるという問題があります.

実際にOpenCVのフォーラムに問い合わせたところ,
以下のように空のcuda関数を呼び出すことで初期化を済ませることができるという回答を得ました.

cv::cuda::GpuMat test;
test.create(1, 1, CV_8U);

answers.opencv.org

Python Computation Time Mesurement Class(Pythonでプログラムの実行時間を測る方法)

Computation time measuring is important issue for most programmers.
Pythonで実行時間を測って可視化したい時があるかと思います。

Basis (原理)

Many functions exist for the time measurement.
以下に詳しくありますがtimeをimportすればOKです。
16.3. time — 時刻データへのアクセスと変換 — Python 3.6.3rc1 ドキュメント

I use time.time() to get current time.
There are some alternative such as time.clock() or something.

そのうち、time.time()で現在の時間を浮動小数点で得ることができるため、

start=time.time()
# ここでなにかする
end=time.time()
dt=end-start # かかった時間

となります。

My class (作成したクラス)

いちいち宣言したり、過去の値を保存するのは管理が面倒で馬鹿らしいため、クラスとして実装しました。

import numpy as np
import matplotlib.pyplot as plt
import time # time.time() to get time

class Checktime:
    def __init__(self):
        self.checktime = [0]
        self.difftime = []
        self.start = time.time()
    def check(self,name=""):
        self.checktime.append(time.time()-self.start)
        self.difftime.append(self.checktime[-1]-self.checktime[-2])
        print(name)
        print("Now time is "+str(self.checktime[-1])+" [s]")
        print("Computed in "+str(self.difftime[-1])+" [s]\n")
        
    def show(self):
        leng = len(self.checktime)
        plt.plot(np.arange(0,leng,1),np.array(self.checktime),label="Accumulation time")
        plt.plot(np.arange(1,leng,1),np.array(self.difftime),label="Each Process time")
        plt.legend()
        plt.grid()
        plt.show()

How to Use

使い方は簡単。

import

Just put this function on you source or save this program as "FILENAME.py" and write as follows.

from FILENAME import *

上のソースコードをまるっとコピーして自分のソースに貼るか、適当な名前で保存して上のようにImportできます。

Usage

プロセス名を入れることでどのプロセスにどれだけ時間がかかったかを可視化できます。

# init 
T = Checktime()

# do something
T.check() # print current time

# or you can name your processing
T.check("PROCESS NAME")

# Finally you can see the time consumption graph
T.show()


以下のような出力を得るでしょう。
results is like this:
Console output

Image Reading
Now time is 0.00387120246887 [s]
Differ from 0.00387120246887 [s]

Get Histogram
Now time is 0.00810813903809 [s]
Differ from 0.00423693656921 [s]

Get Mask
Now time is 0.00903105735779 [s]
Differ from 0.000922918319702 [s]

Extract ORB Feature
Now time is 0.0206370353699 [s]
Differ from 0.0116059780121 [s]

出て来る図はこんな感じ。

Figure output
f:id:ossyaritoori:20171005075324p:plain

pyplotlibに関する覚書

python初心者にありがたいわかりやすい日本語記事がこちら。
bicycle1885.hatenablog.com

Python 配列の形式メモ

c++Pythonを行ったり来たりしていると頭が混乱してきます。

どれがどれ?

基本は以下の3つ。

  • ()がtuple
  • []がlist
  • {}がdict

これらに加えてnumpyのarrayとmatrixがよく使う奴らでしょう。

とりあえず名前さえわかればGoogle先生に聞くことができるので
最低限どんなオブジェクトを対象にしているのか知っておきましょう。

以下にあまりわかり易くなかったTutorialも載せておきます
Lesson 6 - Tuples, Lists, and Dictionaries

各々の違い

  • list :
  • tuple :要素を変更できないlist
  • dict :文字通り辞書。

Pythonのこれらの配列は型の異なる値を代入可能です。
すごいけどそのせいで時々エラーを見逃しちゃったり...

あと、Printした時のnumpyのarrayとlistの出力はとても似通っています。

listのlist的表現

よく出てくるのはこういうやつらです。[({の形からどのタイプのファイルか確認できます。
私は現状、Printした時に横に並ぶのがlistで縦に並ぶのがarrayと覚えています。

[[0. 0.],[1. 1.],[2. 2.]] #こっちがlistのlist

[[0. 0.]
 [1. 1.]
 [2. 2.]] # np.array

初期化と要素へのアクセス

よく使う機能をまとめます。

  • 長さを取得するlen()はtuple,list,dict全てに使えます。

list

[]でアクセスします。もちろん0から。

list = [2005, 2006, 2007, 2008] #初期化
list[0] #最初の要素へのアクセス

リストオブジェクト - リスト - Python入門

tuple

listに準じます。

tuple = (2005, 2006, 2007, 2008) #初期化
tuple[0] #最初の要素へのアクセス

タプル - Python入門

dict

数字が名前になっただけです。

dict = {"yamada":75, "endou":82} #初期化
value =  dict["yamada"] #yamadaへのアクセス

2次元配列とかの対処

以下を見てください。なんてことないでしょう?

list = [10, [20, 16], [32, 34], 18]
list[1] # [20, 16] が左から2番めの要素
list[1][0] # 20 が[20,16]の1番目の要素

各種変換

実際numpy arrayとの変換とかが一番使う気もします。
まぁおいおい追記しましょう。

tuple と list 相互変換

tuple(list)
list(tuple)

numpy arrayとlist 相互変換

これはよく使うと思います。

a = [1, 2]
np.asarray(a) # array
b = np.array([1, 2])
b.tolist() # list

練 習 問 題

Q1.以下の配列の構造を答えよ

a=[(2228.739013671875, 1203.9490966796875), (2898.794189453125, 1092.8704833984375), (3060.037353515625, 852.7973022460938)

Q2.上のaを以下のbへと変換するコードを書け

print(b)
[[[[ 2228.73901367  1203.94909668]
   [ 2898.79418945  1092.8704834 ]
   [ 3060.03735352   852.79730225]]]]


Ans:

b=np.array([[a]])

使用例

OpenCVでcalcOpticalFlowPyrLK()関数へとKeyPointsに渡すときに使います。

Passing ORB Features to calcOpticalFlowPyrLK - OpenCV Q&A Forum