【Raspberry Pi 2】 RasPiカメラモジュールをOpenCVで使用する

USBカメラはOpenCVから簡単に扱えますが、RaspberryPiカメラモジュールの場合はOpenCVの標準機能ではサポートされていません。

以下のライブラリ(raspicam_cv)を使用することで、OpenCVから簡単にRaspberryPiカメラモジュールが使えるようですので試してみました。
https://github.com/robidouille/robidouille/tree/master/raspicam_cv


OpenCVのインストール

まずはOpenCVのインストールを行います。
OpenCVはapt-getでインストールできますが、最新版を使用したいので、ソースからコンパイルします。
現時点最新の2.4.10をインストールします。

まず前準備として、必要なツールやライブラリをインストールします。
$ 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
$ sudo apt-get install libswscale-dev

続いてOpenCVの入手とビルドです。
$ wget http://sourceforge.net/projects/opencvlibrary/files/opencv-unix/2.4.10/opencv-2.4.10.zip
$ unzip opencv-2.4.10.zip
$ cd opencv-2.4.10
$ mkdir build
$ cd build
$ cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D BUILD_NEW_PYTHON_SUPPORT=ON -D BUILD_EXAMPLES=ON ..

$ make -j 4
$ sudo make install
$ sudo ldconfig

以下の指定でmakeすることによって4並列でコンパイルできます。
$ make -j 4

コンパイルは1時間ぐらいで終了しました。
旧モデルのRaspberryPiでは6時間ぐらいかかっていたので、Raspberry Pi 2の発表時に「旧モデルに比べて6倍速になった」という説明とぴったり合いました。
2015年2月28日追記 OpenCV-2.4.11をコンパイルしたところ2時間ぐらいかかりました。時間を見誤ったかもしれません。

ためしに簡単なOpenCVプログラムをコンパイルしてみました。
USBカメラの映像を画面に表示するプログラムです。

ソース camera_test.c
#include
#include

int main (int argc, char **argv)
{
double w = 640, h = 480;

CvCapture *capture = cvCreateCameraCapture(-1);
if (capture==NULL) {
puts(“Camera not found.\n”);
return 0;
}

cvSetCaptureProperty (capture, CV_CAP_PROP_FRAME_WIDTH, w);
cvSetCaptureProperty (capture, CV_CAP_PROP_FRAME_HEIGHT, h);

// ウィンドウを作成する
char *windowName = “camera”;
cvNamedWindow( windowName, CV_WINDOW_AUTOSIZE );

while (1) {
IplImage *frame = cvQueryFrame(capture);
cvShowImage( windowName, frame );

cvWaitKey( 1 );
}

cvReleaseCapture (&capture);
cvDestroyWindow (windowName);

return 0;
}

以下のようにコンパイルします。
gcc -o camera_test camera_test.c -I/usr/local/include/opencv -lpthread -ldl -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_ml -lopencv_video -lopencv_features2d -lopencv_calib3d -lopencv_objdetect -lopencv_contrib -lopencv_legacy -lopencv_flann -lm

結果、問題なく動きました。
当方の環境ではディスプレイをつなげていないため、ネットワーク経由でVNCにて表示しています。
VNCで負荷がかかっていると思いますので、フレームレートは参考値になりますが、8フレーム/secでした。
※上記プログラムを少し改造して、フレームレートを表示するようにしたもので調べました。

cvShowImage( windowName, frame );
の個所をコメントアウトして映像を表示しないようにすると、15フレーム/secとなりました。
USBカメラではこれぐらいが限界なのでしょうか。。。

なお、USBカメラにはロジクールC905を使用しました。

raspicam_cvのインストール

raspicam_cvライブラリを使用すると、OpenCVから簡単にRaspberryPiカメラモジュールを使用できます。

https://github.com/robidouille/robidouille/tree/master/raspicam_cvの手順に従って、インストールしていきます。

前準備としてgitコマンドをインストールします。
# apt-get install git

raspberry pi userlandライブラリをインストールします。
# mkdir ~/git
# cd ~/git
# mkdir raspberrypi
# cd raspberrypi
# git clone https://github.com/raspberrypi/userland.git
# cd userland
# ./buildme

# cd ~/git
# git clone https://github.com/robidouille/robidouille.git
# cd robidouille/raspicam_cv

opencvのインストール先の違いにより、Makefileを一か所書き換えました。
変更前: CFLAGS_OPENCV = -I/usr/include/opencv
変更後: CFLAGS_OPENCV = -I/usr/local/include/opencv

# mkdir objs
# make

サンプルプログラムのソース(RaspiCamTest.c)を見ると、
以下のように一部関数の入れ替えが必要ですが、見慣れたOpenCVのソースですので取っつきやすいです。
CvCapture -> RaspiCamCvCapture
cvCreateCameraCapture -> raspiCamCvCreateCameraCapture
cvQueryFrame -> raspiCamCvQueryFrame
cvReleaseCapture -> raspiCamCvReleaseCapture
cvGetCaptureProperty -> raspiCamCvGetCaptureProperty

サンプルプログラムのraspicamtestを動かしてみます。
# ./raspicamtest -l
“-l”指定で640×480の解像度になります。何も指定しないと320×240となり、”-x”指定で960×720となります。

raspi03

問題なくRaspberryPiカメラモジュールの映像が表示されました。
画面にフレームレートが表示されていますが、これは設定値であり、実際のフレームレートではないので注意が必要です。

フレームレートをUSBカメラと比較すると以下となります。

  USBカメラ Raspiカメラ
画面表示あり(※) 8フレーム/sec 13フレーム/sec
画面表示なし 15フレーム/sec 30フレーム/sec

※VNCにてネットワーク経由のため、負荷がかかっていますので参考値です。

960×720の場合でも、画面表示なしでは30フレーム/secでした。
また、ソース上、
config->framerate=0;
の個所を
config->framerate=60;
とすることで、640×480の場合、画面表示なしでは47フレーム/secとなりました。

USBカメラよりもフレームレートが高いため、画像認識の性能向上が期待できます。


【国内正規代理店版】Raspberry Pi 4 Model B/4GB OKdo版【技適マーク付】


Raspberry Pi + AI 電子工作超入門


OSOYOO(オソヨー) HDMI 3.5 インチ LCD ディスプレイ IPS モニター IPSタッチスクリーン 1920×1280ハイビジョン Raspberry Pi 3 2 Model B に対応 (3.5″ HDMI LCD+クリアケース)


本格派対局将棋 ぴよ将棋
本格派対局将棋アプリ ぴよ将棋
[Android] [iOS]

かわいい「ひよこ」と対局する将棋アプリ。かわいいけどAIは本格派!
対局後の検討機能や棋譜管理機能も充実!棋譜解析機能も搭載!

「【Raspberry Pi 2】 RasPiカメラモジュールをOpenCVで使用する」への30件のフィードバック

  1. はじめまして,「PONTAの工房~プログラミング・電子工作~」を参考に,
    Raspberry PIを使ってプログラミングを行っている学生です.今回,質問があり
    コメントしました.
    Raspberry PIのカメラモジュールのカメラ映像をOpenCVを使って取得して,カメラの映像をモニタに表示するプログラムを作っています.
    流れとしてはカメラキャプチャーを作る.キャプチャー映像を載せるウインドウを作る,キャプチャーの映像から1フレームを切り出して,ウインドウに乗せる.このような感じで,camera_test.cをraspcam_cvで書いたようなイメージのプログラムです.
    このプログラムを実行したところ,なぜかモニタに表示される映像が非常に遅いものとなりました.この原因が分からず困っているのですが,もしアドバイスなどありましたら教えていただけないでしょうか?
    「raspcam_cvを用いた映像の取得プログラムで,取得できる映像が遅くなる原因はなにか?という感じのことを聞きたい感じです.」

    1. mさん
      思い当たることはないですが、以下のように調べてみてはいかがでしょうか?
      ・raspicam_cvのサンプル(RaspiCamTest.c)では遅くならずに表示されるか確認
      ・RaspiCamTest.cでは遅くならないのであれば作成されているプログラムとの差を調べる
      ・RaspiCamTest.cでも遅くなるのであれば環境周りが悪いのかもしれません
        ①裏で負荷がかかるPGが動いてたりしないか?⇒topコマンドで調べる
        ②OSモジュールとファームウェアをバージョンアップしてみる
         % sudo apt-get update
         % sudo apt-get upgrade
         % sudo rpi-update

  2. ありがとうございます。
    いろいろ試してみて無事に問題解決しました。
    カメラでキャプチャした映像をウインドウに張り付ける作業を
    do~whileのループで行っていたのですが、そこで
    ウインドウの大きさをリサイズする、位置を調整するという
    コードを書き入れていたのが原因のようでした。
    それをループの外に出すことで無事に解決しました。

    ありがとうございました。
    また何かあったときはよろしくお願いします。

  3. こんにちは、opencvのマッチングが面白そうだったので純正カメラでやってみようと昨日夜遅くまでインストールしてました。全部入れたのですがgccでビルドした時に一部辞書が無い様なエラーが出て動かない状態です。raspberry pi 2の後にインストールしたc言語のgccが上手く入っていないのでしょうか?gccのビルドのやり方が悪いのでしょうか?raspberry pi、wiring pi、gcc、opencv、userlandの順番で入れてます。先日購入したraspberry pi初心者でよくわかって無いです。gccのインストールやgccのビルドの方法も教えてもらえるとたすかります。

  4. Tさん
    gccのインストールはOSをイメージからインストールした場合には含まれていると思います。(インストールは不要と思います)
    gccでエラーが出るのはopencvをソースからビルドした際ですか?
    それとも自作のプログラムをコンパイルした場合ですか?
    ビルドした際の手順やエラー内容を記載いただけると何かアドバイスできると思います。

    1. こんばんは。
      返信ありがとうございます。
      知らないことだらけで、今日OSから入れ直しをしました。エラーはRaspberrypiカメラモジュールのサンプルプログラムRaspiCamTest.cをビルドした時に出てきます。gcc -o RaspiCamTest RaspCamTest.c -I/use/local/include/open cv -lpthread …の実行でRaspCamTest.cにundefined reference to raspCamCvCreateCameraCapture2などraspCamCv系の名前のエラーが出てきます。opencvのインストール時はMakefileのパスも直してひと通りエラーは出なかった様です。なかなか難しいです。

  5. Tさん
    RaspiCamTestはraspicam_cvのビルド時のmakeで一緒にビルドされたと思います。
    raspicam_cvのビルドでlibraspicamcv.aができた後にraspicamtestのビルドになると思いますが、libraspicamcv.aまでは正常にできているでしょうか?
    エラー内容からすると、libraspicamcv.aが参照できていないように思われます。
    libraspicamcv.aがraspicam_cvライブラリの本体となりますので、libraspicamcv.aがないとRaspiCamTestのビルドはできません。

  6. こんにちは。
    返信ありがとうございます。
    libraspicamcv.aは出来てました。
    初心者で無知なものでmakeでraspcamtestがビルド出来るのを知らなかったです。
    今日makeしたらエラーが出ていて/usr/bin/ld/: cannot find -lollと-lextでした。
    デスクトップのファイルマネージャーから見るとldフォルダ自体無い様な感じです。
    なんとかPONTAさんの言っていることが理解できたのですが難しいです。

  7. もう一度ひとつひとつ確認しながらインストールしなおしたら動きました。ありがとうございます。opencvが動いてよかったです。(・Д・)ノ認識が面白そうなので、なんとかやってみようと思います。
    PONTAさんのRaspberry Pi記事を楽しみにしてます。

  8. Tさん
    ldはフォルダではなく、コマンドです。最後の”/”は謎ですが。
    cannot find -lollと-lextとのことですが、raspicam_cvのMakefileを見直してみても-lollと-lextは見当たりませんでした。もしかすると、-lX11 -lXextでしょうか?
    だとすれば、X-Windowのライブラリがインストールされていないことが考えられますね。私の環境では以下にファイルがありました。
     /usr/lib/arm-linux-gnueabihf/libX11.a
     /usr/lib/arm-linux-gnueabihf/libXext.a
    では、がんばってみてください!

  9. 初めまして。Linux初心者ですが、Raspberry Pi+RaspiカメラでOpenCVを動かしたく、こちらのサイトを参考に実施してみたのですが、何度インストールからやり直しても同じ結果になってしまうので、ご教示いただけますでしょうか。
    OpenCVは2.4.11をインストール・ビルドしています。
    raspicam_cvのmakeで、リンクエラーなのでしょうか、以下のように出力されます。

    //usr/local/lib/libopencv_ml.so.2.4: undefined reference to cv::parallel_for_(cv::Range const&, cv::ParallelLoopBody const&, double)'
    //usr/local/lib/libopencv_ml.so.2.4: undefined reference to
    typeinfo for cv::ParallelLoopBody’
    //usr/local/lib/libopencv_ml.so.2.4: undefined reference to cv::Mutex::unlock()'
    //usr/local/lib/libopencv_ml.so.2.4: undefined reference to
    cv::Mutex::lock()’
    //usr/local/lib/libopencv_ml.so.2.4: undefined reference to cv::Mutex::Mutex()'
    //usr/local/lib/libopencv_ml.so.2.4: undefined reference to
    cv::ParallelLoopBody::~ParallelLoopBody()’
    //usr/local/lib/libopencv_ml.so.2.4: undefined reference to `cv::Mutex::~Mutex()’
    collect2: ld returned 1 exit status
    Makefile:57: recipe for target ‘raspicamtest’ failed
    make: *** [raspicamtest] Error 1

    /usr/local/lib/ に libopencv_ml.so.2.4 は存在していて libopencv_ml.so.2.4.11 を参照しているようです。
    /usr/local/lib を PATH に追加してみたりしましたが、状況変わりませんでした。

    一般的に常識である何かが作業上で抜けているのかも知れませんが、何か分からず行き詰っています。
    考えられる原因などヒントでもいただけたら有難いです。

  10. 先程の今ですみません。ダメ元で Makefile の LDFLAGS2_OPENCV に -lopencv_ml を追記したら、raspicamtestが生成できたようです。
    X上でカメラ映像が表示されました。
    なぜ追記する必要があったのか、なんだかすっきりしませんが、この対処内容で正しかったのでしょうか?
    何らか考えられることがありましたら、ご指摘いただけますでしょうか。

  11. ラズパイ、Linux初心者です、OpenCV Ver3.0をこのサイトでインストールしてLenaさんサンプルプログラムは動いたのですが、カメラモジュールでOpenCVを使ってみたくてraspicam_cvのインストールしてみましたが途中のmakeでエラーが出てしまいます。OpenCV 2.4をインストールしてないからでしょうか? ご教授よろしくお願いいたします。(エラーは以下)
    pi@raspberrypi ~/git/robidouille/raspicam_cv $ make
    gcc objs/RaspiCamTest.o libraspicamcv.a -lopencv_highgui -lopencv_core -lopencv_legacy -lopencv_video -lopencv_features2d -lopencv_calib3d -lopencv_imgproc -lpthread -lm -L/home/pi/git/raspberrypi/userland/build/lib -lmmal_core -lmmal -l mmal_util -lvcos -lbcm_host -lX11 -lXext -lrt -lstdc++ -L. libraspicamcv.a -o raspicamtest
    /usr/bin/ld: -lopencv_legacy が見つかりません
    collect2: ld returned 1 exit status
    Makefile:57: recipe for target ‘raspicamtest’ failed
    make: *** [raspicamtest] Error 1

    1. OpenCV3.0では、動くかどうか確認していないです。
      だめもとでMakefileから -lopencv_legacy をはずしてみたらどうですかね?

      1. -lopencv_legacyをはずしてみたら動きました。makeファイルのこと理解してないので、、、助かりました。。。
        ありがとうございました。

  12. はじめまして,Raspberry PIを初めて一カ月の初心者(老人)です。「PONTAの工房~プログラミング・電子工作~」で勉強させて頂いています。
    RaspiCamTest.cをMakeして動作するようになりました。
    物体の寸法を測りるため下記のプログラム(抜粋)を作成しました。
    IplImg* image = raspiCamCvQueryFrame(capture);
    IplImage* gray;
    cvCvt(Color(image, gray, CV_BGRGRAY);
    IplImage* thr;
    cvThreshold(gray, thr, 80, 255, CV_THRESH_BINARY_INV);
    Makeは成功しました。
    実行するとエラーが発生。
    OpenCv Error:
    Assertion failed (dst.data == dst0,data) in cvCvtColor,
    file /build/opencv-IsmtKH/opencv-2.4.10+dfsg/modules/imgproc/src/color.cpp, line 422
    terminate called after throwing an instance of ‘cv::Exception’
    what():
    /build/opencv-ISmtKH/opencv-2.4.10+dfsg/modules/imgproc/src/color.cpp:4422:
    error: (-215) dst.data == dst0.data in function cvCvtColor
    どうして良いか難しくて分かりません。
    質問の対象外で申し訳、御座いません。
    C++は難しく、Cで行いたいです。
    アドバイスを頂けないでしょうか。
    よろしく、お願いします。

    1. 以下のように、IplImage *grayのメモリ確保をしてあげる必要があるのではないでしょうか?(IplImage* thrも同様)
      IplImage *gray= cvCreateImage(cvGetSize(image ), IPL_DEPTH_8U, 1);

      1. 早速の返信、有難う、御座います。
        グレイスケール、2値化ができました。
        感謝、感謝です。
        掲載されている「OpenCVによる画像処理入門」で
        勉強をしたいと思います。
        有難う、御座いました。

  13. 前回、「物体の寸法を測るプログラム」のraspiCamCvQueryFrame()で
    アドバイスを頂いた者です。
    おかげさまで、無事に寸法を測ることができました。
    しかし、静止物体は測れますが、移動物体は画像が流れて測る事ができません。
    ラズベリーパイ・カメラ関連のサイトで調べました、ところ、Python言語は
    できそうなサイトが有りましたが、C言語では有りませんでした。
    何か、露出や電子シャッタを設定する方法は無いでしょうか?。
    誠に、厚かましい、お願いですが、アドバイスを頂けないでしょうか?。
    よろしく、お願いします。

  14. 初心者です。こちらのサイトや他のサイトを見ながらやってみたのですが、
    raspicam_cvにlibraspicamcv.aがないことに気づき、
    どこかで間違ってしまったのかと、再度同じ手順でやってみたのですが
    libraspicamcv.aは現れましたが、チャック状態。
    raspicamtestは現れなく、こちらのエラーが出てきました。

    ~/robidouille/raspicam_cv $ make
    gcc -c -Wno-multichar -g -I/usr/include/opencv -I/home/pi/git/raspberrypi/userland/host_applications/linux/libs/bcm_host/include -I/home/pi/git/raspberrypi/userland/host_applications/linux/apps/raspicam -I/home/pi/git/raspberrypi/userland -I/home/pi/git/raspberrypi/userland/interface/vcos/pthreads -I/home/pi/git/raspberrypi/userland/interface/vmcs_host/linux -I/home/pi/git/raspberrypi/userland/interface/mmal -MD RaspiCamCV.c -o objs/RaspiCamCV.o
    In file included from /usr/local/include/opencv2/core/core.hpp:48:0,
    from /usr/include/opencv/cv.h:64,
    from RaspiCamCV.c:40:
    /usr/local/include/opencv2/core.hpp:49:4: error: #error core.hpp header must be compiled as C++
    # error core.hpp header must be compiled as C++
    ^
    In file included from /usr/local/include/opencv2/core.hpp:54:0,
    from /usr/local/include/opencv2/core/core.hpp:48,
    from /usr/include/opencv/cv.h:64,
    from RaspiCamCV.c:40:
    /usr/local/include/opencv2/core/base.hpp:49:4: error: #error base.hpp header must be compiled as C++
    # error base.hpp header must be compiled as C++
    ^
    /usr/local/include/opencv2/core/base.hpp:52:19: fatal error: climits: そのようなファイルやディレクトリはありません
    #include
    ^
    compilation terminated.
    Makefile:45: recipe for target ‘objs/RaspiCamCV.o’ failed
    make: *** [objs/RaspiCamCV.o] Error 1

    ラズパイにはOpenCV2.4.11とOpenCV3.1.0の両方がはいってます。
    -lopencv_legacyは消しました。

    どうすればlibraspicamcv.aとraspicamtestが正常にインストールできるか
    教えてください。お手数ですが、宜しくお願い致します。

  15. よくわかりませんが、「OpenCV2.4.11とOpenCV3.1.0の両方がはいってます」が原因では無いでしょうか?
    /usr/include/opencvと/usr/include/opencv2の両方にアクセスしているようなので。

  16. 質問失礼いたします。
    こちらのサイトを見ながらパイカメラは映ったのですが、
    例えば、パイカメラを使いopenCVとraspicam_cvとで
    画面に映っている動画をリアルタイムでグレースケールからの二値化をするには
    C言語だと、どのようなプログラムになるのでしょうか。
    初心者で申し訳ありません。
    宜しくお願い致します。

    1. 本文の camera_test.c 22行目で
      IplImage *frame = cvQueryFrame(capture);
      にてキャプチャした画像がframeに格納されますので、
      あとは好きなように画像を編集後、
      cvShowImage( windowName, frame );
      してあげればリアルタイムに表示されます。
      OpenCVを使用した画像の編集サンプルはネット上に大量にありますので、調べてみてください。

  17. raspberrypi、opencv初心者です。C言語を使ってます。
    2つのプログラムを使い、
    1.システム関数でraspistillコマンドで静止画(normal.jpg)を撮影、保存します。
    2.保存した静止画(normal.jpg)をグレースケールし、最終的に二値化。
    Open CV2.4.13をインストールしてサンプルソースのRaspiCamTest.cはmake、実行もできる環境にしました。
    しかし、下記のようなプログラムをサイトで調べて作成したのですがどのようにコンパイルして良いかわかえいません。ぜひ教えていただければと思っています。

    #include
    #include

    using namespace cv;

    int main(){

    Mat input_img = imread(“normal.jpg”, IMREAD_UNCHANGED);
    Mat gray_img; //グレースケール画像を入れておくためのMat
    Mat bin_img; //2値画像を入れておくためのMat

    cvtColor(input_img, gray_img, CV_BGR2GRAY); //グレースケールに変換
    threshold(gray_img,bin_img,160,255,THRESH_BINARY); //閾値160で2値画像に変換
    threshold(gray_img, bin_img, 0, 255, THRESH_BINARY | THRESH_OTSU); //閾値を自動で設定
    imwrite(“img.jpg”,bin_img);

    return 0;
    }

    1. 本文中の camera_test.c をコンパイルしてみてください。
      うまく行ったら、同じ様にやってみると良いと思います。

コメントを残す

メールアドレスが公開されることはありません。