サブタイトル:「mer2のマイノリティ・レポート(笑)」 --- 最近忍者ブログの仕様が変わったようで、一部の画像が見えなくなってますが、画像のURLコピペで見られます。(どうしよう困ったな) --- ご用件など、ございましたらtwitterまでどうぞ。
ARToolKitをインストールする時に一緒にDSVLというのをインストールする。これがちょっと謎だ。「DirectShow Video Processing Library」の略らしい。美味しそうな名前でしょ。
付属のREADME.txtに載っているアドレスは繋がらない。ぐぐっても配布元の情報は見つからない。終ってしまったプロジェクトなのでしょうか。
解凍ファイルを覗いてみると、「DSVL\media」内に「cube_left.avi」、「cube_right.avi」というのが入っている。どう見てもステレオ動画ですね。ちゃんとステレオ再生可能でした。これはいったいどういう事なの?
とても気になるのでビルドしてみると、「atl*.hが無い」というエラーが出る。どうやらこれはATLって奴を使うみたい。ついに当たっちゃったよ。いろいろやってみたけどVisual C++ 2008 Express Editionではビルドは無理そうです。あきらめました。くすん。
そもそもDSVLってARToolKitで使ってるの?サンプルでは使ってなさそうなかんじなんだけど。
DSVLをビルドすると、ATL関連以外に「streams.hが無い」というエラーが出ます。調べるとこれはWindows SDKの「samples」内の「BaseClasses」に含まれているようです。
Visual C++ 2008 Express Editionをインストールすると、一緒にWindows SDKもインストールされますが、このWindows SDKには「samples」が入っていません。どうも簡略版Windows SDKのようです。
という訳でフルバージョンのWindows SDKをインストールしてみました。ここからダウンロードできます。「Windows SDK for Windows Vista」なんていう名前になってますが、XPでもオーケーです。isoイメージなのでDVDに焼くなり仮想化ソフトなりが必要です。Daemon Toolsを使いました。あら、最近はこの手のソフトはアドウェアが入ったりして色々といやらしくなってるのね。昔にダウンロードしたのを使いました。
ちょっと不安だったので、以前の
\Program Files\Microsoft SDKs
を
\Program Files\0000_Microsoft SDKs_0000
にリネームしてからインスールしました。これなら以前の同梱版Windows SDKはそのまま残るので安心でしょう。まあ必要無かったみたいだけど。
インストールすると、以前の環境がそのまま引き継がれるようです。フルバージョン用の設定も無しに、以前どおりにそのまま使えています。
「samples」もしっかり入っていますし、「GraphEdit」も入っていました。ああ、やっと正式版のGraphEditが手に入った。
んで、「samples」内のサンプルプログラムですが、Visual C++ 2008に合わせてリライトされています。いくつか試してみたところでは、全部slnファイルダブルクリックのビルド一発で警告も無しに通ってしまいました。あー気持ちいい。
以前のPlatform SDKに付いてた「samples」は、makefile仕様な上にサンプルソースをVisual Cの仕様変更に合わせて修正しなければコンパイルが通らないという最高に楽しいシロモノで、これをネタに解説記事をいっぱい書く予定だったのですが、後回しにしてて良かった。手間が省けました。
はっきり言って、フルバージョンのWindows SDKはオススメです。「samples」フォルダはお宝ざっくざくです。
Visual C++ 2008 Express Editionな人は絶対にインストールしましょう。
参考:
BaseClasses のコンパイル
「CAMSchedule 構文エラー」が出たら、
Base classes compile problem with Vista SDK - MSDN Forums
BaseClassesインクルードディレクトリをwindows SDKより上に置くと解決。うぎゃー!
付属のREADME.txtに載っているアドレスは繋がらない。ぐぐっても配布元の情報は見つからない。終ってしまったプロジェクトなのでしょうか。
解凍ファイルを覗いてみると、「DSVL\media」内に「cube_left.avi」、「cube_right.avi」というのが入っている。どう見てもステレオ動画ですね。ちゃんとステレオ再生可能でした。これはいったいどういう事なの?
とても気になるのでビルドしてみると、「atl*.hが無い」というエラーが出る。どうやらこれはATLって奴を使うみたい。ついに当たっちゃったよ。いろいろやってみたけどVisual C++ 2008 Express Editionではビルドは無理そうです。あきらめました。くすん。
そもそもDSVLってARToolKitで使ってるの?サンプルでは使ってなさそうなかんじなんだけど。
DSVLをビルドすると、ATL関連以外に「streams.hが無い」というエラーが出ます。調べるとこれはWindows SDKの「samples」内の「BaseClasses」に含まれているようです。
Visual C++ 2008 Express Editionをインストールすると、一緒にWindows SDKもインストールされますが、このWindows SDKには「samples」が入っていません。どうも簡略版Windows SDKのようです。
という訳でフルバージョンのWindows SDKをインストールしてみました。ここからダウンロードできます。「Windows SDK for Windows Vista」なんていう名前になってますが、XPでもオーケーです。isoイメージなのでDVDに焼くなり仮想化ソフトなりが必要です。Daemon Toolsを使いました。あら、最近はこの手のソフトはアドウェアが入ったりして色々といやらしくなってるのね。昔にダウンロードしたのを使いました。
ちょっと不安だったので、以前の
\Program Files\Microsoft SDKs
を
\Program Files\0000_Microsoft SDKs_0000
にリネームしてからインスールしました。これなら以前の同梱版Windows SDKはそのまま残るので安心でしょう。まあ必要無かったみたいだけど。
インストールすると、以前の環境がそのまま引き継がれるようです。フルバージョン用の設定も無しに、以前どおりにそのまま使えています。
「samples」もしっかり入っていますし、「GraphEdit」も入っていました。ああ、やっと正式版のGraphEditが手に入った。
んで、「samples」内のサンプルプログラムですが、Visual C++ 2008に合わせてリライトされています。いくつか試してみたところでは、全部slnファイルダブルクリックのビルド一発で警告も無しに通ってしまいました。あー気持ちいい。
以前のPlatform SDKに付いてた「samples」は、makefile仕様な上にサンプルソースをVisual Cの仕様変更に合わせて修正しなければコンパイルが通らないという最高に楽しいシロモノで、これをネタに解説記事をいっぱい書く予定だったのですが、後回しにしてて良かった。手間が省けました。
はっきり言って、フルバージョンのWindows SDKはオススメです。「samples」フォルダはお宝ざっくざくです。
Visual C++ 2008 Express Editionな人は絶対にインストールしましょう。
参考:
BaseClasses のコンパイル
「CAMSchedule 構文エラー」が出たら、
Base classes compile problem with Vista SDK - MSDN Forums
BaseClassesインクルードディレクトリをwindows SDKより上に置くと解決。うぎゃー!
PR
[ 生録 ]焼肉マンボ
ちいっ、Windowsのサウンドレコーダーは1分しか録音できないのか。出直してやる。今日は「100円ショップミーツのテーマ」が流れてなかった。
このへんがもう最高なんだ。
詳しくはこちらをどうぞ。
ちいっ、Windowsのサウンドレコーダーは1分しか録音できないのか。出直してやる。今日は「100円ショップミーツのテーマ」が流れてなかった。
このへんがもう最高なんだ。
詳しくはこちらをどうぞ。
息抜きついでに、この記事の最後に書いたARToolkitをz800で立体視実験をやってみました。どうせ上手くいかないよ、とか思いながら。
デュアルモニター状態で、一方でARToolkitを表示+キャプチャーしつつ、さらに一方でz800でモニターできるようにしなくてはなりません。
nvidiaで言うところの「デュアルビュー」にします。z800の立体視はフルスクリーン必須なので、z800のVGAOUTに繋いであるCRTモニターをプライマリモニタに設定します。
セカンダリ: ARToolkit(サイドバイサイドで表示) ->
セカンダリ: ManyCam(キャプチャー) ->
プライマリ: Stereoscopic Player(ページフリップ化) ->
プライマリ: z800(立体視)
という流れで行ってみましょう。
あら、ManyCamはプライマリモニターしかキャプチャーできないみたい。キャプチャー範囲の枠がプライマリモニターの外に出てくれません。意外なManyCamの欠点を発見しました。
VH Screen Capture Driverを使うことにしました。こいつはかなり細かい取り込み指定ができる優秀なヤツです。でも心持ちManyCamのほうが取り込みレートが高かったので、私はManyCamをメインで使ってます。
VH Screen Capture Driverはプライマリモニターもセカンダリモニターも自由自在のようです。よしよし。取り込み範囲を設定。VH Screen Capture Driverはドット単位で取り込み範囲の微調整ができます。このへんは本当に良くできてます。
準備完了。Stereoscopic Playerをnvidaモードでフルスクリーンにします。
nvidaモードを発動すると、エラー発生。Direct Xうんぬんのエラーです。根が深そうです。ほら、やっぱり駄目だ。
それではと、Stereoscopic Playerをあきらめてステレオムービープレイヤーを使ってみることにします。結局、
セカンダリ: ARToolkit(サイドバイサイドで表示) ->
セカンダリ: VH Screen Capture Driver(キャプチャー) ->
プライマリ: ステレオムービープレイヤー(ページフリップ化) ->
プライマリ: z800(立体視)
となりました。
焦る私。でも表示が変です。画像は上半分中央にクォーター表示だし、ページフリップしてません。表示されているのは片目分だけです。いろいろ設定をいじっていたら、
z800で立体視版ARToolkitのリアルタイムモニターできちゃいました!
いまいち信頼性に欠ける証拠写真。クリックで拡大。
nvidaステレオドライバーのキャプチャーです。奥のCRTモニターがページフリップしてるでしょ。
どこがどうに作用してうまくいったのかをいまいち把握できていないので、設定画面をそのまま載せときます。
VH Screen Capture Driverの設定
ステレオムービープレイヤーの設定
できることはできましたが、320x240を800x600にスケーリングしている上に、z800とステレオムービープレイヤーの相性の悪さも手伝って、画像はガチャガチャです。今の環境にはまだ必殺技も仕込んでないし。
おまけにかなり重くなっています。ステレオドライバー発動前でARToolkitのfpsは5~6ぐらい。ステレオドライバー発動でもうちょっと重くなっているかんじです。
まあ、いちおうできましたよっ、程度のものです。いやできるとは思ってなかったんだけど。
しかし落胆するのはまだ早い。実はz800SDKのサンプルプログラムには「Sample_OpenGL_StereoVision」というのが入っています。これ のOpenGL版みたいなもんだと思われます。もちろんglut使ってます。これはもしかするともしかします。
[ステレオドライバーを使わずに、ARToolkitのプログラムから直接立体視ができてしまうかもしれません。](自信が無いのでステルスモード。)
試しにビルドしてみましたが、やはり一発ビルドは無理のようです。ああ、茨の道が。しかしここは一発、z800の明るい未来の為に頑張ってみたいと思っています。
デュアルモニター状態で、一方でARToolkitを表示+キャプチャーしつつ、さらに一方でz800でモニターできるようにしなくてはなりません。
nvidiaで言うところの「デュアルビュー」にします。z800の立体視はフルスクリーン必須なので、z800のVGAOUTに繋いであるCRTモニターをプライマリモニタに設定します。
セカンダリ: ARToolkit(サイドバイサイドで表示) ->
セカンダリ: ManyCam(キャプチャー) ->
プライマリ: Stereoscopic Player(ページフリップ化) ->
プライマリ: z800(立体視)
という流れで行ってみましょう。
あら、ManyCamはプライマリモニターしかキャプチャーできないみたい。キャプチャー範囲の枠がプライマリモニターの外に出てくれません。意外なManyCamの欠点を発見しました。
VH Screen Capture Driverを使うことにしました。こいつはかなり細かい取り込み指定ができる優秀なヤツです。でも心持ちManyCamのほうが取り込みレートが高かったので、私はManyCamをメインで使ってます。
VH Screen Capture Driverはプライマリモニターもセカンダリモニターも自由自在のようです。よしよし。取り込み範囲を設定。VH Screen Capture Driverはドット単位で取り込み範囲の微調整ができます。このへんは本当に良くできてます。
準備完了。Stereoscopic Playerをnvidaモードでフルスクリーンにします。
Stereoscopic PlayerにHYTEK General Stereo 3D Camera Driverを直接接続テストしてみると、320x240ならSoftware Pageflippingオーケーでしたが、640x480だとSoftware Pageflippingに破綻が生じてしまいまっていました。
そんな訳で、このケースではSoftware Pageflippingを使うのはまず無理でしょう。
nvidaモードを発動すると、エラー発生。Direct Xうんぬんのエラーです。根が深そうです。ほら、やっぱり駄目だ。
それではと、Stereoscopic Playerをあきらめてステレオムービープレイヤーを使ってみることにします。結局、
セカンダリ: ARToolkit(サイドバイサイドで表示) ->
セカンダリ: VH Screen Capture Driver(キャプチャー) ->
プライマリ: ステレオムービープレイヤー(ページフリップ化) ->
プライマリ: z800(立体視)
となりました。
あれ、nvidaモードでフルスクリーンできちゃったぞ。
焦る私。でも表示が変です。画像は上半分中央にクォーター表示だし、ページフリップしてません。表示されているのは片目分だけです。いろいろ設定をいじっていたら、
おい、できちゃったよ。
z800で立体視版ARToolkitのリアルタイムモニターできちゃいました!
いまいち信頼性に欠ける証拠写真。クリックで拡大。
nvidaステレオドライバーのキャプチャーです。奥のCRTモニターがページフリップしてるでしょ。
どこがどうに作用してうまくいったのかをいまいち把握できていないので、設定画面をそのまま載せときます。
VH Screen Capture Driverの設定
ステレオムービープレイヤーの設定
できることはできましたが、320x240を800x600にスケーリングしている上に、z800とステレオムービープレイヤーの相性の悪さも手伝って、画像はガチャガチャです。今の環境にはまだ必殺技も仕込んでないし。
おまけにかなり重くなっています。ステレオドライバー発動前でARToolkitのfpsは5~6ぐらい。ステレオドライバー発動でもうちょっと重くなっているかんじです。
まあ、いちおうできましたよっ、程度のものです。いやできるとは思ってなかったんだけど。
しかし落胆するのはまだ早い。実はz800SDKのサンプルプログラムには「Sample_OpenGL_StereoVision」というのが入っています。これ のOpenGL版みたいなもんだと思われます。もちろんglut使ってます。これはもしかするともしかします。
[ステレオドライバーを使わずに、ARToolkitのプログラムから直接立体視ができてしまうかもしれません。](自信が無いのでステルスモード。)
試しにビルドしてみましたが、やはり一発ビルドは無理のようです。ああ、茨の道が。しかしここは一発、z800の明るい未来の為に頑張ってみたいと思っています。
ARTookitヤバいです。次から次へと怪しい考えがうかんできます。お風呂に入っていたらまた怪しい考えがピーンと来ました。簡単に実験できそうな考えだったので、早速お風呂上がりにすっぱだかでコーディングです。
こんなんでました。このへんの過程で作成した640x240なステレオglut画像ベタデータファイルをマイクロポール対応なベタデータファイルに変換します。なんのこたあない1ライン毎に左右の画像を入れ替えただけです。
「test.c」ってのがそれです。例によって汎用性ゼロの定数埋め込みバリバリプログラムです。ごめんなさい。慎重こいて1バイトずつ処理してるので、すごく時間がかかります。ごめんなさい。
コンパイルは「Visual Studio 2008 コマンド プロンプト」から
> cl test.c
でいけます。
同じフォルダに有る「source.dat」を「file_00001.dat」に変換します。「file_00001.dat」は
この記事の最後でアップしてあるzipの中の「gltobmp_test.cpp」でbmpファイルに変換できます。
こんな画像が、こんなになります。都合良く右側と左側のインターレース配置が逆配置になっているので、適当に表示してもどちらかが立体視できるはずです。
という訳で、おなじみROVER416Tさんに実験していただきました。いつも御協力ありがとうございます。結果はご覧のとおりです。ニタニタぐふふ。
この変換を立体視版ARToolkitのプログラム中で行って、変換結果のほうを表示させるようにすれば、マイクロポールモニター上で立体視版ARToolkitのリアルタイムモニターができるはずです。
多分表示位置のY座標が偶数か奇数かによって、インターレース配置を振り分ければいいんじゃないかなと思われます。
面白そうでしょ?誰かやりませんか?私はマイクロポールモニター持ってない上に他にやりたい事がいっぱいいっぱいなので、いまいち優先度が低いのです。
こんなんでました。このへんの過程で作成した640x240なステレオglut画像ベタデータファイルをマイクロポール対応なベタデータファイルに変換します。なんのこたあない1ライン毎に左右の画像を入れ替えただけです。
「test.c」ってのがそれです。例によって汎用性ゼロの定数埋め込みバリバリプログラムです。ごめんなさい。慎重こいて1バイトずつ処理してるので、すごく時間がかかります。ごめんなさい。
コンパイルは「Visual Studio 2008 コマンド プロンプト」から
> cl test.c
でいけます。
同じフォルダに有る「source.dat」を「file_00001.dat」に変換します。「file_00001.dat」は
この記事の最後でアップしてあるzipの中の「gltobmp_test.cpp」でbmpファイルに変換できます。
こんな画像が、こんなになります。都合良く右側と左側のインターレース配置が逆配置になっているので、適当に表示してもどちらかが立体視できるはずです。
という訳で、おなじみROVER416Tさんに実験していただきました。いつも御協力ありがとうございます。結果はご覧のとおりです。ニタニタぐふふ。
この変換を立体視版ARToolkitのプログラム中で行って、変換結果のほうを表示させるようにすれば、マイクロポールモニター上で立体視版ARToolkitのリアルタイムモニターができるはずです。
多分表示位置のY座標が偶数か奇数かによって、インターレース配置を振り分ければいいんじゃないかなと思われます。
面白そうでしょ?誰かやりませんか?私はマイクロポールモニター持ってない上に他にやりたい事がいっぱいいっぱいなので、いまいち優先度が低いのです。
デスクトップキャプチャーでARToolkitの動画を作るのにどうも抵抗が有ったんです。面倒だし、なんかオシャレじゃないじゃないですか。どうせやるんだったら一つのプログラムで済ませたほうがオシャレです。更にステレオ撮影の場合はカメラ2台使うのでCPUの負荷が上ります。余計なソフトはできるだけ動かしたくないんです。
んで、ARToolkitのプログラムからダイレクトに動画を作れないもんかなと調べてみましたが、どうも今の私には難しそうです。まあそんな事ほえっとできてたら、ステレオ動画撮影のプログラムなんかとっくにできてますよね。今後の課題として勉強しようと思います。誰かダイレクトに動画作れてる人はいませんか。いたらソースください。
だったら各フレームの画像をキャプチャーしておいて、後からffmpeg技なりで動画にすればいいんじゃないかな、と考えました。ARToolkitのソースを眺めてみると、最終的な画面出力はglut関係でやっているようです。そっち関係を調べてみたら、glutを使った画面キャプチャの方法がソース付きでそのまんま有りました。
[OpenGL] Bitmapファイルへの書き出し
ここの「010-GLUTsaveBMP.zip」ってやつです。
これをそのまんまビルドすると、
exit' : 再定義 ; __declspec(noreturn) が異なります。
というエラー。V+Cのstdlib.hとglut.hでexitの定義がダブっているようです。
GLUTsaveBMPのフォルダ内にstdlib.hをコピーして、
//_CRTIMP __declspec(noreturn) void __cdecl exit(_In_ int _Code);
//_CRTIMP __declspec(noreturn) void __cdecl _exit(_In_ int _Code);
とコメントアウトして、main.cppを
#include "stdlib.h"
としたら通りました。ちゃんと動いてます。glutのスクリーンキャプチャができてしまいました。きゃっほー!
早速応用しましょう。simpleLiteのソースフォルダに
Bitmap.cpp
Bitmap.h
をコピーして、
「simpleLite.c」の
頭のほうに
#include "Bitmap.h"
キー入力のところに
case 'B':
case 'b':
WriteBitmap("output.bmp",640,480);
break;
を追加して、
simpleLiteのプロジェクトに
「Bitmap.cpp」
を追加。それから「simpleLite.c」を「simpleLite.cpp」にリネーム。そうしないと「Bitmap.cpp」を一緒にビルドしてくれません。何故か上のexit関連のエラーは出ませんでした。
これでARToolkitの画面キャプチャができてしまいました!"B"キーを押すとファイル名「output.bmp」で一画面キャプチャーします。mer2さん大笑い海水浴場。
したらば連続フレームをキャプチャーできるようにしてしまいましょう。
変数追加
int flg=0;
int count=0;
char filename[20];
Bキーでフラグ
case 'B':
case 'b':
if (flg) flg=0; else flg=1;
// WriteBitmap("output.bmp",640,480);
break;
このへんでいいんじゃないかな。Display()内。
if (flg) {
sprintf( filename, "file_%05d.bmp",count);
WriteBitmap( filename,640,480);
count++;
}
glutSwapBuffers();
"B"キーを押してからもう一度押すまでの間の各フレームが「file_00000.bmp」からの連番でキャプチャーされます。キャプチャー中は凄く重くなるけど、そんなのは想定内よ。後でなんとかするから。
連番ファイルを動画にするのはffmpegを使います。
> ffmpeg -r 10 -i file_%05d.bmp -sameq test.avi
この時、大笑海水浴場がピークに逹っしました。
ディスクアクセスを軽くしようとRAM DISKを導入してみました。まあこれは結果的に無駄足だったので不要な手順なのですが、RAM DISK使用レポということで。RAM DISK使ってみたかったんです。
ERAM for Windows:正式版置き場
とりあえずベクターで星がいっぱいついてたから、これにしました。
参考:
EZ-NET レポート: RAM DISK を使ってみる
メモリ量がここのレポートと同じ3GBなのでちょうどよかった。
「simpleLite.cpp」内のbmpファイル名のみ書き換え。
sprintf( filename, "R:\\file_%05d.bmp",count);
RAM DISKはRドライブで固定。X68000の時からの伝統。X68000のRAM DISKドライバはリセットしても内容が残ってたんだけどなー。スペースハリアーやA-JAXやサンダーブレードをRAM DISKに転送すると、もう極楽だったっけ。
うむ、ちょっと軽くなった。でもまだ重いな。
Bitmap.cppをいじって、欲しい範囲[0,120-639,359]だけを取り込むようにしてみる。
頭のほうに追加。
width = 640;height = 240;
読み出し範囲を修正
glReadPixels(
// 0,0,
0,120,
width,height,
GL_RGB,
GL_UNSIGNED_BYTE,
pixel_data);
うん、かなり軽くなった。bmp作成の時のループがオーバーヘッドになっているようだ。
ならばbmp作成のループを無くしてしまおう。bmp化前の元画像データだけ保存しておいて、bmp化は後でやればいいのだ。
Bitmap.cppをさらに変更。
bmp作成の部分をまるごとコメントして、
fwrite( pixel_data, sizeof(GLubyte), (glByteWidth)*(height), fp);
を追加。
simpleLite.cpp内の保存ファイル名を
sprintf( filename, "R:\\file_%05d.dat",count);
とかにすると、RAM DISKに「file_?????.dat」の連番ベタ書きデータファイルができあがります。
うほっ、体感的にはキャプチャー中のフレームレートの変化が無くなりました。
Bitmap.cppをいじってベタ書きデータファイルをbmpファイルにするプログラムを作ります。下のzipにまとめときました。
「gltobmp_test.cpp」が一画面ベタ書きデータファイルを変換するプログラムです。めんどうなのでファイル名も画面サイズも固定です。Visual studioのプロジェクトを作るのも面倒だったので、コマンドラインからコンパイル仕様です。スタートメニューの「Visual Studio 2008 コマンド プロンプト」から
> cl tobitmap_test.cpp
でいけます。
でもglut関係の関数はコマンドラインなプログラムだと(?)エラーになってしまうみたいです。だからglut関数がらみで計算される数値は定数にしてしまっています。という訳で全然汎用性はありません。ごめんなさい。
実行するとベタ書きデータファイルから"bmp"フォルダにbmpファイルを作成します。サンプルにベタ書きデータファイル「file_00001.dat」を一個入れときます。
今回の場合は、一画面あたり、
640*240*3(Byte) = 460800Byte
になってます。
まだ無駄な部分が有るので一気にまとめます。「simpleLite_Capture.c」です。
メインループ内の無駄な処理を外に出して、ベタ書きデータも一つのファイルにまとめて書き出してます。simpleLiteのソースフォルダに置けばビルドできると思います。
simpleLiteは"C"キーを押すと瞬間的fpsを見られますが、うちの環境では記録前も記録中も15fpsぐらいで安定してます。記録中はちょっと低めの数字が見られる程度です。
試しに最終バージョンでハードディスクに記録してみたら、RAM DISKとそんなに変わりないや。なんだ、RAM DISK要らなかったかな。
ファイルは追記モードで開いてますので、消すなりリネームするなりしないとどんどん追記されます。ご注意下さい。
ひとまとめなベタ書きデータを一気にbmpファイルに変換するのが「gltobmp.cpp」です。ほとんど「Bitmap.cpp」のWriteBitmap()をmain()にしただけです。例によって汎用性は有りません。ごめんなさい。
250MBのベタ書きデータを変換するのに一分ぐらいかかります。こりゃ重くなるわ。見ていて不安になるのでカウンターを付けました。
変換した大量のbmpファイルをffmpegで動画にまとめます。
> ffmpeg -r 10 -i file_%05d.bmp -sameq test.avi
とか、
> ffmpeg -r 29.7 -i file_%05d.bmp -b 1024k test.avi
とか。
カメラをゆっくり動かせば、30fpsなARToolkit動画も作れます。
なんだったら60fpsなんてのも作れます。
> ffmpeg -r 60 -i file_%05d.bmp -sameq test.avi
[ 動画 ]
100fpsなんてのも作れますが、リフレッシュレート100HzのCRTで見ても80fps再生になってしまいます。なんで?
> ffmpeg -r 100 -i file_%05d.bmp -sameq test.avi
[ 動画 ]
リフレッシュレート60Hzの液晶モニターではコマ落ち風再生になってしまいます。
120fpsは動画が上手く作れませんでした。
キャプチャー動画のコマ落ちが嫌な人、マシンがロースペックな人にはお勧めです。音とシンクロさせるような場合は駄目ですが。(いや、どうにかなる。(と思う。)) (多重括弧)
んで、ARToolkitのプログラムからダイレクトに動画を作れないもんかなと調べてみましたが、どうも今の私には難しそうです。まあそんな事ほえっとできてたら、ステレオ動画撮影のプログラムなんかとっくにできてますよね。今後の課題として勉強しようと思います。誰かダイレクトに動画作れてる人はいませんか。いたらソースください。
だったら各フレームの画像をキャプチャーしておいて、後からffmpeg技なりで動画にすればいいんじゃないかな、と考えました。ARToolkitのソースを眺めてみると、最終的な画面出力はglut関係でやっているようです。そっち関係を調べてみたら、glutを使った画面キャプチャの方法がソース付きでそのまんま有りました。
[OpenGL] Bitmapファイルへの書き出し
ここの「010-GLUTsaveBMP.zip」ってやつです。
これをそのまんまビルドすると、
exit' : 再定義 ; __declspec(noreturn) が異なります。
というエラー。V+Cのstdlib.hとglut.hでexitの定義がダブっているようです。
GLUTsaveBMPのフォルダ内にstdlib.hをコピーして、
//_CRTIMP __declspec(noreturn) void __cdecl exit(_In_ int _Code);
//_CRTIMP __declspec(noreturn) void __cdecl _exit(_In_ int _Code);
とコメントアウトして、main.cppを
#include "stdlib.h"
としたら通りました。ちゃんと動いてます。glutのスクリーンキャプチャができてしまいました。きゃっほー!
早速応用しましょう。simpleLiteのソースフォルダに
Bitmap.cpp
Bitmap.h
をコピーして、
「simpleLite.c」の
頭のほうに
#include "Bitmap.h"
キー入力のところに
case 'B':
case 'b':
WriteBitmap("output.bmp",640,480);
break;
を追加して、
simpleLiteのプロジェクトに
「Bitmap.cpp」
を追加。それから「simpleLite.c」を「simpleLite.cpp」にリネーム。そうしないと「Bitmap.cpp」を一緒にビルドしてくれません。何故か上のexit関連のエラーは出ませんでした。
これでARToolkitの画面キャプチャができてしまいました!"B"キーを押すとファイル名「output.bmp」で一画面キャプチャーします。mer2さん大笑い海水浴場。
したらば連続フレームをキャプチャーできるようにしてしまいましょう。
変数追加
int flg=0;
int count=0;
char filename[20];
Bキーでフラグ
case 'B':
case 'b':
if (flg) flg=0; else flg=1;
// WriteBitmap("output.bmp",640,480);
break;
このへんでいいんじゃないかな。Display()内。
if (flg) {
sprintf( filename, "file_%05d.bmp",count);
WriteBitmap( filename,640,480);
count++;
}
glutSwapBuffers();
"B"キーを押してからもう一度押すまでの間の各フレームが「file_00000.bmp」からの連番でキャプチャーされます。キャプチャー中は凄く重くなるけど、そんなのは想定内よ。後でなんとかするから。
連番ファイルを動画にするのはffmpegを使います。
> ffmpeg -r 10 -i file_%05d.bmp -sameq test.avi
この時、大笑海水浴場がピークに逹っしました。
ディスクアクセスを軽くしようとRAM DISKを導入してみました。まあこれは結果的に無駄足だったので不要な手順なのですが、RAM DISK使用レポということで。RAM DISK使ってみたかったんです。
ERAM for Windows:正式版置き場
とりあえずベクターで星がいっぱいついてたから、これにしました。
参考:
EZ-NET レポート: RAM DISK を使ってみる
メモリ量がここのレポートと同じ3GBなのでちょうどよかった。
「simpleLite.cpp」内のbmpファイル名のみ書き換え。
sprintf( filename, "R:\\file_%05d.bmp",count);
RAM DISKはRドライブで固定。X68000の時からの伝統。X68000のRAM DISKドライバはリセットしても内容が残ってたんだけどなー。スペースハリアーやA-JAXやサンダーブレードをRAM DISKに転送すると、もう極楽だったっけ。
うむ、ちょっと軽くなった。でもまだ重いな。
Bitmap.cppをいじって、欲しい範囲[0,120-639,359]だけを取り込むようにしてみる。
頭のほうに追加。
width = 640;height = 240;
読み出し範囲を修正
glReadPixels(
// 0,0,
0,120,
width,height,
GL_RGB,
GL_UNSIGNED_BYTE,
pixel_data);
うん、かなり軽くなった。bmp作成の時のループがオーバーヘッドになっているようだ。
ならばbmp作成のループを無くしてしまおう。bmp化前の元画像データだけ保存しておいて、bmp化は後でやればいいのだ。
Bitmap.cppをさらに変更。
bmp作成の部分をまるごとコメントして、
fwrite( pixel_data, sizeof(GLubyte), (glByteWidth)*(height), fp);
を追加。
simpleLite.cpp内の保存ファイル名を
sprintf( filename, "R:\\file_%05d.dat",count);
とかにすると、RAM DISKに「file_?????.dat」の連番ベタ書きデータファイルができあがります。
うほっ、体感的にはキャプチャー中のフレームレートの変化が無くなりました。
Bitmap.cppをいじってベタ書きデータファイルをbmpファイルにするプログラムを作ります。下のzipにまとめときました。
「gltobmp_test.cpp」が一画面ベタ書きデータファイルを変換するプログラムです。めんどうなのでファイル名も画面サイズも固定です。Visual studioのプロジェクトを作るのも面倒だったので、コマンドラインからコンパイル仕様です。スタートメニューの「Visual Studio 2008 コマンド プロンプト」から
> cl tobitmap_test.cpp
でいけます。
でもglut関係の関数はコマンドラインなプログラムだと(?)エラーになってしまうみたいです。だからglut関数がらみで計算される数値は定数にしてしまっています。という訳で全然汎用性はありません。ごめんなさい。
実行するとベタ書きデータファイルから"bmp"フォルダにbmpファイルを作成します。サンプルにベタ書きデータファイル「file_00001.dat」を一個入れときます。
今回の場合は、一画面あたり、
640*240*3(Byte) = 460800Byte
になってます。
まだ無駄な部分が有るので一気にまとめます。「simpleLite_Capture.c」です。
メインループ内の無駄な処理を外に出して、ベタ書きデータも一つのファイルにまとめて書き出してます。simpleLiteのソースフォルダに置けばビルドできると思います。
simpleLiteは"C"キーを押すと瞬間的fpsを見られますが、うちの環境では記録前も記録中も15fpsぐらいで安定してます。記録中はちょっと低めの数字が見られる程度です。
試しに最終バージョンでハードディスクに記録してみたら、RAM DISKとそんなに変わりないや。なんだ、RAM DISK要らなかったかな。
ファイルは追記モードで開いてますので、消すなりリネームするなりしないとどんどん追記されます。ご注意下さい。
ひとまとめなベタ書きデータを一気にbmpファイルに変換するのが「gltobmp.cpp」です。ほとんど「Bitmap.cpp」のWriteBitmap()をmain()にしただけです。例によって汎用性は有りません。ごめんなさい。
250MBのベタ書きデータを変換するのに一分ぐらいかかります。こりゃ重くなるわ。見ていて不安になるのでカウンターを付けました。
変換した大量のbmpファイルをffmpegで動画にまとめます。
> ffmpeg -r 10 -i file_%05d.bmp -sameq test.avi
とか、
> ffmpeg -r 29.7 -i file_%05d.bmp -b 1024k test.avi
とか。
カメラをゆっくり動かせば、30fpsなARToolkit動画も作れます。
なんだったら60fpsなんてのも作れます。
> ffmpeg -r 60 -i file_%05d.bmp -sameq test.avi
[ 動画 ]
100fpsなんてのも作れますが、リフレッシュレート100HzのCRTで見ても80fps再生になってしまいます。なんで?
> ffmpeg -r 100 -i file_%05d.bmp -sameq test.avi
[ 動画 ]
リフレッシュレート60Hzの液晶モニターではコマ落ち風再生になってしまいます。
120fpsは動画が上手く作れませんでした。
キャプチャー動画のコマ落ちが嫌な人、マシンがロースペックな人にはお勧めです。音とシンクロさせるような場合は駄目ですが。(いや、どうにかなる。(と思う。)) (多重括弧)
ソースコード(いーかげんです)
最新記事
(04/20)
(11/21)
(01/01)
(06/12)
(06/12)
(05/29)
(05/22)
(05/21)
(12/25)
(12/20)
最新コメント
[08/27 BernardSr]
[08/27 BernardSr]
[08/27 BernardSr]
[12/29 GroverIcow]
[12/26 gayenKinesl]
[12/25 gayenKincfv]
[12/25 geRoesonokp]
[12/24 geRoesonmxu]
[06/30 LindsayDom]
[06/24 Ayukupim]
[06/22 francinerj2]
[06/21 Karsewis]
[06/17 Porsulik]
[06/16 Porsulik]
[06/16 Porsulik]
[06/16 Amimior]
[06/15 WilfordMof]
[06/11 lakeishatb1]
[06/04 Mathewlomi]
[05/31 tiopomWarriorvrp]
[05/31 Lasdumor]
[05/29 Aredorer]
[05/27 IMPUCKICT]
[05/26 Asosans]
[05/24 RaymondZice]
カテゴリー
リンク
アーカイブ
アクセス解析
カウンター
カレンダー
01 | 2025/02 | 03 |
S | M | T | W | T | F | S |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
プロフィール
HN:
mer2
性別:
男性
趣味:
野良猫の餌付け