LoginSignup
1
3

More than 3 years have passed since last update.

GStreamerを使って、Webカメラから覗き窓っぽい画面を作る

Last updated at Posted at 2021-02-15

1.はじめに

GStreamerはエレメントと呼ばれる処理ブロックを繋げてストリーミング処理をするマルチメディアフレームワークです。

ドキュメントを見ていたらfisheyeというエレメントが気になりました。文字通り魚眼化するエレメントの様ですので、これを使って遊んでみようと思います。

2.開発環境

筆者の環境はUbuntu 20.04です。下記コマンドで、GStreamer関連ライブラリをごっそり入れます。

sudo apt-get install libgstreamer1.0-0 gstreamer1.0-plugins-base gstreamer1.0-plugins-good \
gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-doc \
gstreamer1.0-tools gstreamer1.0-x gstreamer1.0-alsa gstreamer1.0-gl gstreamer1.0-gtk3 \
gstreamer1.0-qt5 gstreamer1.0-pulseaudio

またGStreamerアプリケーションのコンパイル用にlibtoolをインストールします。

sudo apt install libtool-bin

3.作成するGstreamerパイプライン

今回のパイプラインで使用するエレメント説明します。


v4l2src

webカメラの映像取得するエレメント

videoscale

取得したWebカメラの映像を縮小するエレメント

capsfilter

videoscaleエレメントで拡縮するサイズを指定するエレメント

videoconvert

ビデオのフォーマット変換を行うエレメント

fisheye

魚眼化補正を行うエレメント

ximagesink

X11ウィンドウ上に出力するエレメント

上述のエレメントで必要十分だと思っているのですが、過不足などありましたらコメントを頂けたら幸いです。

4.コード

fisheye.c
#include <gst/gst.h>
#include <glib.h>
#include <stdio.h>

int main (int   argc,
      char *argv[])
{
  GMainLoop *loop;

  GstElement *pipeline, *src, *vscale, *filter, *vconv, *fish, *sink;
  GstCaps *filtercaps;

  /* Initialisation */
  gst_init (&argc, &argv);

  loop = g_main_loop_new (NULL, FALSE);

  /* Create gstreamer elements */
  pipeline = gst_element_factory_make("pipeline",      "pipeline");
  src      = gst_element_factory_make("v4l2src",       "src");
  vscale   = gst_element_factory_make("videoscale",    "vscale");
  filter   = gst_element_factory_make("capsfilter",    "filter");
  vconv    = gst_element_factory_make("videoconvert",  "vconv");
  fish     = gst_element_factory_make("fisheye",       "fish");
  sink     = gst_element_factory_make("ximagesink",    "sink");

  if (!pipeline || !src || !vscale || !filter || !vconv || !fish || !sink) {
    g_printerr ("One element could not be created. Exiting.\n");
    return -1;
  }

  /* Set up the pipeline */

  /* we set the input web-cam to the source element */
  g_object_set (G_OBJECT (src), "device", "/dev/video0", "io-mode", 0, NULL);

  filtercaps = gst_caps_new_simple(
    "video/x-raw",
    "width",  G_TYPE_INT, 480,
    "height", G_TYPE_INT, 480,
    NULL);
  g_object_set (G_OBJECT(filter),"caps",filtercaps, NULL);

  g_object_set (G_OBJECT(sink),
                "sync",FALSE,
                NULL);

  /* we add all elements into the pipeline */
  gst_bin_add_many (GST_BIN (pipeline),
                    src, vscale, filter, vconv, fish, sink, NULL);

  /* we link all elements */
  gst_element_link_many (src, vscale, filter, vconv, fish, sink, NULL);

  /* Set the pipeline to "playing" state*/
  gst_element_set_state (pipeline, GST_STATE_PLAYING);

  /* Iterate */
  g_print ("Running...\n");
  g_main_loop_run (loop);

  /* Out of the main loop, clean up nicely */
  g_print ("Returned, stopping playback\n");
  gst_element_set_state (pipeline, GST_STATE_NULL);

  g_print ("Deleting pipeline\n");
  gst_object_unref (GST_OBJECT (pipeline));
  g_main_loop_unref (loop);

  return 0;
}

5.コンパイルと実行

下記コマンドでコンパイルし、実行ファイルを生成します。

libtool --mode=link gcc `pkg-config --cflags --libs gstreamer-1.0` -o fisheye fisheye.c

生成したファイルを実行します。

./fisheye

次のように魚眼化されます。(PCのディスプレイをwebカメラで撮影したが、魚眼化して表示されている)
browser.png

近づいてカメラをのぞき込めば、玄関前に居る人みたいになります。
kirby.png

6.最後に

GStreamerは現在勉強中です。また面白いエレメントがあったら遊んでみます!
ここまで読んでいただいてありがとうございます。

1
3
0

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
1
3