Octaveでdeformable part modelを使ってみる (2)

著者のページから最新のコードをダウンロードして展開します。
ディレクトリ内でoctaveを立ち上げ、まずmexでCファイルをコンパイルします。

$ cd voc-release4
$ octave
octave:1> mex dt.cc
octave:2> mex features.cc
octave:3> mex fconv.cc
octave:4> mex getdetections.cc
octave:5> mex resize.cc
resize.cc: In function ‘void resize1dtran(double*, int, double*, int, int, int)’:
resize.cc:46: error: ‘sy’ was not declared in this scope

resize.ccのコンパイルでエラーがでます。これは多分'sy1'の誤りですが、いずれにせよただのassertなのでコメントアウトしてもいいでしょう。

いよいよ、サンプルスクリプトのdemo.mを走らせてみます。バスの画像が表示されました。

しかし、次へ進むとエラーが出て落ちてしまいました。
HOGpicture.mの12行目で読んでるimrotateが原因とのこと。どうやらoctaveのimrotateでは補間方法をちゃんと書かないといけないようです。
以下のように修正します。

12   bim(:,:,i) = imrotate(bim1, -(i-1)*20, 'bilinear', 'crop');

すると、モデルが表示されるところまで行けるようになりました。論文とかでよく見るやつですね。

先へ進むとまた落ちてしまいます。今度はreduceboxes.mの33行目で代入の次元がおかしいといわれています。ただ、これはそもそもIの値が空(boxが見つからない)時に処理が進んでいるのが原因です。
(変数が空の時の処理はoctavematlabで異なるのでしょうか?matlab環境が手元にないので分かりません...)
以下のように、空の時は処理を飛ばすようにします。

 18   % process boxes for component i
 19   I = find(boxes(:,end-1) == i);
 20   if isempty(I)
 21     continue
 22   end
 23   tmp = boxes(I,:);

これでようやく検出結果が表示されるようになりました。

Bounding boxはこんな感じ。

しかし安心したのも束の間、次のpersonの例のbox描画部でまた落ちてしまいます。
showboxes.mの76行目のlineで怒られています。
octaveのlineでは、座標が配列でまとめて与えられるとまずいようです。なので、今回のように検出対象が複数だと問題が起こってしまいます。
仕方ないので地道にfor文で書き換えます。

for j = 1:size(x1,1)
  line([x1(j) x1(j) x2(j) x2(j) x1(j)], [y1(j) y2(j) y2(j) y1(j) y1(j)], 'color', c, 'linewidth', cwidth, 'linestyle', s);
end

これでめでたく3例ともきちんと動くようになりました。(まだ表面化していない不具合はあるかもしれませんが...)

追記

fconvはマルチスレッドのものをコンパイルしたほうが速いです。

octave:1> mex fconvMT.cc -o fconv