前回は【さん山目】で、JetsonTK1 上で、既存ツールにより、FullHDのキャプチャーが行えるところまで確認できました。今回は、我々のデモアプリでキャプチャーすべくJetsonTK1上でのビルドを行おう、というところからです。
【よん山目】OpenCV またお前か!
我々のデモアプリ、ARM上でのビルドはすんなり通りました、そして、いよいよドキドキの瞬間です。ちなみに、デモアプリを動作させる機器構成図は、こんな感じです。
諸々接続も完了し、まずはVGAサイズでデモアプリの起動を確認、順調に動作しています。次に、iniファイルの設定をFullHDに変更して起動すると、何やら画面が真っ黒になって、WindowサイズもVGAのままです、、、ここでまた一同に動揺の色が走ります。詳しくは書きませんが、デバッグライトを入れたり様々設定の組み合わせで対照実験を行ったりした結果、以下の結論に至りました。
OpenGLとCUDAが有効なOpenCVのHighguiとV4L2を組み合わせるとキャプチャサイズの変更ができない
(*) V4L2 … Video for Linux 2
これはつまり、以下に記すOpenGL+Highguiでのビデオキャプチャの定番中の定番コードが、VGA以外のサイズでは、使えないんだよ、ということを意味しています。
VideoCapture cap(0); // デフォルトカメラをオープン
namedWindow("Sample",1);
for(;;) {
Mat frame;
cap >> frame; // カメラから新しいフレームを取得
imshow("Sample ", frame);
}
正確には、我々のデモは、GpuMatを使用しているので、上記とはコードが若干異なりますが、肝としては、
cap >> frame
が、使えないということが重要で、このシンプルな1行の影に、それはもう沢山の処理が隠れていたというわけです。
ちょっと休憩
さて、ご山目を登る前に、少し作戦会議をしましょう。上記問題を解決するには、いくつかの作戦が考えられます。
- OpenCVをデバッグする
- V4L2をgstreamer に変える
- highguiを諦める(≒ cap >> frame を捨てる)
(1)は極めて王道な作戦ですが、とてもそんな時間はありません。(2)と(3)は、全部を組み合わせるとダメなのだから、どれかを諦めようという作戦で、今回のデモでは、OpenGLとCUDAは必須なので、それ以外のどちらかを諦めることを考えます。
(2)はちょっと試してみたところ、例によってビルドの問題にぶつかったので、スルーしました。それで、(3)の作戦をとらざるを得なかったわけですが、ここで天啓が閃きます。V4L2のキャプチャツールとして、luvcview ではFullHDでのキャプチャが正しく動作しているではないかと!!
(*注) 当時の環境は、L4T19.3+OpenCV2.4 でした。現在ではL4T19.3+OpenCV3.0の組み合わせで、上記問題が解決されていることを確認しています。
【ご山目】神さま仏さま luvcviewさま
luvcviewさまの存在に気がついた後とあっては、ご山目の山はそう高いものではありませんでした。luvcview のソースコードを参考にして、V4L2 のドライバを ioctl で直接叩くことで、無事にFull HDのビデオキャプチャを行うことができました。
【ろく山目】USB2.0のWebCAM遅いぞ問題
ビデオキャプチャが行えるようになったのですが、デフォルトの YUV422のフォーマットでキャプチャするとあまりに遅い。WebCAM のマニュアルにも、MotionJPEGならFull HDで30fps出るけど、YUV422だと数fpsしか出ないと書いてあります。だったらということで、いったんMotionJPEGでキャプチャして、アプリ内でYUV422に変換するよう手を入れました。
GTC2014については、ここまでの工夫でタイムアップ。一応、無事に当日の展示を行うことができました。
To Be Continued !!