- ベストアンサー
動画処理のライブラリについて
現在WindowsのVC++で動画ファイル(.avi)に画像処理を行いたいと思っています。 もう少し具体的に述べますと、.aviファイルを読み込み、その映像にエッジ抽出や差分画像抽出などの画像処理を施して、画像処理された新たな.aviファイルを出力するというものです。 しかし、1から画像処理プログラミングを行うほどの知識もなく、どうすれば…と思っていたところ、OpenCVなど画像処理ライブラリというものがあることを知りました。 それを用いて.bmpなどの静止画像のエッジを取ったりというような処理はなんとなくわかったのですが、.aviファイルなどの動画ファイルに対する画像処理の方法がよくわからないのです。 動画というものは静止画の集合なので、動画像処理は静止画像処理を連続的に行えばよいと耳にしたのですが、これは正しいのでしょうか? もし正しいのであれば、.avi動画ファイルにたいして連続的な静止画処理を行い、また.aviファイルを出力するということはOpenCVを用いてできるのでしょうか? また、そういったことが詳しく解説されている書籍や日本語サイトなどがあれば教えていただけませんでしょうか。 素人の質問ではありますが、皆様どうぞよろしくお願いいたします。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
>上記のプログラムのどの部分を変更してVC++にコピーして実行すれば動くものなのでしょうか? とりあえずOpenCVをダウンロードしてビルドしなければいけません。それでビルドが通ると"なんとか.lib"や"なんとか.dll"が生成されて、それをリンクして自分のプログラムを書く形になります。VCの人のためにビルド用プロジェクトが用意してあるのですが、私の環境(VC6)では一発でコンパイル通りませんでしたので、いろいろコメントアウトしながらだましだましやりました。とてもめんどくさいです。 下のソースの場合はhighgui.libとcvcam.libを同じフォルダにコピーしてきます。あとは”なんとか.dll”が無いよと言われるので、それも探してきて配置します。 >size.width = ***; >size.height = ***; に入力データのピクセルサイズを入れてやります。 >(double)***, // fps指定 のところは 30.0 とか書いとけばとりあえずOK. ところで下のソース、致命的な欠点がありました。ファイル読み書きと再生はできるのですが、まともに画像処理ができませんでした。 imageの中にフレームのメタデータは入ってくるのですが、実画像データが入ってこないです(入れる場所はあるんだけどNULLになってる)。 なので試しにこれをOpenCVで画像変換しようとするとエラーになり、いまのところお手上げ系です。ビデオメモリの中にバッファを確保してる系かもしれません。 VFWはVCのデフォルト状態で #include "vfw.h" #pragma comment (lib, "vfw32.lib") とするだけでいいので導入がすごく楽です。 あと、システムメモリ上にビットマップデータがちゃんと入ってきますので、あとはそれをOpenCV互換な形(IplImage構造体)に直してやります。 >動画処理やOpenCVに関するサイトや書籍 昨日見つけたんですがここ http://chihara.naist.jp/people/2004/kenta-t/OpenCV/pukiwiki/pukiwiki.php?FrontPage
その他の回答 (4)
- keibou21
- ベストアンサー率31% (18/58)
>補足して質問なのですが、このエンコードの種類を調べるにはどうすればよいのでしょうか? もしaviファイルがお手元にあるのなら使われている圧縮形式を調べる方法は簡単です。 http://kurohane.net/seisanbutu.phtml にある [真空波動研] で調べることができるはずです。 >また、デコーダのインストールをすることで、aviファイルのRGB値を取得する準備ができるとのことですが、デコーダをインストールすればプログラム内では特にデコードは気にする必要はないのでしょうか? >それともプログラム内にデコードするための部分などが必要なのでしょうか? 私が経験あるのはDirect Showを用いた手法ですので直接参考にはならないと思いますが Direct Showではデコーダ(Codec)さえインストールされていれば メモリに自動的にテクスチャデータ(RGB値の入ったデータ群)として作ってくれます。 あとはそいつをどのように加工するのもユーザの自由ですので。
お礼
DirectShowですか~。 VFWやOpenCV以外にもたくさんのAPIがあるのですね。 いろいろと試して自分に合うものを見つけてみたいと思います。
- saitoha
- ベストアンサー率81% (9/11)
■OpenCVの調査結果 OpenCVはいけてる系でした。VFWもラップされてるようです。 読み書きしながら再生するのはこんな感じでできました。 // // test.cpp // #include "highgui.h" #include "cvcam.h" #pragma comment (lib, "highgui.lib") #pragma comment (lib, "cvcam.lib") CvVideoWriter* writer; void mycallback(IplImage* image) { /* imageに対してなんか処理 */ ::cvWriteFrame( writer, image ); } int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { CvSize size; size.width = ***; size.height = ***; writer = :cvCreateVideoWriter("C:\\***out.avi", -1, // 出力コーデックをダイアログで選ばせる系 (double)***, // fps指定 size, // サイズ 1 // カラーで ); ::cvcamPlayAVI("***.avi", ::GetDesktopWindow, ::GetSystemMetrics(SM_CXSCREEN), ::GetSystemMetrics(SM_CYSCREEN), mycallback); ::cvReleaseVideoWriter(&writer); return 0; } ひょっとしたらCinepackとかキーフレーム入れて差分をとる系のコーデックだと、これではうまくいかないかもしれません。(VFWのときは何これっていうかんじのDIBしかとれませんでした。) そのときはメモリ上にバックバッファを用意して、そこにカリカリ描画して、それを値コピーしてきたものに処理かけていくほうがいいかも。
お礼
saitohaさん、またまたありがとうございます。 わざわざプログラムまで書いていただいて申し訳ありません。 せっかく貴重なご回答を頂いたにもかかわらず、私の勉強不足であまり理解できませんでした・・・申し訳ございません。 上記のプログラムのどの部分を変更してVC++にコピーして実行すれば動くものなのでしょうか? ぱっと見た目、C:\\***out.aviなどの部分は私のaviファイルの場所に設定しなおせば良いということはわかりますが、その他書き換えると良い部分もよろしければ教えていただけませんでしょうか? >■OpenCVの調査結果 >OpenCVはいけてる系でした。VFWもラップされてるようです。 とのことですが、私のような初心者でも理解しやすいような動画処理やOpenCVに関するサイトや書籍がございましたら教えていただけませんでしょうか? saitohaさんからいただいた貴重なご回答が理解できるように、勉強したいと思っております。 初心者のような質問でまことに申し訳ございませんが、よろしくお願いいたします。
- saitoha
- ベストアンサー率81% (9/11)
いろいろなやりかたがあるかもしれませんが、私が以前AVI再生エンジンに使ったのはVFH(Video for Windows)系APIでした。 VC6ではデフォルト状態でついてくる系だし、MSDNにもAPIの説明がある系です。 一枚一枚のビットマップをDIBで取得することができます。 だから、入出力はVFHで、処理はOpenCVとかでやるというのはどうでしょう。 (最近はMISTっていうのも気になっていますが落としっぱなしでまだ使ってません。どうなんでしょう?) 古いAPIだから描画とかが遅いのではないかと心配でしたが、意外といいかんじでしたよ。
お礼
saitohaさん、ご回答ありがとうございます。 Video for Windows APIというものもあるんですね~。 VFWと検索すると結構詳しいサイトもありますね。 う~ん、難しそうですが検討してみますね~。 私の予想ではOpenCVがaviの入出力から画像処理までなんでもやってくれるのかと思っていたのですが…どうやら難しいようですね。
- keibou21
- ベストアンサー率31% (18/58)
私はOpenCVを使ったことがないので分かる所だけ説明します。 >動画というものは静止画の集合なので、動画像処理は静止画像処理を連続的に行えばよいと耳にしたのですが、これは正しいのでしょうか? 基本的にはあっていますが、少し補足説明 プログラムで画像処理を行うためにはRGB値を取得しなければいけません。 しかし、静止画ファイルでもそうですが、動画ファイルのほとんどは”圧縮”技術によってファイルサイズが小さくなっています。 (静止画で言うところのjpgやgif等です) そして.aviというのは汎用動画の拡張子です。 aviには圧縮の種類がたくさんあります。 有名なところでは”DivX”,”WMV9”などなど・・・ プログラムで扱うにはまず読み込んだaviファイルがどの圧縮方式でエンコードされているか調査する必要があります。 そしてエンコードの種類がわかれば該当するデコーダをインストールしなければなりません。 これでようやくaviファイルのRGB値を取得する準備が整いました。 (上記の事項はもしかしたらOpenCVがやってくれるかも知れませんが、私には知識がないのでわかりません) これ以降はOpenCVの事をご存知の方にフォロー願います。
お礼
keibou21さん、ご回答ありがとうございます。 なるほど、.aviファイルといっても中身は圧縮されていて、いろいろな圧縮形式があったんですね。 そういった部分の知識が足りていませんでした。 >そしてエンコードの種類がわかれば該当するデコーダをインストールしなければなりません。 補足して質問なのですが、このエンコードの種類を調べるにはどうすればよいのでしょうか? また、デコーダのインストールをすることで、aviファイルのRGB値を取得する準備ができるとのことですが、デコーダをインストールすればプログラム内では特にデコードは気にする必要はないのでしょうか? それともプログラム内にデコードするための部分などが必要なのでしょうか? よろしくお願いいたします。
お礼
ご回答ありがとうございます。 OpenCVだけでの処理はどうやら難しいようですね。 とにかくVFWなどを導入してみて、画像処理が出来るところまでやってみたいと思います。