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-tools
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のソースをダウンロードする
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 build
cd build
Xサーバの場所を指定する
export DISPLAY=192.168.1.7:0.0
CMsakeを起動する
cmake-gui
ソースがある場所とバイナリを出力する場所を次のように指定する。必要と思われるコンポーネントを選んでConfigure → Generateする。
コンパイルとインストールCMakeで選択したコンポーネントに依るが4時間ぐらいはかかる(^^;)
make
sudo 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/pkgconfig
export 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 argument
USBデバイスとして認識しているし、さらにv4lもビデオデバイスとしても認識しているのになぜ???
$ lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 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-id
total 0
lrwxrwxrwx 1 root root 12 Sep 13 09:17 usb-046d_0825_E52302F0-video-index0 -> ../../video0
UVCクラスのカメラをテストする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 0
Using camera #0
Camera : /dev/video0
Driver name : uvcvideo
Driver Version : 3.1.9
Device name : UVC Camera (046d:0825)
Bus information : usb-bcm2708_usb-1.2.1
Capabilities : 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) : OK
Ctrl 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 : 00000000h
Ctrl 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 : 00000000h
Ctrl 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 : 00000000h
Ctrl 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 : 00000000h
Ctrl 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 : 00000000h
Ctrl 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 : 00000000h
Ctrl 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 : 00000000h
Ctrl 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 : 00000000h
Ctrl 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 : 00000000h
Ctrl 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 Mode
VIDIOC_QUERYMENU: Invalid argument ★
3 : Aperture Priority Mode
Min,Max,Step,Default : 0,3,1,0
Flags : 00000000h
Ctrl 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 : 00000000h
Ctrl 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 : 00000000h
Image 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/5
Image 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を介して接続しなおしてみた。
$ lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 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 Hub
Bus 001 Device 005: ID 046d:0825 Logitech, Inc. Webcam C270
$ ls -l /dev/v4l/*
/dev/v4l/by-id:
total 0
lrwxrwxrwx 1 root root 12 Jan 1 1970 usb-046d_0825_E52302F0-video-index0 -> ../../video0
/dev/v4l/by-path:
total 0
lrwxrwxrwx 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
$ lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 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 Hub
Bus 001 Device 010: ID 046d:08b2 Logitech, Inc. QuickCam Pro 4000
$ lsmod
Module Size Used by
pwc 75411 0
videobuf2_vmalloc 2117 1 pwc
videobuf2_memops 2592 1 videobuf2_vmalloc
videobuf2_core 19232 1 pwc
gspca_zc3xx 39599 0
gspca_main 20979 1 gspca_zc3xx
snd_bcm2835 21505 0
snd_usb_audio 97984 0
snd_usbmidi_lib 19388 1 snd_usb_audio
snd_hwdep 6406 1 snd_usb_audio
snd_seq_midi 4958 0
evdev 9470 1
snd_seq_midi_event 7409 1 snd_seq_midi
snd_rawmidi 22731 2 snd_seq_midi,snd_usbmidi_lib
snd_pcm 80650 2 snd_usb_audio,snd_bcm2835
snd_page_alloc 5347 1 snd_pcm
snd_seq 59372 2 snd_seq_midi_event,snd_seq_midi
snd_seq_device 6916 3 snd_seq,snd_rawmidi,snd_seq_midi
snd_timer 21638 2 snd_seq,snd_pcm
snd 57253 9 snd_timer,snd_seq_device,snd_seq,snd_pcm,snd_rawmidi,snd_hwdep,snd_usbmidi_lib,snd_usb_audio,snd_bcm2835
uvcvideo 64055 0
videodev 97717 3 uvcvideo,gspca_main,pwc
$ ls -l /dev/v4l/*
/dev/v4l/by-id:
total 0
lrwxrwxrwx 1 root root 12 Sep 13 17:36 usb-046d_08b2-video-index0 -> ../../video0
/dev/v4l/by-path:
total 0
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++のプログラムを作って動かしてみた。
#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)