danglingfarpointer's memoization

仕事周りでの気付き、メモ、愚痴などを書いていきます。

OS Xのbashでファイルをランダムにk個選択する

OS Xbashで、あるディレクトリ以下の全てのファイルから5ファイルをランダムに選択したい場合:

for f in $(find . -type f); do echo `uuidgen` $f; done | sort | head -5 | awk '{print $2}'

CentOSであればsort -Rでランダムにソートできるので、もう少しシンプルにできそうだが、OS Xのsortではできないようだ。

uuidgenの代わりに$RANDOMでもよいが、ファイル数が多い場合にランダム性が損なわれる。

Raspberry Pi - OpenCVで動画のread/write

前回のエントリと同様、Raspberry Pi + OpenCV関連。

今回は、

  • Web Camのキャプチャから動画を作成するプログラム
  • その動画を再生するプログラム(動画確認用)

を作ってみた。

1. Web Cam.

前回と同様、LogitechのC270というWeb Camを接続。

2. FFmpeg

FFmpegをインストールしておく。

sudo apt-get install ffmpeg

3. 動画作成

3-1. ソース

writer.cpp:

#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;

int main(int argc, char* argv[])
{
    VideoCapture cap(0);
    if(!cap.isOpened())
        return -1;

    // 320x240
    cap.set(CV_CAP_PROP_FRAME_WIDTH, 320);
    cap.set(CV_CAP_PROP_FRAME_HEIGHT, 240);

    string filename = argc > 1 ? string(argv[1]) + ".avi" : "test.avi";
    int codec = CV_FOURCC('F', 'M', 'P', '4'); // use MP4 as video codec
    VideoWriter writer(filename, codec, 20, Size(320, 240), true);

    Mat image;
    namedWindow("video", CV_WINDOW_AUTOSIZE);
    while(true){
        cap >> image;
        if (image.empty())
            break;

        imshow("video", image);

        writer << image;
        if(waitKey(50) >= 0)
            break;
    }
}

コンテナとして".avi", 動画コーデックとしてfmp4を利用する。OpenCVでは、サポートされているコンテナは".avi"のみとのこと。動画のfpsは20を指定。

3-2. コンパイル・実行

g++ writer.cpp `pkg-config --libs opencv` -o writer
./writer # または、./writer <filename>

実行時にいろいろとwarningがでるものの、動画ファイルが作成される。引数無しで実行した場合のファイル名は、test.avi.

4. 動画再生

Raspberry Piではmplayerなどで動画を再生できる。しかし、上記のプログラムで作った動画は、fpsをいろいろと調整してもなぜか速く再生されてしまう。解決方法もよくわからないので、再生部分もOpenCVで用意しておくことにした。

4-1. ソース

reader.cpp:

#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;

int main(int argc, char* argv[])
{
    string filename = argc > 1 ? argv[1] : "test.avi";
    VideoCapture cap(filename);
    if(!cap.isOpened())
        return -1;

    // read fps from the video to coordinate the video play speed
    int fps = cap.get(CV_CAP_PROP_FPS);
    int wait = 1000 / fps;

    Mat image;
    namedWindow("video", CV_WINDOW_AUTOSIZE);
    while(true){
        cap >> image;
        if (image.empty())
            break;

        imshow("video", image);

        if(waitKey(wait) >= 0)
            break;
    }
}

4-2. コンパイル・実行

g++ reader.cpp `pkg-config --libs opencv` -o reader
./reader # または、./reader <filename>

粗々ではあるが、これでひと通り動画作成・確認ができるようになった。

Raspberry PiでOpenCV

Raspberry Piを買ったものの、しばらく放置していた。何か遊び方を見つけていくために、手始めにOpenCVWebカメラの画像を取り込んで表示するプログラムを作ってみた。

Web Cam.

LogitechのC270というWeb Camを調達。USBに差し込んでRaspberry Piを起動すれば、自動で認識された。

$ lsusb
Bus 001 Device 002: ID 0424:9512 Standard Microsystems Corp. 
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. 
Bus 001 Device 004: ID 046d:0825 Logitech, Inc. Webcam C270 #### <- Web Cam

OpenCVのインストール

現在のRaspbianのapt-getからは、やや古いが2.3がインストールできる。

$ sudo apt-get install libopencv-* libopencv-*-*

プログラムを作る

camera.cpp:

#include <opencv2/opencv.hpp>

using namespace cv;

int main()
{
    // open the default camera
    VideoCapture cap(0);
    if(!cap.isOpened())
        return -1;

    // set capture size
    cap.set(CV_CAP_PROP_FRAME_WIDTH, 320);
    cap.set(CV_CAP_PROP_FRAME_HEIGHT, 240);

    Mat image;
    namedWindow("Video", CV_WINDOW_AUTOSIZE);

    while(1){
        cap >> image;
        imshow("Video", image);

        if(waitKey(30) >= 0)
            break;
    }
}

コンパイル

$ g++ camera.cpp `pkg-config --libs opencv`

実行

$ ./a.out

やや処理が遅いが、カメラの映像をちゃんと取り込める。

f:id:danglingfarpointer:20140517191119p:plain

実行直後、以下のエラーがコンソールに10回程度出るが、一応動作している。。。

VIDIOC_QUERYMENU: Invalid argument

プログラムの中でフレームサイズを160x120と指定すれば、より滑らかに取り込める。

とりあえずここまで。。。もう少し面白いアプリケーションを考えていきたい。

栃木・益子の陶器市

GWに地元の栃木に帰ったついでに、益子で陶器市が開催されているということで行ってみた。益子はうちの地元の町から1時間半程度。実際に陶器市に行ったのは初めてだ。

登り窯という段々状の窯。

f:id:danglingfarpointer:20140507001906j:plain

いくつか陶器も買ってきた。鶏の楊枝入れとか。どうやら連れ合いのお気に入りらしい。しかしこれは益子焼なんだろうか・・

f:id:danglingfarpointer:20140507002947j:plain

あるヘッダファイルを-Wallの対象から除く

gccで-Wall付きでコンパイルした際、他者ライブラリのヘッダファイルからのwarningがあまりに多かったので、これらのヘッダファイルを-Wallの対象から除外したくなった。

ググッた結果、以下のページにヒット: http://stackoverflow.com/questions/1867065/how-to-suppress-gcc-warnings-from-library-headers

インクルードパスを、-Iではなく-isystemで指定すればよい。これにより、指定されたパスがシステムのインクルードパスと解釈され、warningが出なくなる。

例えば以下のコマンドだと、include以下のヘッダファイルは-Wallの適用対象外になる:

g++ -Wall -O2 -c -o test.o test.cpp -I. -isystem include

JAL工場見学

先日会社の組合のイベントで、JALの工場見学に行ってきた。

内容は、JALの博物館、整備場、滑走場の見学。巨大な整備場には圧巻。

f:id:danglingfarpointer:20140420223639j:plain

f:id:danglingfarpointer:20140420223647j:plain

午後は羽田空港国際線ターミナルに立ち寄り。ターミナル開港以来初めて入ったが、成田と比べるとかなり小さい。

うちは連れと二人だったが、やはり子供連れが多かった。子供を楽しませるにはうってつけの企画だろう。もちろん大人だけでも楽しめるが。