Raspberry Pi で OpenCV

Raspbery Pi (2012-08-16-wheezy-raspbian)にOpenCV-2.4.2をインストールしてデモを動かしてみた。そして、自分でも簡単なプログラムを作って動かしてみた。

なおX画面は、HDMIディスプレイではなくWindowsマシン上にXminingというXサーバーを立てて、Windows画面上に表示させた。

ターミナルは、UART端子にUART-USB変換基板(FT232RX 3.3V)を介してパソコンに接続し、TeraTermで表示させた。(115200bps,8N1)

パッケージ情報の更新

  1. sudo apt-get update

必要なパッケージをインストール

  1. sudo apt-get -y install build-essential cmake cmake-qt-gui pkg-config libpng12-0 libpng12-dev libpng++-dev libpng3 libpnglite-dev zlib1g-dbg zlib1g zlib1g-dev pngtools libtiff4-dev libtiff4 libtiffxx0c2 libtiff-tools
  2. sudo apt-get -y install libjpeg8 libjpeg8-dev libjpeg8-dbg libjpeg-progs ffmpeg libavcodec-dev libavcodec53 libavformat53 libavformat-dev libgstreamer0.10-0-dbg libgstreamer0.10-0 libgstreamer0.10-dev libxine1-ffmpeg libxine-dev libxine1-bin libunicap2 libunicap2-dev libdc1394-22-dev libdc1394-22 libdc1394-utils swig libv4l-0 libv4l-dev python-numpy libpython2.6 python-dev python2.6-dev libgtk2.0-dev pkg-config

OpenCVのソースをダウンロードする

  1. wget http://sourceforge.net/projects/opencvlibrary/files/opencv-unix/2.4.2/OpenCV-2.4.2.tar.bz2

ホーム(/home/pi)に解凍する

  1. tar -xvjpf OpenCV-2.4.2.tar.bz2

ビルド用ディレクトリを作る

  1. cd OpenCV-2.4.2/
  2. mkdir build
  3. cd build

Xサーバの場所を指定する

  1. export DISPLAY=192.168.1.7:0.0

CMsakeを起動する

  1. cmake-gui

ソースがある場所とバイナリを出力する場所を次のように指定する。必要と思われるコンポーネントを選んでConfigure → Generateする。

コンパイルとインストールCMakeで選択したコンポーネントに依るが4時間ぐらいはかかる(^^;)

  1. make
  2. sudo make install

テキストエディタで次の空ファイルに一行追加

  1. sudo nano /etc/ld.so.conf.d/opencv.conf
  2. --------------
  3. /usr/local/lib
  4. --------------
テキストエディタで次のファイルの最後に2行追加
  1. sudo nano /etc/bash.bashrc
  2. --------------
  3.     :
  4. PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig
  5. export PKG_CONFIG_PATH
  6. ---------------

まず、OpenCV-2.4.2/samples/pythonの中にあるカメラを使わないサンプルから、、、

chessboard.py

chessboard.py

contours.py

contours.py

convexhull.py

convexhull.py

delaunay.py (1)

delaunay.py (1)

delaunay.py (2)

delaunay.py (2)

drawing.py

drawing.py

kalman.py

kalman.py

minarea.py

minarea.py

pyramid_segmentation.py

pyramid_segmentation.py

次に、ウェブカメラを接続してみる。使用したカメラは、Logicool HD Webcam C270だ。Pythonによるカメラ映像を表示するだけのサンプルを動かしてみた。

  1. $ cd OpenCV-2.4.2/samples/python
  2. $ python camera.py

しかし、次のようなメッセージが表示され、真っ黒な画面が表示されるだけ。

  1. VIDIOC_QUERYMENU: Invalid argument

USBデバイスとして認識しているし、さらにv4lもビデオデバイスとしても認識しているのになぜ???

  1. $ lsusb
  2. Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
  3. Bus 001 Device 002: ID 0424:9512 Standard Microsystems Corp.
  4. Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
  5. Bus 001 Device 005: ID 046d:0825 Logitech, Inc. Webcam C270
  6. $ ls -l /dev/v4l/by-id
  7. total 0
  8. lrwxrwxrwx 1 root root 12 Sep 13 09:17 usb-046d_0825_E52302F0-video-index0 -> ../../video0

UVCクラスのカメラをテストするluvcviewをインストールして確かめてみた。

  1. $ sudo apt-get -yV install luvcview
  2. $ luvcview

すると、問題なく表示した。

調べてみると、どうやらこのメッセージは、v4l(Video For Linux)のドライバが表示しているらしい。もう少し詳しく調べるために、次のページを参考にさせていただいた。

http://saibara.sakura.ne.jp/program/v4l2/

http://linuxtv.org/downloads/v4l-dvb-apis/

試しに、ここで公開されているlistup.cをコンパイルして実行してみた。

  1. $ gcc -o listup listup.c
  2. $ ./listup 0
  3. Using camera #0
  4. Camera : /dev/video0
  5. Driver name : uvcvideo
  6. Driver Version : 3.1.9
  7. Device name : UVC Camera (046d:0825)
  8. Bus information : usb-bcm2708_usb-1.2.1
  9. Capabilities : 04000001h
  10. V4L2_CAP_VIDEO_CAPTURE (Video Capture) : OK
  11. V4L2_CAP_VIDEO_OUTPUT (Video Output) : Not supported.
  12. V4L2_CAP_VIDEO_OVERLAY (Video Overlay) : Not supported.
  13. V4L2_CAP_VBI_CAPTURE (Raw VBI Capture) : Not supported.
  14. V4L2_CAP_VBI_OUTPUT (Raw VBI Output) : Not supported.
  15. V4L2_CAP_SLICED_VBI_CAPTURE (Sliced VBI Capture) : Not supported.
  16. V4L2_CAP_SLICED_VBI_OUTPUT (Sliced VBI Output) : Not supported.
  17. V4L2_CAP_RDS_CAPTURE (Undefined.[to be defined]) : Not supported.
  18. V4L2_CAP_VIDEO_OUTPUT_OVERLAY (Video Output Overlay (OSD)) : Not supported.
  19. V4L2_CAP_TUNER (Tuner) : Not supported.
  20. V4L2_CAP_AUDIO (Audio inputs or outputs) : Not supported.
  21. V4L2_CAP_RADIO (Radio receiver) : Not supported.
  22. V4L2_CAP_READWRITE (Read/write() I/O method) : Not supported.
  23. V4L2_CAP_ASYNCIO (Asynchronous I/O method) : Not supported.
  24. V4L2_CAP_STREAMING (Streaming I/O method) : OK
  25. Ctrl id(CID) : 00980900h (V4L2_CID_BRIGHTNESS)
  26. Ctrl name : Brightness
  27. Ctrl type : 1 (V4L2_CTRL_TYPE_INTEGER)
  28. Min,Max,Step,Default : 0,255,1,-8193
  29. Flags : 00000000h
  30. Ctrl id(CID) : 00980901h (V4L2_CID_CONTRAST)
  31. Ctrl name : Contrast
  32. Ctrl type : 1 (V4L2_CTRL_TYPE_INTEGER)
  33. Min,Max,Step,Default : 0,255,1,57343
  34. Flags : 00000000h
  35. Ctrl id(CID) : 00980902h (V4L2_CID_SATURATION)
  36. Ctrl name : Saturation
  37. Ctrl type : 1 (V4L2_CTRL_TYPE_INTEGER)
  38. Min,Max,Step,Default : 0,255,1,57343
  39. Flags : 00000000h
  40. Ctrl id(CID) : 0098090ch (V4L2_CID_AUTO_WHITE_BALANCE)
  41. Ctrl name : White Balance Temperature, Auto
  42. Ctrl type : 2 (V4L2_CTRL_TYPE_BOOLEAN)
  43. Min,Max,Step,Default : 0,1,1,1
  44. Flags : 00000000h
  45. Ctrl id(CID) : 00980913h (V4L2_CID_GAIN)
  46. Ctrl name : Gain
  47. Ctrl type : 1 (V4L2_CTRL_TYPE_INTEGER)
  48. Min,Max,Step,Default : 0,255,1,57343
  49. Flags : 00000000h
  50. Ctrl id(CID) : 00980918h (V4L2_CID_POWER_LINE_FREQUENCY)
  51. Ctrl name : Power Line Frequency
  52. Ctrl type : 3 (V4L2_CTRL_TYPE_MENU)
  53. Menu items:
  54. 0 : Disabled
  55. 1 : 50 Hz
  56. 2 : 60 Hz
  57. Min,Max,Step,Default : 0,2,1,2
  58. Flags : 00000000h
  59. Ctrl id(CID) : 0098091ah (V4L2_CID_WHITE_BALANCE_TEMPERATURE)
  60. Ctrl name : White Balance Temperature
  61. Ctrl type : 1 (V4L2_CTRL_TYPE_INTEGER)
  62. Min,Max,Step,Default : 0,10000,10,61432
  63. Flags : 00000000h
  64. Ctrl id(CID) : 0098091bh (V4L2_CID_SHARPNESS)
  65. Ctrl name : Sharpness
  66. Ctrl type : 1 (V4L2_CTRL_TYPE_INTEGER)
  67. Min,Max,Step,Default : 0,255,1,57343
  68. Flags : 00000000h
  69. Ctrl id(CID) : 0098091ch (V4L2_CID_BACKLIGHT_COMPENSATION)
  70. Ctrl name : Backlight Compensation
  71. Ctrl type : 1 (V4L2_CTRL_TYPE_INTEGER)
  72. Min,Max,Step,Default : 0,1,1,57343
  73. Flags : 00000000h
  74. Ctrl id(CID) : 009a0901h (V4L2_CID_EXPOSURE_AUTO)
  75. Ctrl name : Exposure, Auto
  76. Ctrl type : 3 (V4L2_CTRL_TYPE_MENU)
  77. Menu items:
  78. VIDIOC_QUERYMENU: Invalid argument ★
  79. 1 : Manual Mode
  80. VIDIOC_QUERYMENU: Invalid argument ★
  81. 3 : Aperture Priority Mode
  82. Min,Max,Step,Default : 0,3,1,0
  83. Flags : 00000000h
  84. Ctrl id(CID) : 009a0902h (V4L2_CID_EXPOSURE_ABSOLUTE)
  85. Ctrl name : Exposure (Absolute)
  86. Ctrl type : 1 (V4L2_CTRL_TYPE_INTEGER)
  87. Min,Max,Step,Default : 1,10000,1,166
  88. Flags : 00000000h
  89. Ctrl id(CID) : 009a0903h (V4L2_CID_EXPOSURE_AUTO_PRIORITY)
  90. Ctrl name : Exposure, Auto Priority
  91. Ctrl type : 2 (V4L2_CTRL_TYPE_BOOLEAN)
  92. Min,Max,Step,Default : 0,1,1,0
  93. Flags : 00000000h
  94. Image format #0 : YUYV (YUV 4:2:2 (YUYV))
  95. 0: (160 x 120) 1/15 1/10 1/5
  96. 1: (176 x 144) 1/15 1/10 1/5
  97. Image format #1 : MJPG (MJPEG)
  98. 0: (640 x 480) 1/30 1/25 1/20 1/15 1/10 1/5
  99. 1: (160 x 120) 1/30 1/25 1/20 1/15 1/10 1/5
  100. 2: (176 x 144) 1/30 1/25 1/20 1/15 1/10 1/5
  101. 3: (320 x 176) 1/30 1/25 1/20 1/15 1/10 1/5
  102. 4: (320 x 240) 1/30 1/25 1/20 1/15 1/10 1/5
  103. 5: (352 x 288) 1/30 1/25 1/20 1/15 1/10 1/5
  104. 6: (432 x 240) 1/30 1/25 1/20 1/15 1/10 1/5
  105. 7: (544 x 288) 1/30 1/25 1/20 1/15 1/10 1/5
  106. 8: (640 x 360) 1/30 1/25 1/20 1/15 1/10 1/5
  107. 9: (752 x 416) 1/15 1/10 1/5
  108. 10: (800 x 448) 1/15 1/10 1/5
  109. 11: (800 x 600) 1/15 1/10 1/5

、、がやはり同じメッセージが表示される。V4L2_CID_EXPOSURE_AUTO(自動露出)は、ドライバーのソースプログラムvideodev2.hで次のように定義されている。

  1. #define V4L2_CID_EXPOSURE_AUTO (V4L2_CID_CAMERA_CLASS_BASE+1)
  2. enum v4l2_exposure_auto_type {
  3.     V4L2_EXPOSURE_MANUAL = 0,
  4.     V4L2_EXPOSURE_AUTO = 1,
  5.     V4L2_EXPOSURE_SHUTTER_PRIORITY = 2,
  6.     V4L2_EXPOSURE_APERTURE_PRIORITY = 3
  7. };

このカメラは、この自動露出に対して次の2つについて正しい値を返さないということか?

V4L2_EXPOSURE_MANUAL (手動)

V4L2_EXPOSURE_SHUTTER_PRIORITY (シャッター速度優先)

  1. if(0 == ioctl (fd, VIDIOC_QUERYMENU, &querymenu))
  2.     {
  3.      printf ("\t\t %d : %s\n", querymenu.index,querymenu.name);
  4.     }
  5. else
  6.     {
  7.      perror ("VIDIOC_QUERYMENU"); ★
  8. //     exit (EXIT_FAILURE);
  9.     }

よくわからないoz、手詰まりである。ネットで調べると同輩がいるようであるが、これといった解決策は見当たらない。もしや!?と思いこのUSBカメラをHUBを介して接続しなおしてみた。

  1. $ lsusb
  2. Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
  3. Bus 001 Device 002: ID 0424:9512 Standard Microsystems Corp.
  4. Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
  5. Bus 001 Device 004: ID 0451:2046 Texas Instruments, Inc. TUSB2046 Hub
  6. Bus 001 Device 005: ID 046d:0825 Logitech, Inc. Webcam C270
  7. $ ls -l /dev/v4l/*
  8. /dev/v4l/by-id:
  9. total 0
  10. lrwxrwxrwx 1 root root 12 Jan 1 1970 usb-046d_0825_E52302F0-video-index0 -> ../../video0
  11. /dev/v4l/by-path:
  12. total 0
  13. lrwxrwxrwx 1 root root 12 Jan 1 1970 platform-bcm2708_usb-usb-0:1.3.3:1.0-video-index0 -> ../../video0

すると、同じエラーは表示されるものの、Pythonのサンプルが表示するようになった。

camera.py

camera.py

laplace.py

laplace.py

/OpenCV-2.4.2/build/bin/にあるCの顔認識のサンプルfacedetectも動いた。3fpsぐらいで処理している。なぜ、表示される画像のサイズが小さいのかは不明である。

じゃぁ、別なカメラではどうだろうか?Logitech, Inc. QuickCam Pro 4000で試してみた。年代物のカメラである。このカメラはUVCクラスではないので、ドライバーがあるかどうか?でも、そんな心配をよそに、pwcドライバとgspcaドライバがちゃんと入っていたのである(^^)v

  1. $ dmesg
  2.    :
  3. [ 1363.388036] usb 1-1.3.4: USB disconnect, device number 9
  4. [ 1365.417119] usb 1-1.3.2: new full speed USB device number 10 using dwc_otg
  5. [ 1365.612796] usb 1-1.3.2: New USB device found, idVendor=046d, idProduct=08b2
  6. [ 1365.612842] usb 1-1.3.2: New USB device strings: Mfr=0, Product=0, SerialNumber=0
  7. [ 1365.620054] pwc: Logitech QuickCam 4000 Pro USB webcam detected.
  8. [ 1366.096976] pwc: Registered as video0.
  9. [ 1366.097402] input: PWC snapshot button as /devices/platform/bcm2708_usb/usb1/1-1/1-1.3/1-1.3.2/input/input5
  10. $ lsusb
  11. Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
  12. Bus 001 Device 002: ID 0424:9512 Standard Microsystems Corp.
  13. Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
  14. Bus 001 Device 004: ID 0451:2046 Texas Instruments, Inc. TUSB2046 Hub
  15. Bus 001 Device 010: ID 046d:08b2 Logitech, Inc. QuickCam Pro 4000
  16. $ lsmod
  17. Module Size Used by
  18. pwc 75411 0
  19. videobuf2_vmalloc 2117 1 pwc
  20. videobuf2_memops 2592 1 videobuf2_vmalloc
  21. videobuf2_core 19232 1 pwc
  22. gspca_zc3xx 39599 0
  23. gspca_main 20979 1 gspca_zc3xx
  24. snd_bcm2835 21505 0
  25. snd_usb_audio 97984 0
  26. snd_usbmidi_lib 19388 1 snd_usb_audio
  27. snd_hwdep 6406 1 snd_usb_audio
  28. snd_seq_midi 4958 0
  29. evdev 9470 1
  30. snd_seq_midi_event 7409 1 snd_seq_midi
  31. snd_rawmidi 22731 2 snd_seq_midi,snd_usbmidi_lib
  32. snd_pcm 80650 2 snd_usb_audio,snd_bcm2835
  33. snd_page_alloc 5347 1 snd_pcm
  34. snd_seq 59372 2 snd_seq_midi_event,snd_seq_midi
  35. snd_seq_device 6916 3 snd_seq,snd_rawmidi,snd_seq_midi
  36. snd_timer 21638 2 snd_seq,snd_pcm
  37. snd 57253 9 snd_timer,snd_seq_device,snd_seq,snd_pcm,snd_rawmidi,snd_hwdep,snd_usbmidi_lib,snd_usb_audio,snd_bcm2835
  38. uvcvideo 64055 0
  39. videodev 97717 3 uvcvideo,gspca_main,pwc
  40. $ ls -l /dev/v4l/*
  41. /dev/v4l/by-id:
  42. total 0
  43. lrwxrwxrwx 1 root root 12 Sep 13 17:36 usb-046d_08b2-video-index0 -> ../../video0
  44. /dev/v4l/by-path:
  45. total 0
  46. lrwxrwxrwx 1 root root 12 Sep 13 17:36 platform-bcm2708_usb-usb-0:1.3.2:1.0-video-index0 -> ../../video0

というわけで、このカメラもOKだった。こちらも3pfsぐらいで処理している様子。

この顔認識のサンプルをHDMIディスプレイにつないで行ってみたが、HUBやマウス、キーボードの接続によってかなり動作が不安定になった。

最後に、次のような簡単な輪郭抽出のC++のプログラムを作って動かしてみた。

  1. #include <opencv2/opencv.hpp>
  2. #include <iostream>
  3. using namespace std;
  4. using namespace cv;
  5. int main(int argc, char * argv[])
  6. {
  7.     cv::VideoCapture cap(0);
  8.     cap.set(CV_CAP_PROP_FRAME_WIDTH, 640);
  9.     cap.set(CV_CAP_PROP_FRAME_HEIGHT, 480);
  10.     if(cap.isOpened() == false)
  11.     {
  12.         cout << "Device not found" << endl;
  13.         return -1;
  14.     }
  15.     for(;;)
  16.     {
  17.         cv::Mat frame, gray, canny;
  18.         cap >> frame;
  19.         cv::cvtColor(frame, gray, CV_BGR2GRAY);
  20.         cv::Canny(gray, canny, 70, 150);
  21.         cv::imshow("Hello OpenCV [frame]", frame);
  22.         cv::imshow("Hello OpenCV [canny]", canny);
  23.         if(cv::waitKey(33) >= 0) break;
  24.     }
  25.     return 0;
  26. }

結局、Raspberry PiのUSBポートが供給できる電流が足りないことが、今回のカメラのトラブルの原因ではないだろうか?だとすれば、この現象は当然ながらキーボードやマウスなど他のUSB機器でも起こるはずだし、実際そのようなトラブルが発生しているようだ。USBカメラはUSB機器の中でもとりわけ電流を消費するので、今回のような現象が起こっても不思議はない。いずれにせよ、Rspberry PiのUSBポートへの直挿しは注意が必要なことは確かのようだ。http://elinux.org/Rpi_Hardware#Power_Supply_Problemsこのページに、Raspberry Piの電源に関する注意点について詳しく述べられている。この中で、2つのUSBポートにはそれぞれ140mAのポリフューズ(ポリスイッチ)が接続されているので、接続する機器はこの値以上の電流を流さないようにするべきだと言っている。公開されている回路図を見ると確かに140mA のポリスイッチTyco miniSMDC014が入っている。今回の現象は、USBカメラによる過電流がこのポリスイッチによって遮断されたことが直接の原因だろう。

USBまわり回路図

 

ちなみに、この回路図から、USB給電の過電流がこのポリスイッチによって遮断されたことを、USB+LANコントローラ SMC LAN9512 によって検出していることもわかった。(SMC LAN9512 データシート P.18)

2012年09月15日