動画サイトに色々と動画あがってるけども、再生してみないとどんな動画かわかんない。
そこで、自動でやりたい。
1, クローラで巡回して
2, OpenCvあたりでよさげな手法で解析して
3, 分析した結果をRで解析して
4, 一枚の静止画見るだけで、動画の内容がどんなもんか予測つくようにしたい
1はきっとpythonあたりでくるくる回せばよさげなのでスルー。
というわけで、2から順番に
2, OpenCVで解析
こんな感じ。半分くらいはサンプルコードのまんまかもしれません。
vector<MatND> hist(3);
const int hist_size = 256;
const int hdims = {hist_size};
const float hranges = {0,256};
const float* ranges = {hranges};
double max_val = .0;
if( sch==1 ) {
// シングルチャネル
calcHist(&src_img, 1, 0, Mat(), hist[0], 1, hdims, ranges, true, false);
minMaxLoc(hist[0], 0, &max_val);
} else {
// マルチチャネル。全プレーンのヒストグラムを求める
for(int i=0; i<sch; ++i) {
calcHist(&src_img, // 入力配列
1, // 入力配列の個数
&i, // ヒストグラムを求める対象のチャネル
Mat(), // オプションマスク
hist[i], // 出力されるヒストグラム
1, // ヒストグラムの次元数(32未満を指定すること)
hdims, // 各次元のヒストグラムの配列
ranges, // ヒストグラムのビンの境界
true, // ヒストグラムが一様か否か
false); // ヒストグラムの累積計算を行うかどうか
double tmp_val;
minMaxLoc(hist[i], 0, &tmp_val);
max_val = max_val < tmp_val ? tmp_val : max_val;
}
}
// R言語での集計を行うために、csv形式でファイルへ出力をする
// 出力形式
// "hist0.csv", "hist1.csv", "hist2.csv"
char * hist_filename = {"hist0.csv", "hist1.csv", "hist2.csv"};
for(int ri=0; ri<sch; ri++) {
// ヒストグラム出力用ファイルを開く
const char* filename = hist_filename[ri];
FILE* fp = fopen(filename, "w");
if(fp == NULL){
printf("file open error \n");
}
// ヒストグラムを出力する
// 出力形式= "index, hist"
for(int rj=0; rj<hist_size; ++rj) {
float h = hist[ri].at<float>(rj);
fprintf(fp, "%d,%0.3f\n", rj, h);
}
// 忘れずに閉じること
fclose(fp);
}
これで"hist0.csv", "hist1.csv", "hist2.csv"というファイルにcsv形式で画像のヒストグラム情報が吐き出される。
動画の場合は、どうしよう。ヒストグラムのデータがもっと大量になるのかな。フレーム単位とか。
これをRで読み込んでぐりぐりと分析。
とりあえずコード。
args <- commandArgs();
# 5番目まではユーザーが渡したデータ以外のものが格納されている
filename <- args[5+1];
histgram <- read.csv(filename, header=F, col.names=c("index", "hist") );
jpeg("hist.jpg")
plot(histgram, type="l")
dev.off()
Rの起動方法。
上記プログラムがTestProg.Rという名前で保存されている場合、
こんな感じで起動する。引数にファイル名を渡す。
$ Rscript TestProg.R hist2.csv
結果:
思った以上に簡単にできた。
今回はヒストグラムだけしか出せなかったけど、ほかの手法も色々と試してみたい。、
あとは時間みながら動画の対応とクローラの実装進めていきたいね。