suzuzusu日記

(´・ω・`)

Pure C Project in Visual Studio

今まで雑にwin32コンソールでCを書いていたがVisual StudioでCを書くときのメモ

  1. 空のsolutionを作る
  2. 空のproject追加
  3. main.cを追加
  4. projectのプロパティ -> 構成プロパティ -> C/C++ -> すべてのオプション -> コンパイル言語の選択 を Cコードとしてコンパイル/TCにする
  5. projectのプロパティ -> 構成プロパティ -> C/C++ -> システム -> サブシステム を コンソール(/SUBSYSTEM:CONSOLE)

重複あり組み合わせ C++11

メモとして

#include<functional>
#include<vector>
#include<iostream>

using namespace std;

template<class T>
vector<vector<T>> combinations_with_replacement(const vector<T> n, int r) {
    vector<vector<T>> result;

    function<void(const vector<T>, int, vector<T>, vector<vector<T>>*)> f = [&f](const vector<T> n, const int r, const vector<T> acc, vector<vector<T>>* result) {
        if (r <= 0) {
            (*result).push_back(acc);
            return;
        }
        for (auto itr = n.begin(); itr != n.end(); ++itr) {
            vector<T> tmp_acc = vector<T>(acc);
            tmp_acc.push_back(*itr);
            f(n, r - 1, tmp_acc, result);
        }
    };

    f(n, r, {}, &result);
    return result;
}

int main(){
    auto result = combinations_with_replacement<int>({1, 2, 3, 4}, 2);
    for (auto i : result) {
        for (auto j : i) {
            cout << j << " ";
        }
        cout << endl;
    }
    return 0;
}

/*
1 1
1 2
1 3
1 4
2 1
2 2
2 3
2 4
3 1
3 2
3 3
3 4
4 1
4 2
4 3
4 4
*/

whywaitaフィルタ

この記事はwhywaita Advent Calendar 2016 - Adventar 21日目の記事です。

www.adventar.org

whyさんについて

whyさんは私が所属している電気通信大学MMAの先輩です。 実は高校が一緒だったりとなにかと縁があったりなかったりします。 whyさんのイメージとしてはなんかインフラ強そうな印象があります。 初めて会った時の印象は覚えてないのですがMMAの部室で再履の実験のレポートを何人かの先輩と一緒になって書いていたことは覚えています。 あと純粋だった私は本名を橘和板だと信じていたので本名聞いた時はなんで偽名使ってるんだろう、過去に悪いことしたのかなと思ったことがあります。

whywaitaとは?

突然ですが哲学的な問いをここで提示します。 いったいインターネット上に存在するwhywaitaとは何なのでしょうか。 何をもって私たちはwhywaitaを認識しているのでしょうか。

"whywaita"という文字列がwhywaitaという存在を一意にしているという意見もあると思いますが昔使ってたIDをwhywaita_oldと仮定します。 whywaitaもwhywaita_oldもwhyさんであるということは一緒なのにIDが違うと全く別の存在になるのでしょうか。仮に他のsnsのサービスでwhywaitaというIDを取得することができずwhywaita_というIDであった場合も同じことが言えると思います。

ここで現実に置き換えて考えてみましょう。例えば私がwhyさんと道ですれ違います。その時私はIDでwhyさんという存在を判断していませんし小さい子供みたいに名札に書いてある文字列から判断しているわけではありません。私はwhyさんの顔からwhyさんであるという判断をします。

ここでインターネットに戻って考えてみましょう。現実の顔に相当するものつまりwhywaitaのあのアイコンでもって認識しているという結論が導かれますね。snsでも急にアイコンを変えられると「誰だこの人?」となったことが誰しも経験していると思います。

whywaita

ここから私は全人類whywaita計画という計画を思いつきました。

whywaitaフィルタ

ffmpegのfilterとしてFrei0rを利用してwhywaitaフィルタというものを作ってみました。

こちらにdllを一応置いておきますがgithubにソースは上げたので信用できない場合はbuildしてみてください。

github.com

使い方

# buildしたfilter DLLのmat33.dllをC:\Program Files (x86)\frei0r\lib\frei0r-1\whywaita.dllに置いたとしましょう

# FREI0R_PATH環境変数を設定
$ export FREI0R_PATH="C:\Program Files (x86)\frei0r\lib\frei0r-1"
# powershellの場合は以下のようにする
# Set-Item env:FREI0R_PATH -value "C:\Program Files (x86)\frei0r\lib\frei0r-1"

# whyさんのアイコン画像を取ってきたものをC:\tmp\whywaita.pngとします
export WHYWAITA_IMG="C:\tmp\whywaita.png"

# OpenCVで顔認識に使われているカスケードファイルをC:\opencv\build\etc\haarcascades\haarcascade_frontalface_default.xmlにあるとします
export CASCADE_FILE="C:\opencv\build\etc\haarcascades\haarcascade_frontalface_default.xml"


$ ffmpeg -i INPUT.mp4 -vf "frei0r=whywaita" OUTPUT.mp4

カスケードファイルをアニメ顔を認識するものに変更すると2次元でも顔認識してくれます。

ultraist.hatenablog.com

全人類whywaita計画

実際にwhywaitaフィルタをかけた画像、動画をご覧ください。

f:id:suzuzusu:20161221160805j:plain

f:id:suzuzusu:20161221160816j:plain

f:id:suzuzusu:20161221160822j:plain

f:id:suzuzusu:20161221160826j:plain

f:id:suzuzusu:20161221160830j:plain

f:id:suzuzusu:20161221160833j:plain

僕の同期のbenevolent0505もwhywaitaになりました。最初はかなりはしゃいで協力してくれたんですが顔をあまり動かすと顔として認識にてくれなくなるので結局かなりおとなしい動画になってしまいました。あと途中で飽きたと言ってテンション自体もかなり下がってしまいました。ちなみにフレームごとに検査したので顔ばれしているフレームは除去しました。

さいごに

今回はカスケード分類器という特徴量ベースの顔認識を行いましたが動画などを見てみるとわかると思いますが顔でないものを顔と認識したり精度の面でかなり難があります。最近は猫も杓子もDeepLearningしているみたいなのでDeepLearningを用いたwhywaitaフィルタを作れたらいいかなと少し思いました。

ffmpegとFrei0r

windows環境でFrei0rをffmpegで使うための実行環境設定備忘録

ffmpegにはfrei0r対応のバイナリをBuilds - Zeranoe FFmpeg から持ってくる

visual studioでビルドしようとしたがうまく行かなったのでmingwでビルドする

TDM-GCC : Download, Download | CMake からTDM-GCC, cmakeをインストールする

Index of files.dyne.org/frei0r/ からfrei0r持ってくる

frei0rのディレクトリで以下のコマンドを実行する

cmake -G "MinGW Makefiles"
mingw32-make.exe
mingw32-make.exe install

成功するとC:/Program Files (x86)/frei0r が出来上がるのであとは以下のようにすれば使用することができる

# frei0rのdllの場所を環境変数にセットする
Set-Item env:FREI0R_PATH -value "C:\Program Files (x86)\frei0r\lib\frei0r-1"
# frei0rのフィルターはfrei0r=hogefugaでセットする
ffplay -f lavfi -i mandelbrot -vf frei0r=sobel

ちなみにwindowsffmpegでinputをwebcameraにする方法も記述する

# 使えるカメラが表示される
ffmpeg -list_devices true -f dshow -i dummy

# 私の環境下ではLogicool HD Pro Webcam C920を用いた
ffplay -f dshow -i video="Logicool HD Pro Webcam C920"  -vf frei0r=cartoon

MATLABの無名関数で分岐処理

MATLABでmap処理したいときに無名関数で分岐処理したいなと思ったら三項演算子もないしif文も使えないしどうすればいいのか調べてたらどうやらfeval使えばいいみたいなので使い方を忘備録として書く。

どうやらMATLABの無名関数は副作用のない純粋関数として設計されているらしい。

% 奇数の場合0を返し偶数の場合2倍にして返す関数
f = (@(num) ...
    feval((@ (list, index) list{index}), ...
             {0, num*2}, ...
             ( (mod(num, 2)==1)*1 + (mod(num, 2)==0)*2 )));

% arrayfunで配列の要素にfを適用させる
result = arrayfun(f, 1:100);

(mod(num, 2)==1)*1 + (mod(num, 2)==0)*2この奇数の場合1を返し偶数の場合1を返す式をindexとして{0, num*2}のcell配列に添え字としてアクセスしている。

参考

関数の計算 - MATLAB feval - MathWorks 日本

配列内の個々の要素に関数を適用 - MATLAB arrayfun - MathWorks 日本

constexprにおけるused before its definition

C++のconstexprで少し詰まったので忘備録として書く。

// mylib.h
constexpr int square(int x);
// mylib.cpp
#include "mylib.h"

constexpr int square(int x){
    return x*x;
}
// main.cpp
#include "mylib.h"

int main(){
    constexpr int result = square(5);
    static_assert(result == 25, "error");
    return 0;
}

上記のC++によくあるようなファイル構成のものをGCC5.3.0で-std=c++11オプションをつけてコンパイルしようとすると‘constexpr int square(int)’ used before its definitionというエラーが吐かれる。原因は以下に記述する。

N2235の4.1より

A constant expression function must be defined before its first use.

// N2235にあるサンプルコード

struct S {
    constexpr int twice();
    constexpr int t();
    private:
    static constexpr int val; // constexpr variable
};

constexpr int S::val = 7;
constexpr int S::twice() { return val + val; }
constexpr S s = { };
int x1 = s.twice(); // ok
int x2 = s.t(); // error: S::t() not defined
texpr int ff(); // ok
constexpr int gg(); // ok
int x3 = ff(); // error: ff() not defined
constexpr int ff() { return 1; } // too late
constexpr int gg() { return 2; }
int x4 = gg(); // ok

原因は分かったがどんなファイル構成にすればいいのかイマイチ分からない。 誰か教えてほしい。

include "mylib.h"ではなくinclude "mylib.cpp"にするとか(?)

参考

stackoverflow.com

stackoverflow.com

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2235.pdf