2018年6月21日木曜日

OpenCV Viz の Widgetのサンプル(その1)

OpenCVのVizにはどんなWidgetがあるのか?確認してみる。
3Dスキャナーで計算した3次元の点をOpenCVのVizで表示するための下準備。
チュートリアルにないものを抜粋。
ここを見れば良い。
https://docs.opencv.org/3.4.1/d1/d19/group__viz.html

全3回

WAllow(矢印)

始点、終点、太さを指定する。
 auto arrow = cv::viz::WArrow(cv::Point3d(1, 0, 0),        // 始点
                               cv::Point3d(1, 1, 0),        // 終点
                               0.01,                         // 太さ
                               cv::viz::Color::amethyst());  // 色
  myWindow.showWidget("Arrow", arrow);↲         


WCircle(円)

半径、中心座標、平面の法線、太さを指定する。
塗りつぶしたいときは、半径を半分にして、太さを半径と同じ値にする。
  auto circle = cv::viz::WCircle(1.0,                         // 半径
                                 cv::Point3d(0.0 ,0.0, 0.0),  // 中心
                                 cv::Vec3b(1.0, 0.0, 0.0),    // 平面の法線
                                 0.01,                        // 太さ
                                 cv::viz::Color::celestial_blue());
  myWindow.showWidget("Circle", circle);



WCone(円柱)

長さ、中心座標、先端座標、円の解像度を指定。
  auto cone = cv::viz::WCone(0.5,                     // 長さ
                             cv::Point3d(-1, -1, -1), // 中心
                             cv::Point3d(-2, -2, -2), // 先端
                             12,                           // 円の解像度(何角型か)
                             cv::viz::Color::chartreuse());
  myWindow.showWidget("Cone", cone);


WCylinder(円柱)

始点、終点、半径、円の解像度を指定。
両端は閉じていないので、WCricleを描画してあげる必要がある。
   auto cylinder = cv::viz::WCylinder(cv::Point3d(2.0, 2.0, 2.0),  // 始点
                                     cv::Point3d(3.0, 2.0, 2.0),  // 終点
                                     1.0, // 半径
                                     30,  // 円の解像度(何角型か)
                                     cv::viz::Color::maroon());
  myWindow.showWidget("Cylinder", cylinder);


WGrid(グリッド)

グリッドの平面を描画。
中心座標、平面の法線、Y軸の方向、グリットのマス目、グリット間の距離を指定。
  auto grid = cv::viz::WGrid(cv::Point3d(0.0, 0.0, 0.0),  // 中心座標
                             cv::Vec3d(-1.0, 1.0, 0.0),   // 平面の法線
                             cv::Vec3d(0.0, 1.0, 0.0),    // Y軸の方向
                             cv::Vec2i(10, 10),           // グリッドのマス目
                             cv::Vec2d(0.2, 0.2),         // グリッド間の距離
                             cv::viz::Color::lime());
  myWindow.showWidget("Grid", grid);


続く。

2018年6月17日日曜日

YOLOv3をFedora28+CUDAで動かしてみる

YOLOv3

YOLOとは、state-of-the-artsなリアルタイム一般物体認識。
詳細の説明は割愛。
今回は、Fedora28でYOLOv3を試そうとしたときにつまずいたポイントを紹介。

Fedora28でつまずいたポイント

darknetのビルドで、OPENCV、CUDAを有効とすると、ビルドエラーが発生。
環境は以下
  • CPU AMD Ryzen 7 1700
  • GPU NVIDIA GeForce GTX 1070
  • OS Fedora 28 
  • GCC 8.1.1
  • CUDA 9.1
  • OpenCV 3.4.1(ソースビルド)
ビルドエラーの内容と解決した方法について解説。
解決方法は公式の手順ではないので注意。

OpenCV

MakefileのOPENCVを有効にしてビルドすると、ビルドエラーが発生。
$ make
gcc -Iinclude/ -Isrc/ -DOPENCV `pkg-config --cflags opencv`  -DGPU -I/usr/local/cuda/include/ -DCUDNN  -Wall -Wno-unused-result -Wno-unknown-pragmas -Wfatal-errors -fPIC -Ofast -DOPENCV -DGPU -DCUDNN -c ./src/gemm.c -o obj/gemm.o
In file included from /usr/local/include/opencv2/core/types_c.h:59,
                 from /usr/local/include/opencv2/core/core_c.h:48,
                 from /usr/local/include/opencv2/highgui/highgui_c.h:45,
                 from include/darknet.h:25,
                 from ./src/utils.h:5,
                 from ./src/gemm.c:2:
/usr/local/include/opencv2/core/cvdef.h:485:1: エラー: 不明な型名 ‘namespace’ です
 namespace cv {
 ^~~~~~~~~
-Wfatal-errors によりコンパイルを停止しました。
make: *** [Makefile:85: obj/gemm.o] エラー 1

原因は、darknetはOpenCVのC言語IFを呼び出しているが、OpenCV3系はC言語IFはサポートしなくなったためらしい。。。(ほんと?)
みんな、コンパイルできなくて困っている。。。
https://github.com/pjreddie/darknet/issues/485
https://github.com/opencv/opencv/issues/10963

解決方法

OpenCV2系をビルド・インストール
以下から2.4.13.6のソースをダウンロードしていつもどおりビルド。
https://github.com/opencv/opencv/releases/tag/2.4.13.6

ビルドする際の注意
あとは、darknetのMakefileでpkg-configでopencvを指定している箇所をopencv2に変更してビルドすればOK。


CUDA

CUDAのhost compilerはGCC 6以下がサポートしており、Fedora 28のGCC 8はサポートしていない。このため、CUDAを有効としてビルドするとビルドエラーが発生する。
In file included from /usr/local/cuda/include/host_config.h:50,
                 from /usr/local/cuda/include/cuda_runtime.h:78,
                 from <コマンドライン>:
/usr/local/cuda/include/crt/host_config.h:121:2: エラー: #error -- unsupported GNU version! gcc versions later than 6 are not supported!
 #error -- unsupported GNU version! gcc versions later than 6 are not supported!
  ^~~~~

解決方法

host compilerにGCC 6以下を指定する。
MakefileのNVCC=nvccに-ccbinオプションでコンパイラを指定。
gccは5.5をソースビルドしたものを使用。

結果

darknetのサンプルファイル"data/kite.jpg"で確認


Model
Build option
Prediction time
(seconds)
Prediction time
(milliseconds)
FPS
GPUCUDAOPENMP
YOLOv31100.03365633.729.7
YOLOv3-tiny 1100.0062996.3158.8
YOLOv30007.9802647980.30.1
YOLOv3-tiny 0000.729358729.41.4
YOLOv30012.3087572308.80.4
YOLOv3-tiny 0010.286995287.03.5
GPUありのYOLOv3で約30fps。早い!

2018年4月14日土曜日

OpenCVでビデオキャプチャが遅く感じるとき

事象

OpenCVでビデオキャプチャの画像を表示すると遅くなる場合がある。
例えば、このようなコードを書いたときに遅くなる(Python, C++に関係なく発生する)。
以下はPythonコード。

cap = cv2.VideoCapture(0)
while (True):
    ret, frame = cap.read()

    # 何か重い処理

    cv2.imshow("camera", frame)
    key = cv2.waitKey(1) & 0xff
    if key == 27:
        break

原因

これは、OpenCVはキャプチャした画像はバッファリングしているが、重い処理が原因で常にバッファの一番最後の画像を取得してしまうので遅くなってしまう(タイムラグが発生してしまう)。

解決方法

ビデオキャプチャのループ処理は設定したビデオキャプチャで指定したFPS内で処理できるようにすること。つまり、重い処理をしてはいけない。
どうしても重い処理を行うのであれば、

  • ビデオキャプチャのFPSを下げる(CV_CAP_PROP_FPSを指定)
  • ビデオキャプチャのループと何か重い処理を別スレッドにする(処理しないフレームが発生する)
のいずれかが必要。これは「何か重い処理」の内容を見極めて対応する必要がある。

2018年3月24日土曜日

Open3Dを動かしてみる

最近、話題のOpen3Dをビルドしてみた。
DesktopPC(Ryzen 1700)とRaspberry pi 3で動作させてみた。

ビルド方法

チュートリアルに書かれてある通りにビルド
$ git clone https://github.com/IntelVCL/Open3D
$ ./scripts/install-deps-ubuntu.sh
$ mkdir build
$ cd build
$ cmake ../src
$ make -j

Tutorial/Basicのコードを動かしてみる

Raspberry pi 3の場合、画面が重くてほとんど動かない。表示もおかしい。
チュートリアルのコードを実行すると
GLFW Error: X11: RandR gamma ramp support seems broken
が出力されているのでOpenGL?の問題もありそう。

手持ちの環境(Ryzen1700 と Raspberry pi 3)で処理時間を比較してみる。
処理時間の計測はPython3のtime.perf_counter()を使用。単位はすべて秒

rgbd_redwood.py


Open3D python apiRyzen 1700Raspberry pi 3
create_rgbd_image_from_color_and_depth0.0031308780.035566293
create_point_cloud_from_rgbd_image0.0031308780.146715472

rgbd_odometry.py


Open3D python apiRyzen 1700Raspberry pi 3
compute_rgbd_odometry(using RGB-D Odometery)0.7698600583.41303919
compute_rgbd_odometry(using Hybrid RGB-D Odometery)0.7833153363.615518965

odometeryの結果、RtはRyzen, Raspberry pi 3とも一致。
Ryzenの場合
Using RGB-D Odometry
[[ 9.99985161e-01 -2.24233601e-04 -5.44316453e-03 -4.82515882e-04]
 [ 1.46064327e-04  9.99896920e-01 -1.43571495e-02  2.89043658e-02]
 [ 5.44582281e-03  1.43561414e-02  9.99882115e-01  7.88078866e-04]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00  1.00000000e+00]]
Using Hybrid RGB-D Odometry
[[ 9.99994666e-01 -1.00290832e-03 -3.10826679e-03 -3.75410519e-03]
 [ 9.64494137e-04  9.99923448e-01 -1.23356688e-02  2.54977515e-02]
 [ 3.12040039e-03  1.23326051e-02  9.99919082e-01  1.88139777e-03]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00  1.00000000e+00]]
Raspberry pi 3の場合
[[ 9.99985161e-01 -2.24233601e-04 -5.44316453e-03 -4.82515882e-04]
 [ 1.46064327e-04  9.99896920e-01 -1.43571495e-02  2.89043658e-02]
 [ 5.44582281e-03  1.43561414e-02  9.99882115e-01  7.88078866e-04]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00  1.00000000e+00]]
Using Hybrid RGB-D Odometry
[[ 9.99994666e-01 -1.00290832e-03 -3.10826679e-03 -3.75410519e-03]
 [ 9.64494137e-04  9.99923448e-01 -1.23356688e-02  2.54977515e-02]
 [ 3.12040039e-03  1.23326051e-02  9.99919082e-01  1.88139777e-03]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00  1.00000000e+00]]

pointcloud.py


Open3D python apiRyzen 1700Raspberry pi 3
voxel_down_sample0.0153782820.136582671
estimate_normals0.0052679820.085729508
crop_point_cloud0.0284832150.285484762
paint_uniform_color0.0001464830.00105934

kdtree.py


Open3D python apiRyzen 1700Raspberry pi 3
KDTreeFlann0.0005339760.00671003
search_knn_vector_3d0.0000498730.000483227
search_radius_vector_3d0.0000223110.000134426

icp_registration.py


Open3D python apiRyzen 1700Raspberry pi 3
evaluate_registration0.0733231261.06074374
registration_icp
(point-to-point ICP)
1.19398570718.54412634
registration_icp
(point-to-plane ICP)
1.13801447217.36850839

Raspberry pi 3の場合、ほとんど表示されない(黒い点の集合だけ)。

いや、もっとPoint Couldのことを覚えないと。。。

2018年2月16日金曜日

Fedora27にNVIDIA driverとcudaをインストール


概要

NVIDIAのドライバーはFedoraには25しか提供されていない。Fedora 27にインストールしたい場合は、25のものを使用すれば良い。オフィシャルのパッケージを手動で入れるか、rpmfusionなどのレポジトリから導入する手順がある。
今回は、rpmfusionのレポジトリからインストールした。
https://rpmfusion.org/Howto/NVIDIA

なお、rpmfusionやcudaのレポジトリからインストールした場合は、セキュアブートを無効にしないとドライバがロードできない。セキュアブートを有効にしたい場合は手動のインストールが必要。自分の環境では、DKMSでエラーとなってしまうことからrpmfusionのレポジトリからインストールすることにした。

事前の確認

まず、HW情報を確認。
(自分の環境は Ryzen 1700 + Gforce 1070)
$ /sbin/lspci | grep -e VGA
28:00.0 VGA compatible controller: NVIDIA Corporation GP104 [GeForce GTX 1070] (rev a1)


rpmfusionのレポジトリを登録

sudo dnf install https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm https://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm

ディスプレイドライバのインストール

sudo dnf install xorg-x11-drv-nvidia akmod-nvidia
sudo dnf update


cudaのインストール

cudaのレポジトリを登録する。
オフィシャルページのFedora25のrpm[network]をダウンロード&インストールする
https://developer.nvidia.com/cuda-downloads
sudo dnf install cuda

注意

cudaとrpmfusionのレポジトリでドライバが競合してしまうため、インストール後はcudaのレポジトリは無効にしておいたほうがよい(excludeを指定すればよい)

2017年11月12日日曜日

Opencv 3.3.1 Viz - Fedora 26

OpenCV 3.3.1にバージョンアップしたら、vizのチュートリアルが動作しないことがわかった。ビルドしたときの環境は下記。

環境

  • Fedora 26
  • OpenCV 3.3.1
  • Cuda 9
  • VTK 7 (パッケージをインストール)
vizのチュートリアルを動作させるとVTKモジュールでエラーとなっている模様。
Shader object was not initialized, cannot attach it.

ググるとOpenGLが初期化されていない???
NVIDIAの新しいOpenGLのバージョンだとVTK 7 が対応できていないための模様。
バグチケットにも登録されていた。
https://bugzilla.redhat.com/show_bug.cgi?id=1496287

解決方法

VTK 7 はあきらめて、VTK 8をソースからビルドして、OpenCVを再ビルドした。
結果、vizのチュートリアルが動作できた。

2017年11月5日日曜日

Bash on Windows で yocto (はできなかった)

Windows10のBash on Windowsでyoctoがビルドできるかなと思ってチャレンジ。
(ubuntuだし、できるかも?と淡い期待をもってみた)
yoctoの公式Documentの通り、パッケージをインストール後、Raspberry pi3のBasicイメージでビルド。
ビルドするとエラーとなってしまう。autoreconf m4? 見慣れないエラー。。。

$ bitbake rpi-hwup-image
Parsing recipes: 100% |##################################################################################| Time: 0:00:23
Parsing of 1987 .bb files complete (0 cached, 1987 parsed). 2778 targets, 109 skipped, 0 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies
Build Configuration:
BB_VERSION        = "1.35.0"
BUILD_SYS         = "x86_64-linux"
NATIVELSBSTRING   = "universal"
TARGET_SYS        = "arm-poky-linux-gnueabi"
MACHINE           = "raspberrypi3"
DISTRO            = "poky"
DISTRO_VERSION    = "2.4"
TUNE_FEATURES     = "arm armv7ve vfp thumb neon vfpv4 callconvention-hard cortexa7"
TARGET_FPU        = "hard"
meta
meta-poky
meta-yocto-bsp    = "master:65d23bd7986615fdfb0f1717b615534a2a14ab80"
meta-oe
meta-multimedia
meta-python
meta-networking   = "master:0d220e002e4f525469f0c24e0585318d2178e7a1"
meta-raspberrypi  = "master:a1cfeb3324c458a73507e34ffcf28c25591b8052"
WARNING: The Linux kernel on your build host was not configured to provide process I/O statistics. (CONFIG_TASK_IO_ACCOUNTING is not set)
Initialising tasks: 100% |###############################################################################| Time: 0:00:05
NOTE: Executing SetScene Tasks
NOTE: Executing RunQueue Tasks
ERROR: libtool-native-2.4.6-r0 do_configure: autoreconf execution failed.
ERROR: libtool-native-2.4.6-r0 do_configure: Function failed: do_configure (log file is located at /home/xxxx/rpi3/rpi-build/tmp/work/x86_64-linux/libtool-native/2.4.6-r0/temp/log.do_configure.222)
ERROR: Logfile of failure stored in: /home/xxxx/rpi3/rpi-build/tmp/work/x86_64-linux/libtool-native/2.4.6-r0/temp/log.do_configure.222
Log data follows:
| DEBUG: Executing shell function autotools_preconfigure
| DEBUG: Shell function autotools_preconfigure finished
| DEBUG: Executing python function autotools_aclocals
| DEBUG: SITE files ['endian-little', 'common-linux', 'common-glibc', 'bit-64', 'x86_64-linux', 'common']
| DEBUG: Python function autotools_aclocals finished
| DEBUG: Executing shell function do_configure
| automake (GNU automake) 1.15.1
| Copyright (C) 2017 Free Software Foundation, Inc.
| License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl-2.0.html>;
| This is free software: you are free to change and redistribute it.
| There is NO WARRANTY, to the extent permitted by law.
|
| Written by Tom Tromey <tromey@redhat.com>
|        and Alexandre Duret-Lutz <adl@gnu.org>.
| AUTOV is 1.15
| NOTE: Executing ACLOCAL="aclocal --system-acdir=/home/xxxx/rpi3/rpi-build/tmp/work/x86_64-linux/libtool-native/2.4.6-r0/recipe-sysroot-native/usr/share/aclocal/ --automake-acdir=/home/xxxx/rpi3/rpi-build/tmp/work/x86_64-linux/libtool-native/2.4.6-r0/recipe-sysroot-native/usr/share/aclocal-1.15" autoreconf --verbose --install --force --exclude=libtoolize -I /home/xxxx/rpi3/rpi-build/tmp/work/x86_64-linux/libtool-native/2.4.6-r0/libtool-2.4.6/m4/ -I /home/xxxx/rpi3/rpi-build/tmp/work/x86_64-linux/libtool-native/2.4.6-r0/libtool-2.4.6/tests/
| autoreconf: Entering directory `.'
| autoreconf: configure.ac: not using Gettext
| autoreconf: running: aclocal --system-acdir=/home/xxxx/rpi3/rpi-build/tmp/work/x86_64-linux/libtool-native/2.4.6-r0/recipe-sysroot-native/usr/share/aclocal/ --automake-acdir=/home/xxxx/rpi3/rpi-build/tmp/work/x86_64-linux/libtool-native/2.4.6-r0/recipe-sysroot-native/usr/share/aclocal-1.15 -I /home/xxxx/rpi3/rpi-build/tmp/work/x86_64-linux/libtool-native/2.4.6-r0/libtool-2.4.6/m4/ -I /home/xxxx/rpi3/rpi-build/tmp/work/x86_64-linux/libtool-native/2.4.6-r0/libtool-2.4.6/tests/ --force -I m4
| m4: ../sysdeps/unix/sysv/linux/spawni.c:368: __spawnix: Assertion `ec >= 0' failed.
| m4: internal error detected; please report this bug to <bug-m4@gnu.org>: Aborted
| autom4te: m4 failed with exit status: 2
| aclocal: error: echo failed with exit status: 2
| autoreconf: aclocal failed with exit status: 2
| ERROR: autoreconf execution failed.
| WARNING: exit code 1 from a shell command.
| ERROR: Function failed: do_configure (log file is located at /home/xxxx/rpi3/rpi-build/tmp/work/x86_64-linux/libtool-native/2.4.6-r0/temp/log.do_configure.222)
ERROR: Task (/home/xxxx/rpi3/poky/meta/recipes-devtools/libtool/libtool-native_2.4.6.bb:do_configure) failed with exit code '1'
NOTE: Tasks Summary: Attempted 559 tasks of which 525 didn't need to be rerun and 1 failed.
Summary: 1 task failed:
  /home/xxxx/rpi3/poky/meta/recipes-devtools/libtool/libtool-native_2.4.6.bb:do_configure
Summary: There was 1 WARNING message shown.
Summary: There were 2 ERROR messages shown, returning a non-zero exit code.

どうやらBash on Windowsではglibcが完全に動作しないことが原因らしい。
https://github.com/Microsoft/WSL/issues/1878
(Bash on Windowsでyoctoを試そうとする人は他にもいたみたい。。。)