LoginSignup
12
7

More than 3 years have passed since last update.

Raspberry PiにOpenCV+gstreamerをインストールしH264動画をキャプチャ

Last updated at Posted at 2019-07-21

背景

Raspberry PiでH264動画の動画フレームを取得する手段としてOpenCVを使う。H264動画のデコードをCPUで実行すると時間がかかりすぎるので、GPUでデコードできるようにgstreamerをあわせてインストールする。

環境

hardware: Raspberry Pi 3
Distributor ID: Raspbian
Description: Raspbian GNU/Linux 9.9 (stretch)
Release: 9.9
Codename: stretch

手順

gstreamerインストール。
gstreamer1.0-omx-rpiでバージョン指定している理由は後述。

sudo apt install cmake libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev gstreamer1.0-tools libgtk2.0-dev gstreamer1.0-omx=1.0.0.1-0+rpi12+jessiepmg gstreamer1.0-plugins-bad gstreamer1.0-plugins-good

gstreamerがh264のハードウェアアクセラレーションに対応しているか確認する。

gst-inspect-1.0 | grep omx

以下のように表示される。

omx:  omxmpeg2videodec: OpenMAX MPEG2 Video Decoder
omx:  omxmpeg4videodec: OpenMAX MPEG4 Video Decoder
omx:  omxh263dec: OpenMAX H.263 Video Decoder
omx:  omxh264dec: OpenMAX H.264 Video Decoder
omx:  omxtheoradec: OpenMAX Theora Video Decoder
omx:  omxvp8dec: OpenMAX VP8 Video Decoder
omx:  omxmjpegdec: OpenMAX MJPEG Video Decoder
omx:  omxvc1dec: OpenMAX WMV Video Decoder
omx:  omxh264enc: OpenMAX H.264 Video Encoder

OpenCVダウンロード。

mkdir OpenCV
cd OpenCV
wget https://github.com/opencv/opencv/archive/4.1.0.zip
unzip 4.1.0.zip
cd opencv-4.1.0

ビルド。
-jオプションの数字を大きくしすぎるとメモリが足りず止まってしまう模様。何度か-jの値を小さくしたり調整した結果ビルド完了まで3~4時間かかってしまった。

mkdir build
cd build
cmake -D CMAKE_BUILD_TYPE=RELEASE  -D  INSTALL_C_EXAMPLES=OFF  -D WITH_1394=OFF -D WITH_GSTREAMER=ON -D WITH_FFMPEG=OFF -D WITH_QT=OFF ..
make -j 4

インストール

sudo make install

pkg-configが使えるようにopencv4.pcファイルを追加する。

sudo mkdir -p /usr/local/lib/pkgconfig
sudo nano /usr/local/lib/pkgconfig/opencv4.pc
opencv4.pc
Package Information for pkg-config

prefix=/usr/local
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include/opencv4

Name: OpenCV
Description: Open Source Computer Vision Library
Version: 4.1.0
Libs: -L${exec_prefix}/lib -lopencv_dnn -lopencv_gapi -lopencv_highgui -lopencv_ml -lopencv_objdetect -lopencv_photo -lopencv_stitching -lopencv_video -lopencv_calib3d -lopencv_features2d -lopencv_flann -lopencv_videoio -lopencv_imgcodecs -lopencv_imgproc -lopencv_core
Libs.private: -ldl -lm -lpthread -lrt
Cflags: -I${includedir}

サンプルコードを実行してみる。

gstreamer_test.cpp
#include <opencv2/opencv.hpp>

int main(int argc, char *argv[])
{
        cv::VideoCapture gstreamer;
        gstreamer.open("videotestsrc  ! appsink");

        if (!gstreamer.isOpened())
        {
                printf("=ERR= fail to open\n");
                return -1;
        }

        cv::Mat GstCap;
        gstreamer >> GstCap;
        cv::imwrite("test.jpg",GstCap);
        return 0;
}

コンパイル&実行

g++ `pkg-config --cflags opencv4`  gstreamer_test.cpp -std=c++11 -g `pkg-config --libs opencv4` -o gstcvtest
 ./gstcvtest

test02.jpgとしてカラーバーが表示される。

test02.jpg

h264動画をキャプチャしてみる。
使用した動画はここからダウンロード。
https://www2.nhk.or.jp/archives/creative/material/view.cgi?m=D0002040402_00000

h264test.cpp
#include <opencv2/opencv.hpp>
#include <iostream>

int main(int argc, char *argv[])
{
        cv::VideoCapture gstreamer;
        //gstreamer.open("filesrc location=/home/pi/nfs/experiment/movie/D0002040402_00000_V_000.mp4 ! qtdemux name=demux demux.video_0 ! h264parse ! omxh264dec ! videoconvert ! appsink");
        gstreamer.open("/home/pi/nfs/experiment/movie/D0002040402_00000_V_000.mp4");

        if (!gstreamer.isOpened())
        {
                printf("=ERR= fail to open\n");
                return -1;
        }


        int i=0;
        cv::Mat GstCap;
        gstreamer.read(GstCap);
        cv::imwrite("nfs/preview.jpg",GstCap);
        while (gstreamer.read(GstCap))
        {
                std::cout << "frame=" <<  i << std::endl;
                i++;
        }
        return 0;
}

コンパイル&実行

g++ `pkg-config --cflags opencv4`  h264test.cpp -std=c++11 -g `pkg-config --libs opencv4` -o h264test 
time ./h264test

結果。timeコマンドのログ。
1083フレームを37秒なので、29fps程度。

real    0m37.376s
user    0m22.739s
sys     0m4.799s

性能比較

GPUを使わない場合との性能比較を行う。
openの引数に単にファイル名を指定する。

 gstreamer.open("/home/pi/nfs/experiment/movie/D0002040402_00000_V_000.mp4");

結果。

real    0m42.042s
user    0m26.877s
sys     0m4.827s

? あまり変わらない。単純にファイル名を指定した場合でもGPUが使用されているということか。

一度GPU用のプラグインを削除してみる。

sudo apt remove gstreamer1.0-omx

結果。激遅

real    7m9.670s
user    7m14.918s
sys     0m0.620s

ここでバージョン指定せずにgstreamer1.0-omxを入れてみる。
1.10.4-1+rpt3が入る。

gstreamerパイプラインをopenに記述して実行してみる。

real    1m44.353s
user    1m38.168s
sys     0m3.689s

このくらい遅い。なぜだろう?

参考URL

12
7
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
7