はじめての動画ファイルプログラミングの第7章の7-1のサンプルを改造して、
フレームごとの色の特徴量を取れるプログラムを作成しています。省略するのも、良くないと思いますし、文字制限がありますので、区切って書き込みます。
// frame3.cpp DirectShowを使ったフレームの切り出しの応用
// ○list502.h、list502b.cppを合わせて、
// コンソールアプリケーションで作成すること
// ○[プロジェクト][リンク]にstrmiids.lib を追加
// ○COMの操作はすべてHRESULTを返すが、プログラムを簡単にするため
// 最低限の吟味しか行っていない。
#include <windows.h> #include <string.h> #include <dshow.h> // DirectShowのヘッダファイル #include <qedit.h> // SampleGrabber用 #include <conio.h> // getch()用 #include <stdio.h> #include "lis.h" void main( void ) { // インターフェース用のポインタ // フィルタグラフ用 IGraphBuilder *pigb = NULL; IMediaControl *pimc = NULL; IMediaSeeking *pims = NULL; // サンプルグラバ用 IBaseFilter *pF = NULL; ISampleGrabber *pGrab = NULL; // これらは後で解放すること。 IMG0 img00; // 表示ウィンドウ用の構造体 BYTE *buffer; // 外部バッファ AM_MEDIA_TYPE amt; WCHAR filename[ MAX_PATH ]; HRESULT hr; img00.hi = (HINSTANCE)GetWindowLong( HWND_DESKTOP, GWL_HINSTANCE ); img00.x = 100; img00.y = 100; gr_reg(); // 表示用ウィンドウの登録 CoInitialize(NULL); // COMの準備 // FilterGraphの初期化 CoCreateInstance( CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&pigb); // フィルタグラフのインターフェースを得る pigb -> QueryInterface( IID_IMediaControl, (void **)&pimc ); pigb -> QueryInterface( IID_IMediaSeeking, (void **)&pims ); // グラバフィルタを作りフィルタグラフに追加 CoCreateInstance( CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (LPVOID *)&pF); pF -> QueryInterface( IID_ISampleGrabber, (void **)&pGrab ); pigb -> AddFilter( pF, L"SamGra" ); // グラバフィルタの挿入場所の特定のための設定 ZeroMemory( &amt, sizeof(AM_MEDIA_TYPE) ); amt.majortype = MEDIATYPE_Video; amt.subtype = MEDIASUBTYPE_RGB24; amt.formattype = FORMAT_VideoInfo; pGrab -> SetMediaType(&amt); OPENFILENAME fname; static char fn[256]; memset(&fname, 0, sizeof(OPENFILENAME)); fname.lStructSize = sizeof(OPENFILENAME); fname.lpstrFile = fn; // パス付きファイル名が格納されるアドレス fname.nMaxFile = sizeof(fn); fname.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; if( ! GetOpenFileName( &fname ) ) return ; // ファイル名の変換 MultiByteToWideChar( CP_ACP, 0, fn, -1, filename, MAX_PATH ); // 再生するファイルを指定、この時点で使用するフィルタが決まる hr = pigb -> RenderFile( filename, NULL ); printf( "RenderFile hr %x\n", hr ); if(hr != 0) return; // ビットマップ情報の取得 pGrab -> GetConnectedMediaType( &amt ); // ビデオ ヘッダーへのポインタを獲得する。 // ビデオ ヘッダーには、ビットマップ情報が含まれる。 // ビットマップ情報を BITMAPINFO 構造体にコピーする。 img00.bih = ((VIDEOINFOHEADER*)amt.pbFormat) ->bmiHeader; long n = amt.lSampleSize; buffer = (BYTE *)malloc( n ); img00.lpBmpData=buffer; pims -> SetTimeFormat( &(TIME_FORMAT_FRAME) ) ; // シークをフレーム単位で行うよう設定~つづく