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)
パッケージ情報の更新
sudo apt-get update必要なパッケージをインストール
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-toolssudo 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-configOpenCVのソースをダウンロードする
wget http://sourceforge.net/projects/opencvlibrary/files/opencv-unix/2.4.2/OpenCV-2.4.2.tar.bz2ホーム(/home/pi)に解凍する
tar -xvjpf OpenCV-2.4.2.tar.bz2ビルド用ディレクトリを作る
cd OpenCV-2.4.2/mkdir buildcd buildXサーバの場所を指定する
export DISPLAY=192.168.1.7:0.0CMsakeを起動する
cmake-guiソースがある場所とバイナリを出力する場所を次のように指定する。必要と思われるコンポーネントを選んでConfigure → Generateする。
コンパイルとインストールCMakeで選択したコンポーネントに依るが4時間ぐらいはかかる(^^;)
makesudo make installテキストエディタで次の空ファイルに一行追加
sudo nano /etc/ld.so.conf.d/opencv.conf--------------/usr/local/lib--------------sudo nano /etc/bash.bashrc-------------- :PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfigexport PKG_CONFIG_PATH---------------まず、OpenCV-2.4.2/samples/pythonの中にあるカメラを使わないサンプルから、、、
chessboard.py
contours.py
convexhull.py
delaunay.py (1)
delaunay.py (2)
drawing.py
kalman.py
minarea.py
pyramid_segmentation.py
次に、ウェブカメラを接続してみる。使用したカメラは、Logicool HD Webcam C270だ。Pythonによるカメラ映像を表示するだけのサンプルを動かしてみた。
$ cd OpenCV-2.4.2/samples/python$ python camera.pyしかし、次のようなメッセージが表示され、真っ黒な画面が表示されるだけ。
VIDIOC_QUERYMENU: Invalid argumentUSBデバイスとして認識しているし、さらにv4lもビデオデバイスとしても認識しているのになぜ???
$ lsusbBus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hubBus 001 Device 002: ID 0424:9512 Standard Microsystems Corp.Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.Bus 001 Device 005: ID 046d:0825 Logitech, Inc. Webcam C270$ ls -l /dev/v4l/by-idtotal 0lrwxrwxrwx 1 root root 12 Sep 13 09:17 usb-046d_0825_E52302F0-video-index0 -> ../../video0UVCクラスのカメラをテストするluvcviewをインストールして確かめてみた。
$ sudo apt-get -yV install luvcview$ luvcviewすると、問題なく表示した。
調べてみると、どうやらこのメッセージは、v4l(Video For Linux)のドライバが表示しているらしい。もう少し詳しく調べるために、次のページを参考にさせていただいた。
http://saibara.sakura.ne.jp/program/v4l2/
http://linuxtv.org/downloads/v4l-dvb-apis/
試しに、ここで公開されているlistup.cをコンパイルして実行してみた。
$ gcc -o listup listup.c$ ./listup 0Using camera #0Camera : /dev/video0Driver name : uvcvideoDriver Version : 3.1.9Device name : UVC Camera (046d:0825)Bus information : usb-bcm2708_usb-1.2.1Capabilities : 04000001h V4L2_CAP_VIDEO_CAPTURE (Video Capture) : OK V4L2_CAP_VIDEO_OUTPUT (Video Output) : Not supported. V4L2_CAP_VIDEO_OVERLAY (Video Overlay) : Not supported. V4L2_CAP_VBI_CAPTURE (Raw VBI Capture) : Not supported. V4L2_CAP_VBI_OUTPUT (Raw VBI Output) : Not supported. V4L2_CAP_SLICED_VBI_CAPTURE (Sliced VBI Capture) : Not supported. V4L2_CAP_SLICED_VBI_OUTPUT (Sliced VBI Output) : Not supported. V4L2_CAP_RDS_CAPTURE (Undefined.[to be defined]) : Not supported. V4L2_CAP_VIDEO_OUTPUT_OVERLAY (Video Output Overlay (OSD)) : Not supported. V4L2_CAP_TUNER (Tuner) : Not supported. V4L2_CAP_AUDIO (Audio inputs or outputs) : Not supported. V4L2_CAP_RADIO (Radio receiver) : Not supported. V4L2_CAP_READWRITE (Read/write() I/O method) : Not supported. V4L2_CAP_ASYNCIO (Asynchronous I/O method) : Not supported. V4L2_CAP_STREAMING (Streaming I/O method) : OKCtrl id(CID) : 00980900h (V4L2_CID_BRIGHTNESS) Ctrl name : Brightness Ctrl type : 1 (V4L2_CTRL_TYPE_INTEGER) Min,Max,Step,Default : 0,255,1,-8193 Flags : 00000000hCtrl id(CID) : 00980901h (V4L2_CID_CONTRAST) Ctrl name : Contrast Ctrl type : 1 (V4L2_CTRL_TYPE_INTEGER) Min,Max,Step,Default : 0,255,1,57343 Flags : 00000000hCtrl id(CID) : 00980902h (V4L2_CID_SATURATION) Ctrl name : Saturation Ctrl type : 1 (V4L2_CTRL_TYPE_INTEGER) Min,Max,Step,Default : 0,255,1,57343 Flags : 00000000hCtrl id(CID) : 0098090ch (V4L2_CID_AUTO_WHITE_BALANCE) Ctrl name : White Balance Temperature, Auto Ctrl type : 2 (V4L2_CTRL_TYPE_BOOLEAN) Min,Max,Step,Default : 0,1,1,1 Flags : 00000000hCtrl id(CID) : 00980913h (V4L2_CID_GAIN) Ctrl name : Gain Ctrl type : 1 (V4L2_CTRL_TYPE_INTEGER) Min,Max,Step,Default : 0,255,1,57343 Flags : 00000000hCtrl id(CID) : 00980918h (V4L2_CID_POWER_LINE_FREQUENCY) Ctrl name : Power Line Frequency Ctrl type : 3 (V4L2_CTRL_TYPE_MENU) Menu items: 0 : Disabled 1 : 50 Hz 2 : 60 Hz Min,Max,Step,Default : 0,2,1,2 Flags : 00000000hCtrl id(CID) : 0098091ah (V4L2_CID_WHITE_BALANCE_TEMPERATURE) Ctrl name : White Balance Temperature Ctrl type : 1 (V4L2_CTRL_TYPE_INTEGER) Min,Max,Step,Default : 0,10000,10,61432 Flags : 00000000hCtrl id(CID) : 0098091bh (V4L2_CID_SHARPNESS) Ctrl name : Sharpness Ctrl type : 1 (V4L2_CTRL_TYPE_INTEGER) Min,Max,Step,Default : 0,255,1,57343 Flags : 00000000hCtrl id(CID) : 0098091ch (V4L2_CID_BACKLIGHT_COMPENSATION) Ctrl name : Backlight Compensation Ctrl type : 1 (V4L2_CTRL_TYPE_INTEGER) Min,Max,Step,Default : 0,1,1,57343 Flags : 00000000hCtrl id(CID) : 009a0901h (V4L2_CID_EXPOSURE_AUTO) Ctrl name : Exposure, Auto Ctrl type : 3 (V4L2_CTRL_TYPE_MENU) Menu items:VIDIOC_QUERYMENU: Invalid argument ★ 1 : Manual ModeVIDIOC_QUERYMENU: Invalid argument ★ 3 : Aperture Priority Mode Min,Max,Step,Default : 0,3,1,0 Flags : 00000000hCtrl id(CID) : 009a0902h (V4L2_CID_EXPOSURE_ABSOLUTE) Ctrl name : Exposure (Absolute) Ctrl type : 1 (V4L2_CTRL_TYPE_INTEGER) Min,Max,Step,Default : 1,10000,1,166 Flags : 00000000hCtrl id(CID) : 009a0903h (V4L2_CID_EXPOSURE_AUTO_PRIORITY) Ctrl name : Exposure, Auto Priority Ctrl type : 2 (V4L2_CTRL_TYPE_BOOLEAN) Min,Max,Step,Default : 0,1,1,0 Flags : 00000000hImage format #0 : YUYV (YUV 4:2:2 (YUYV)) 0: (160 x 120) 1/15 1/10 1/5 1: (176 x 144) 1/15 1/10 1/5Image format #1 : MJPG (MJPEG) 0: (640 x 480) 1/30 1/25 1/20 1/15 1/10 1/5 1: (160 x 120) 1/30 1/25 1/20 1/15 1/10 1/5 2: (176 x 144) 1/30 1/25 1/20 1/15 1/10 1/5 3: (320 x 176) 1/30 1/25 1/20 1/15 1/10 1/5 4: (320 x 240) 1/30 1/25 1/20 1/15 1/10 1/5 5: (352 x 288) 1/30 1/25 1/20 1/15 1/10 1/5 6: (432 x 240) 1/30 1/25 1/20 1/15 1/10 1/5 7: (544 x 288) 1/30 1/25 1/20 1/15 1/10 1/5 8: (640 x 360) 1/30 1/25 1/20 1/15 1/10 1/5 9: (752 x 416) 1/15 1/10 1/5 10: (800 x 448) 1/15 1/10 1/5 11: (800 x 600) 1/15 1/10 1/5、、がやはり同じメッセージが表示される。V4L2_CID_EXPOSURE_AUTO(自動露出)は、ドライバーのソースプログラムvideodev2.hで次のように定義されている。
#define V4L2_CID_EXPOSURE_AUTO (V4L2_CID_CAMERA_CLASS_BASE+1)enum v4l2_exposure_auto_type { V4L2_EXPOSURE_MANUAL = 0, V4L2_EXPOSURE_AUTO = 1, V4L2_EXPOSURE_SHUTTER_PRIORITY = 2, V4L2_EXPOSURE_APERTURE_PRIORITY = 3};このカメラは、この自動露出に対して次の2つについて正しい値を返さないということか?
V4L2_EXPOSURE_MANUAL (手動)
V4L2_EXPOSURE_SHUTTER_PRIORITY (シャッター速度優先)
if(0 == ioctl (fd, VIDIOC_QUERYMENU, &querymenu)) { printf ("\t\t %d : %s\n", querymenu.index,querymenu.name); } else { perror ("VIDIOC_QUERYMENU"); ★// exit (EXIT_FAILURE); }よくわからないoz、手詰まりである。ネットで調べると同輩がいるようであるが、これといった解決策は見当たらない。もしや!?と思いこのUSBカメラをHUBを介して接続しなおしてみた。
$ lsusbBus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hubBus 001 Device 002: ID 0424:9512 Standard Microsystems Corp.Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.Bus 001 Device 004: ID 0451:2046 Texas Instruments, Inc. TUSB2046 HubBus 001 Device 005: ID 046d:0825 Logitech, Inc. Webcam C270$ ls -l /dev/v4l/*/dev/v4l/by-id:total 0lrwxrwxrwx 1 root root 12 Jan 1 1970 usb-046d_0825_E52302F0-video-index0 -> ../../video0/dev/v4l/by-path:total 0lrwxrwxrwx 1 root root 12 Jan 1 1970 platform-bcm2708_usb-usb-0:1.3.3:1.0-video-index0 -> ../../video0すると、同じエラーは表示されるものの、Pythonのサンプルが表示するようになった。
camera.py
laplace.py
/OpenCV-2.4.2/build/bin/にあるCの顔認識のサンプルfacedetectも動いた。3fpsぐらいで処理している。なぜ、表示される画像のサイズが小さいのかは不明である。
じゃぁ、別なカメラではどうだろうか?Logitech, Inc. QuickCam Pro 4000で試してみた。年代物のカメラである。このカメラはUVCクラスではないので、ドライバーがあるかどうか?でも、そんな心配をよそに、pwcドライバとgspcaドライバがちゃんと入っていたのである(^^)v
$ dmesg :[ 1363.388036] usb 1-1.3.4: USB disconnect, device number 9[ 1365.417119] usb 1-1.3.2: new full speed USB device number 10 using dwc_otg[ 1365.612796] usb 1-1.3.2: New USB device found, idVendor=046d, idProduct=08b2[ 1365.612842] usb 1-1.3.2: New USB device strings: Mfr=0, Product=0, SerialNumber=0[ 1365.620054] pwc: Logitech QuickCam 4000 Pro USB webcam detected.[ 1366.096976] pwc: Registered as video0.[ 1366.097402] input: PWC snapshot button as /devices/platform/bcm2708_usb/usb1/1-1/1-1.3/1-1.3.2/input/input5$ lsusbBus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hubBus 001 Device 002: ID 0424:9512 Standard Microsystems Corp.Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.Bus 001 Device 004: ID 0451:2046 Texas Instruments, Inc. TUSB2046 HubBus 001 Device 010: ID 046d:08b2 Logitech, Inc. QuickCam Pro 4000$ lsmodModule Size Used bypwc 75411 0videobuf2_vmalloc 2117 1 pwcvideobuf2_memops 2592 1 videobuf2_vmallocvideobuf2_core 19232 1 pwcgspca_zc3xx 39599 0gspca_main 20979 1 gspca_zc3xxsnd_bcm2835 21505 0snd_usb_audio 97984 0snd_usbmidi_lib 19388 1 snd_usb_audiosnd_hwdep 6406 1 snd_usb_audiosnd_seq_midi 4958 0evdev 9470 1snd_seq_midi_event 7409 1 snd_seq_midisnd_rawmidi 22731 2 snd_seq_midi,snd_usbmidi_libsnd_pcm 80650 2 snd_usb_audio,snd_bcm2835snd_page_alloc 5347 1 snd_pcmsnd_seq 59372 2 snd_seq_midi_event,snd_seq_midisnd_seq_device 6916 3 snd_seq,snd_rawmidi,snd_seq_midisnd_timer 21638 2 snd_seq,snd_pcmsnd 57253 9 snd_timer,snd_seq_device,snd_seq,snd_pcm,snd_rawmidi,snd_hwdep,snd_usbmidi_lib,snd_usb_audio,snd_bcm2835uvcvideo 64055 0videodev 97717 3 uvcvideo,gspca_main,pwc$ ls -l /dev/v4l/*/dev/v4l/by-id:total 0lrwxrwxrwx 1 root root 12 Sep 13 17:36 usb-046d_08b2-video-index0 -> ../../video0/dev/v4l/by-path:total 0lrwxrwxrwx 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++のプログラムを作って動かしてみた。
#include <opencv2/opencv.hpp>#include <iostream>using namespace std;using namespace cv;int main(int argc, char * argv[]){ cv::VideoCapture cap(0); cap.set(CV_CAP_PROP_FRAME_WIDTH, 640); cap.set(CV_CAP_PROP_FRAME_HEIGHT, 480); if(cap.isOpened() == false) { cout << "Device not found" << endl; return -1; } for(;;) { cv::Mat frame, gray, canny; cap >> frame; cv::cvtColor(frame, gray, CV_BGR2GRAY); cv::Canny(gray, canny, 70, 150); cv::imshow("Hello OpenCV [frame]", frame); cv::imshow("Hello OpenCV [canny]", canny); if(cv::waitKey(33) >= 0) break; } return 0;}
結局、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)