ラズパイにつけるUSBカメラについて調べてみました。
ラズパイには公式カメラモジュールとUSBカメラをつけることができて、複数台のカメラを搭載することができます。ただし、全部をフルパワー全開で利用するには、電源的にもCPU的にもディスクアクセス的にも厳しいものがあったりするので、用途に応じて切り替えをしながら使う必要があります。きちんと使うためには、いろいろ調べとかないとなぁ、と思ったのがきっかけです。
ということで、手元にUSBカメラが4台あったので、それぞれ1台ずつラズパイにつけてみました。それについて簡単に調べたことを記録しておきます。UVC(USB video device classまたはUSB video class)対応のカメラであれば認識して使えるようです。
目次
Logicool C270
まず、定番の「LOGICOOL ウェブカム HD画質 120万画素 C270 」です。これは優秀でラズパイへつけると普通に使えます。値段も安くていいですよね。
USBデバイスが認識されているかを調べるにはlsusbを使います。C270の場合は、下記のようにすればわかります。
$ lsusb | grep C270 Bus 001 Device 005: ID 046d:0825 Logitech, Inc. Webcam C270
ここではC270というキーワードがわかっているのでgrepを使ってますが、キーワードがわからないデバイスの場合は、デバイスをつける前後でlsusbコマンドを実行して追加されたものが何かで判断します。
それで、USBカメラのデバイスが認識されていると、/dev/video0が使えるようになります。複数台のUSBカメラをつけると、/dev/video1、/dev/video2と増えていきます。
昔のラズパイの場合はバスパワーでUSBカメラを使おうとすると電力不足になることがありました。Raspberry Pi 3だと1台ぐらいなら大丈夫なようですが、複数台つける場合は動作が不安定になることもありえるので、セルフパワーのUSB HUBを用意するなどして対応が必要なこともあるという認識はしておいたほうが良いでしょう。
カメラの解像度
カメラが対応している解像度については、lsusbの「-v」オプションで表示できます。同時に「-s」オプションで「Bus:Device」の値を指定する必要があります。情報はたくさん出てくるので、grepでWidthで絞って、その前後1行を表示すると見やすくなります。整理すると、さっきのC270の情報から「Bus」が「001」で「Device」が「005」とわかるので、C270の対応する解像度を取得する実際のコマンドは下記になります。
$ lsusb -s 001:005 -v | grep -1 Width
fswebcam
画像取得用コマンドとして有名なのはfswebcamで、追加インストールが必要です。使うには、保存するファイル名を指定します。コマンドラインで実行できるので、モニタにつないでないラズパイでは重宝します。
$ sudo apt-get -y install fswebcam $ fswebcam 001.jpg
カメラによっては初期処理に時間がかかる場合があり、撮影開始まで遅延させたほうが良い場合があります。その場合は「-D」を使います。
$ fswebcam -D 2 snap.jpg
カメラによっては最初に何回か撮影をすることで各種パラメータが調整されるものがあり、その場合は「-S」を使って調整をします。
$ fswebcam -S 10 snap.jpg
luvcviewなど
luvcviewを使うとカメラのプレビューを見ることができます。コマンドラインでUSBカメラの情報を取得できて便利なので、uvccapture と uvcdynctrlも一緒にインストールしておくと良いでしょう。uvcdynctrlで設定を保存したり読み込んだりできますが、その設定ファイルは後で紹介するguvcviewの設定ファイルと互換性があるようです。
$ sudo apt-get -y install luvcview uvccapture uvcdynctrl $ luvcview
uvcdynctrlのオプションについて、ヘルプは「-h」、デバイス一覧表示が「-l」です。利用可能なコントロール一覧は「-d」でデバイスを指定して「-c」、詳細を知りたいなら「-v」を追加とします。利用可能なフォーマット一覧は「-f」を指定します。
$ uvcdynctrl -h $ uvcdynctrl -l $ uvcdynctrl -d video0 -c $ uvcdynctrl -d video0 -c -v $ uvcdynctrl -f
個別に値を取得したり、設定するには、それぞれ「-g」、「-s」を使います。例えば「$ uvcdynctrl -d video0 -c 」でBrightnessがコントロールできるなら、下記のように使います。例では現在値が128のところを40に設定しなおしてます。
$ uvcdynctrl -d video0 -g "Brightness" 128 $ uvcdynctrl -d video0 -s "Brightness" 40
uvccaptureを使うと写真撮影ができて、snap.jpgに保存できます。「-o」でファイル名指定もできます。空白をいれずにファイル名を指定します。「-v」は詳細情報の出力です。エラーが出たときの確認に使えます。カメラによっては動作しませんでした。
$ uvccapture -m -v $ uvccapture -m -v -osnapshot.jpg
guvcviewなど
luvcviewだと写真撮影や動画撮影が大変なので、そういうことをしたい場合は、GUI版の guvcview を使います。インストールをするとメニューの「サウンドとビデオ」-「guvcview」から使えるようになります。
$ sudo apt-get -y install guvcview
起動するとカメラの自動調整をしてくれるようです。このあと紹介するDigio2やELECOM UCAM-C0220FBNWHも写真撮影に使えました。
設定値はメニューの「Settings」-「Save」で保存できます。保存した設定値は「Settings」-「Load」で利用できます。
v4l-utils
v4l-utilsは、Webカメラ用のユーティリティを提供するもので、libv4lで利用可能な独自のフォーマットを処理し、V4Lデバイスをテストするためのツールが含まれているようです。最初からインストールされているようですが、ない場合は次のようにしてインストールできます。
$ sudo apt-get -y install v4l-utils
これに含まれるv4l2-ctlコマンドを実行すると、利用可能なデバイスの一覧を表示することができます。
$ v4l2-ctl --list-devices
明るさ、ズーム、フォーカスなどは、v4l2-ctlで調整できます。すべてのコントロールとそのメニューを表示するには、「-L」を使います。
$ v4l2-ctl -L
値を調整するには、「-c」を使います。
$ v4l2-ctl -c <option> = <value>
C270を使った場合の結果を入れておきます。UVCカメラとして認識されています。
$ v4l2-ctl --list-devices UVC Camera (046d:0825) (usb-3f980000.usb-1.4): /dev/video0 $ v4l2-ctl -L brightness (int) : min=0 max=255 step=1 default=-8193 value=128 contrast (int) : min=0 max=255 step=1 default=57343 value=32 saturation (int) : min=0 max=255 step=1 default=57343 value=32 white_balance_temperature_auto (bool) : default=1 value=1 gain (int) : min=0 max=255 step=1 default=57343 value=64 power_line_frequency (menu) : min=0 max=2 default=2 value=2 0: Disabled 1: 50 Hz 2: 60 Hz white_balance_temperature (int) : min=0 max=10000 step=10 default=61432 value=4000 flags=inactive sharpness (int) : min=0 max=255 step=1 default=57343 value=24 backlight_compensation (int) : min=0 max=1 step=1 default=57343 value=0 exposure_auto (menu) : min=0 max=3 default=0 value=3 1: Manual Mode 3: Aperture Priority Mode exposure_absolute (int) : min=1 max=10000 step=1 default=166 value=166 flags=inactive exposure_auto_priority (bool) : default=0 value=1 brightness (int) : min=0 max=255 step=1 default=-8193 value=128 contrast (int) : min=0 max=255 step=1 default=57343 value=32 saturation (int) : min=0 max=255 step=1 default=57343 value=32 white_balance_temperature_auto (bool) : default=1 value=1 gain (int) : min=0 max=255 step=1 default=57343 value=64 power_line_frequency (menu) : min=0 max=2 default=2 value=2 0: Disabled 1: 50 Hz 2: 60 Hz white_balance_temperature (int) : min=0 max=10000 step=10 default=61432 value=4000 flags=inactive sharpness (int) : min=0 max=255 step=1 default=57343 value=24 backlight_compensation (int) : min=0 max=1 step=1 default=57343 value=0
ロアス Digio2
「Digio2 UVC対応リアル130万画素超小型スティックPCカメラ ホワイト MCM-14W 」もつけてみました。Amazonだと結構な値段がしますが、延長ケーブルつきでラズパイにもコンパクトにつけることができるので、人気があるのでしょうか。
lsusbコマンドの実行結果は次の通りです。
$ lsusb|grep Z-Star Bus 001 Device 009: ID 0ac8:0332 Z-Star Microelectronics Corp.
fswebcamコマンドだと色がおかしくなります。オプションの「-S」を使って撮影すると良くなりました。
guvcviewで見ると調整がされて使えました。guvcviewの「Settings」-「Save Profile」で保存できる設定ファイルは下記のようになりました。ファイル名はdigio2.gpflで保存してみました。
$ cat digio2.gpfl #V4L2/CTRL/0.0.2 APP{"guvcview 2.0.1"} # control data #Brightness ID{0x00980900};CHK{-16:16:1:-8193}=VAL{2} #Contrast ID{0x00980901};CHK{1:32:1:57343}=VAL{16} #Saturation ID{0x00980902};CHK{0:15:1:57343}=VAL{4} #Hue ID{0x00980903};CHK{-45:45:1:-8193}=VAL{0} #White Balance Temperature, Auto ID{0x0098090c};CHK{0:1:1:1}=VAL{1} #Gamma ID{0x00980910};CHK{100:200:10:61432}=VAL{190} #Gain ID{0x00980913};CHK{64:64:1:57343}=VAL{64} #Power Line Frequency ID{0x00980918};CHK{0:2:1:1}=VAL{1} #Sharpness ID{0x0098091b};CHK{0:15:1:57343}=VAL{1} #Backlight Compensation ID{0x0098091c};CHK{0:1:1:57343}=VAL{0} #Exposure, Auto ID{0x009a0901};CHK{0:3:1:0}=VAL{3} #Exposure, Auto Priority ID{0x009a0903};CHK{0:1:1:0}=VAL{1}
「Settings」-「Hardware Default」とすると、輝度が -16 になったり、色相が -45 になったり、ガンマが 200 になったりと、いろいろとおかしな値になります。ですから、最初にguvcviewを起動して自動調整で良い感じになっていたら「Settings」-「Save Profile」して設定を保存しておき、問題が起きたら「Settings」-「Load Profile」で設定をロードしなおすのが良いようです。
コマンドから使う場合のカメラ設定については、uvcdynctrlを使えばいいかと思って、設定をしてみたりしたのですが、uvccaptureもfswebcamもuvcdynctrlで設定した値を使ってくれないようでうまく写真撮影ができませんでした。
GUIアプリを使える環境なら、guvcviewを使えばいいのですが、fswebcamコマンドなどを使いたい場合は「-S」で調整して使うことになりそうです。motionやMJPG Streamerでどうなるかまでは見てませんが、動画系だと自動調整がうまく入って大丈夫なのだと思います。
v4l-ctlコマンドの結果では、USB 2.0 カメラとして認識されています。
$ v4l2-ctl --list-devices USB 2.0 Camera (usb-3f980000.usb-1.4): /dev/video0 $ v4l2-ctl -L brightness (int) : min=-16 max=16 step=1 default=-8193 value=2 contrast (int) : min=1 max=32 step=1 default=57343 value=16 saturation (int) : min=0 max=15 step=1 default=57343 value=4 hue (int) : min=-45 max=45 step=1 default=-8193 value=0 white_balance_temperature_auto (bool) : default=1 value=1 gamma (int) : min=100 max=200 step=10 default=61432 value=190 gain (int) : min=64 max=64 step=1 default=57343 value=64 power_line_frequency (menu) : min=0 max=2 default=1 value=1 0: Disabled 1: 50 Hz 2: 60 Hz white_balance_temperature (int) : min=2800 max=6500 step=1850 default=11693 value=6500 flags=inactive sharpness (int) : min=0 max=15 step=1 default=57343 value=3 backlight_compensation (int) : min=0 max=1 step=1 default=57343 value=0 exposure_auto (menu) : min=0 max=3 default=0 value=3 1: Manual Mode 3: Aperture Priority Mode exposure_absolute (int) : min=2 max=20 step=2 default=4 value=4 flags=inactive exposure_auto_priority (bool) : default=0 value=1 brightness (int) : min=-16 max=16 step=1 default=-8193 value=2 contrast (int) : min=1 max=32 step=1 default=57343 value=16 saturation (int) : min=0 max=15 step=1 default=57343 value=4 hue (int) : min=-45 max=45 step=1 default=-8193 value=0 white_balance_temperature_auto (bool) : default=1 value=1 gamma (int) : min=100 max=200 step=10 default=61432 value=190 gain (int) : min=64 max=64 step=1 default=57343 value=64 power_line_frequency (menu) : min=0 max=2 default=1 value=1 0: Disabled 1: 50 Hz 2: 60 Hz white_balance_temperature (int) : min=2800 max=6500 step=1850 default=11693 value=6500 flags=inactive sharpness (int) : min=0 max=15 step=1 default=57343 value=3 backlight_compensation (int) : min=0 max=1 step=1 default=57343 value=0
値の変更はuvcdynctrlでもいいと思いますが、v4l2-ctlでもできます。
$ v4l2-ctl -c brightness=2 $ v4l2-ctl -c contrast=16 $ v4l2-ctl -c saturation=4 $ v4l2-ctl -c hue=0 $ v4l2-ctl -L
ELECOM UCAM-C0220FBNWH
「エレコム WEBカメラ 200万画素 マイク内蔵 MAC対応 ホワイト UCAM-C0220FBNWH 」もつけてみました。
lsusbコマンドの実行結果は次の通りです。
$ lsusb|grep Elecom Bus 001 Device 006: ID 056e:7016 Elecom Co., Ltd
こちらもfswebcamで写真を撮影すると緑色がかってしまいます。オプションの「-S」を使って撮影すると良くなりました。
guvcviewの「Settings」-「Save Profile」で保存できる設定ファイルは下記のようになりました。ファイル名はelecom_ucam-c0220fbnwh.gpflで保存してみました。
$ cat elecom_ucam-c0220fbnwh.gpfl #V4L2/CTRL/0.0.2 APP{"guvcview 2.0.1"} # control data #Brightness ID{0x00980900};CHK{-127:127:1:-8193}=VAL{0} #Contrast ID{0x00980901};CHK{0:127:1:57343}=VAL{64} #Saturation ID{0x00980902};CHK{0:255:1:57343}=VAL{64} #Hue ID{0x00980903};CHK{-16000:16000:1:-8193}=VAL{0} #White Balance Temperature, Auto ID{0x0098090c};CHK{0:1:1:1}=VAL{1} #Gamma ID{0x00980910};CHK{16:500:1:57343}=VAL{100} #Power Line Frequency ID{0x00980918};CHK{0:2:1:1}=VAL{1} #Sharpness ID{0x0098091b};CHK{0:63:1:57343}=VAL{10} #Exposure, Auto ID{0x009a0901};CHK{0:3:1:0}=VAL{3} #Exposure, Auto Priority ID{0x009a0903};CHK{0:1:1:0}=VAL{64}
v4l2-ctlコマンドでの結果も記載しておきます。UCAM-C0220Fと表示されていました。
$ v4l2-ctl --list-devices UCAM-C0220F (usb-3f980000.usb-1.4): /dev/video0 $ v4l2-ctl -L brightness (int) : min=-127 max=127 step=1 default=-8193 value=0 contrast (int) : min=0 max=127 step=1 default=57343 value=64 saturation (int) : min=0 max=255 step=1 default=57343 value=64 hue (int) : min=-16000 max=16000 step=1 default=-8193 value=0 white_balance_temperature_auto (bool) : default=1 value=1 gamma (int) : min=16 max=500 step=1 default=57343 value=100 power_line_frequency (menu) : min=0 max=2 default=1 value=1 0: Disabled 1: 50 Hz 2: 60 Hz white_balance_temperature (int) : min=2800 max=6500 step=1 default=57343 value=5200 flags=inactive sharpness (int) : min=0 max=63 step=1 default=57343 value=10 exposure_auto (menu) : min=0 max=3 default=0 value=3 1: Manual Mode 3: Aperture Priority Mode exposure_absolute (int) : min=1 max=5000 step=1 default=625 value=625 flags=inactive error 5 getting ext_ctrl Exposure, Auto Priority brightness (int) : min=-127 max=127 step=1 default=-8193 value=0 contrast (int) : min=0 max=127 step=1 default=57343 value=64 saturation (int) : min=0 max=255 step=1 default=57343 value=64 hue (int) : min=-16000 max=16000 step=1 default=-8193 value=0 white_balance_temperature_auto (bool) : default=1 value=1 gamma (int) : min=16 max=500 step=1 default=57343 value=100 power_line_frequency (menu) : min=0 max=2 default=1 value=1 0: Disabled 1: 50 Hz 2: 60 Hz white_balance_temperature (int) : min=2800 max=6500 step=1 default=57343 value=5200 flags=inactive sharpness (int) : min=0 max=63 step=1 default=57343 value=10
詳細不明のWebカメラ
かなり昔に購入したWebカメラで640×480, 320×240に対応しているもので、lsusbコマンドではZC0302 Webcamと認識しています。15cm ほどの距離でもピンぼけしてしまうのと、反応が遅く、1fpsしかないようなので、使いみちがありません。とはいえ、認識して使えたので記録としていれておきます。
$ lsusb|grep ZC0302 Bus 001 Device 008: ID 0ac8:0302 Z-Star Microelectronics Corp. ZC0302 Webcam
python-opencv
python-opencvを使うとUSBカメラをプログラムから使えるようになります。pygameでもいけますが、オプションの指定がpygame.camera.Camera.set_controls(hflip = bool, vflip = bool, brightness)しかなかったので、OpenCVの方が細かく指定できていいかと思い調べました。python-opencvはpythonコマンド用なので、python3では使えません。python3コマンドで使いたい場合は別途対応したopencvをインストールする必要があります。
$ sudo apt-get -y install python-opencv
プログラム例 snap.py は下記です。ただ、これだと色調がおかしいカメラだとおかしな色で撮影されます。
#!/usr/bin/env python # -*- coding: utf-8 -*- import cv2 camera_port = 0 # /dev/video0に対応 cap = cv2.VideoCapture(camera_port) print("Taking image...") ret, im = cap.read() if ret==True: file_name = "snap.jpg" cv2.imwrite(file_name, im) cap.release()
使い方は次のとおりです。
$ python snap.py
自動で色調などを調整するカメラの場合は、時間をおいて調整が済んでから撮影をすれば良いかもしれないということで、time.sleep(3)としたものが下記です。Digio2のカメラでは良くなりました。Elecomのカメラではそれほど良くはなりませんでした。
#!/usr/bin/env python # -*- coding: utf-8 -*- import cv2 import time camera_port = 0 # /dev/video0に対応 cap = cv2.VideoCapture(camera_port) print("Ready...") time.sleep(3) print("Taking image...") ret, im = cap.read() if ret==True: file_name = "snap.jpg" cv2.imwrite(file_name, im) cap.release()
ただ3秒待つのでなく、撮影を30回すれば補正されるかもしれないということで、そういう処理をReadyの直後にいれたのが下記です。Digio2、Elecomのカメラ両方で良くなりました。
#!/usr/bin/env python # -*- coding: utf-8 -*- import cv2 camera_port = 0 # /dev/video0に対応 ramp_frames = 30 cap = cv2.VideoCapture(camera_port) print("Ready...") for i in xrange(ramp_frames): ret, im = cap.read() print("Taking image...") ret, im = cap.read() if ret==True: file_name = "snap.jpg" cv2.imwrite(file_name, im) cap.release()
opencvからカメラの設定をするようにしてみましたが、Digio2ではきちんと動きませんでした。整数値をそのまま渡すとうまくいかないので、妙な数式にしてありますが、いくつか値をいれてみて、v4l2-ctl -L で確認をして調整をしています。いまのところは役に立たないのですが、記録として残しておきます。
#!/usr/bin/env python # -*- coding: utf-8 -*- import cv2 import time camera_port = 0 # /dev/video0に対応 cap = cv2.VideoCapture(camera_port) cap.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, 640) cap.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT, 480) x = 2 cap.set(cv2.cv.CV_CAP_PROP_BRIGHTNESS, (x + 16) / 32.0) x = 16 cap.set(cv2.cv.CV_CAP_PROP_CONTRAST, x / 32.0) x = 4 cap.set(cv2.cv.CV_CAP_PROP_SATURATION, x / 15.0) x = 0 cap.set(cv2.cv.CV_CAP_PROP_HUE, (x + 45) / 90.0) x = 64 cap.set(cv2.cv.CV_CAP_PROP_GAIN, x / 64.0) print("Ready...") time.sleep(1) print("Taking image...") ret, im = cap.read() if ret==True: file_name = "snap.jpg" cv2.imwrite(file_name, im) cap.release()
uv4l
いろいろ調べていたら、uv4lというのもあるのですね。面白そうです。インストール方法は「Installation for ARM (Raspberry Pi) – (advanced) Projects」にあります。下記のようにしてインストールしてみました。ただ、USBカメラはうまく動作しなくて、いろいろやっていたら環境がおかしくなってUSBカメラの/dev/video0が作られなくなってしまいました。ラズパイの公式カメラはすんなりと動きました。ということで、メモという前提で読んでもらえばと思います。
$ curl http://www.linux-projects.org/listing/uv4l_repo/lrkey.asc | sudo apt-key add - $ sudo su -c "echo '' >> /etc/apt/sources.list" $ sudo su -c "echo 'deb http://www.linux-projects.org/listing/uv4l_repo/raspbian/ jessie main' >> /etc/apt/sources.list" $ sudo apt-get update $ sudo apt-get -y install uv4l uv4l-raspicam
これで ラズパイのIPアドレスが192.168.0.100だとしたら、http://192.168.0.100:8080/ へアクセスするとラズパイの公式カメラモジュールが動きました。
USBカメラを使う場合は、追加作業が必要なのですが、書いてある通りにしても動きませんでした。uv4l-uvcが必要なのですが、ほかもあったほうがいいようなのでインストールします。
$ sudo apt-get -y install uv4l-server uv4l-uvc uv4l-xscreen uv4l-mjpegstream uv4l-dummy uv4l-raspidisp
IDが必要なので、lsusbコマンドで取得。awkを使うと取り出せます。
$ lsusb | grep C270 Bus 001 Device 008: ID 046d:0825 Logitech, Inc. Webcam C270 $ lsusb | grep C270 | awk '{print $6}' 046d:0825
/etc/uv4l/uv4l-uvc.confのdevice-idにさっきのIDを指定します。それから、uv4lコマンドで実行。device-idをオプションで指定してますが、これがないとエラーになるので指定してます。警告などがでてますが、これでuv4lが起動します。
$ uv4l --driver uvc --device-id 046d:0825 --config-file=/etc/uv4l/uv4l-uvc.conf <notice> [core] Trying driver 'uvc' from built-in drivers... <warning> [core] Driver 'uvc' not found <notice> [core] Trying driver 'uvc' from external plug-in's... <notice> [driver] Video functionality '' recognized at 046d:0825 <notice> [core] Device detected! <notice> [core] Registering device node /dev/video0
ラズパイのIPアドレスが192.168.0.100だとしたら、http://192.168.0.100:8090/ へアクセスすると画面が表示されます。uvcの場合は8090なので注意してください。ただ、手元では写真撮影も動画配信もうまく動かなかったです。コントロールパネルもカメラを認識していないような感じ。「Device detected!」とか「Registering device node /dev/video0」と起動時に表示されているのに不思議です。
停止はpkillコマンドを使います。
$ pkill uv4l
自動起動をしたいなら、uv4l-raspicam-extrasをインストール。WebRTCを使いたいならuv4l-webrtcをインストールすれば良いそうです。
$ sudo apt-get -y install uv4l-raspicam-extras $ sudo apt-get -y install uv4l-webrtc
ということで、今回はここまで。