DirectShow+OpenCV 未整理&テスト用
ビットマップのヘッダを手に入れるために以下を行う
AM_MEDIA_TYPE am_media_type;
pSampleGrabber->GetConnectedMediaType(&am_media_type);
VIDEOINFOHEADER *pVideoInfoHeader =(VIDEOINFOHEADER *)am_media_type.pbFormat;
上記の情報をビットマップのヘッダ情報へ置き換える
(bitsizeを使わなくてよくなるのであればほぼ不要になる記述)
BITMAPINFO BitmapInfo;
ZeroMemory( &BitmapInfo, sizeof(BitmapInfo) );
CopyMemory( &BitmapInfo.bmiHeader, &(pVideoInfoHeader->bmiHeader), sizeof(BITMAPINFOHEADER) );
long bitsize = BitmapInfo.bmiHeader.biSizeImage;
バッファの確保を行う
char *pBuffer = (char *)malloc(bitsize);
char *pBuffer2 = (char *)malloc(bitsize);
バッファを取得
pSampleGrabber->GetCurrentBuffer(&nBufferSize,(long *)pBuffer);
pSampleGrabber->GetCurrentBuffer(&nBufferSize,(long *)pBuffer2);
画像データの入れ物を作成
(srcがカラーでdstはグレースケール)
IplImage *src = cvCreateImage( cvSize(width, height), IPL_DEPTH_8U, 3);
IplImage *src2 = cvCreateImage( cvSize(width, height), IPL_DEPTH_8U, 3);
IplImage *dst = cvCreateImage( cvSize(width, height), IPL_DEPTH_8U, 1);
IplImage *dst2 = cvCreateImage( cvSize(width, height), IPL_DEPTH_8U, 1);
バッファから格納する
src->imageData=(char *)pBuffer;
src2->imageData=(char *)pBuffer2;
データの反転を修正
cvFlip(src,NULL,0);
cvFlip(src2,NULL,0);
グレースケールへチャンネル数を下げる
cvCvtColor(src,dst,CV_RGB2GRAY);
cvCvtColor(src2,dst2,CV_RGB2GRAY);
あとは、dstをオプティカルフローの関数へ入れればOK
秒数を入れると実行時からその秒数後までの画像を取得すし、オプティカルフローにかけて表示する
void Video::showOpticalFlow( DWORD millisecond )
{
// バッファを用意
// 必要なバッファサイズを取得
long nBufferSize = 0;
pSampleGrabber->GetCurrentBuffer(&nBufferSize,NULL);
// 接続情報取得。
// RenderFileによりGraphが構成された後に行う
AM_MEDIA_TYPE am_media_type;
pSampleGrabber->GetConnectedMediaType(&am_media_type);
VIDEOINFOHEADER *pVideoInfoHeader =(VIDEOINFOHEADER *)am_media_type.pbFormat;
//Bitmap情報に変換準備
BITMAPINFO BitmapInfo;
ZeroMemory( &BitmapInfo, sizeof(BitmapInfo) );
CopyMemory( &BitmapInfo.bmiHeader, &(pVideoInfoHeader->bmiHeader), sizeof(BITMAPINFOHEADER) );
long bitsize = BitmapInfo.bmiHeader.biSizeImage;
//可読性をあげるためにのみ記述
int width, height;
width = pVideoInfoHeader->bmiHeader.biWidth;
height = pVideoInfoHeader->bmiHeader.biHeight;
//画像のバッファ確保
char *pBuffer = (char *)malloc(bitsize);
char *pBuffer2 = (char *)malloc(bitsize);
// 現在表示されている映像を静止画として取得
pSampleGrabber->GetCurrentBuffer(&nBufferSize,(long *)pBuffer);
Sleep( millisecond );//差異を手に入れるために記述
pSampleGrabber->GetCurrentBuffer(&nBufferSize,(long *)pBuffer2);
BITMAPINFOHEADER bHead, bHead2;
bHead = bHead2 = BitmapInfo.bmiHeader;
//画像を入れる入れ物の作成
IplImage *src = cvCreateImage( cvSize(width, height), IPL_DEPTH_8U, 3);
IplImage *src2 = cvCreateImage( cvSize(width, height), IPL_DEPTH_8U, 3);
IplImage *dst = cvCreateImage( cvSize(width, height), IPL_DEPTH_8U, 1);
IplImage *dst2 = cvCreateImage( cvSize(width, height), IPL_DEPTH_8U, 1);
//カラー画像を格納
src->imageData=(char *)pBuffer;
src2->imageData=(char *)pBuffer2;
//データが反転しているので逆転させる
cvFlip(src,NULL,0);
cvFlip(src2,NULL,0);
//グレースケールへ変更
cvCvtColor(src,dst,CV_RGB2GRAY);
cvCvtColor(src2,dst2,CV_RGB2GRAY);
// (1)速度ベクトルを格納する構造体の確保,等
int cols = width;
int rows = height;
CvMat *velx = cvCreateMat (rows, cols, CV_32FC1);
CvMat *vely = cvCreateMat (rows, cols, CV_32FC1);
const int threshold = 15; //閾値
// オプティカルフローを計算(LK)
cvCalcOpticalFlowLK(dst, dst2, cvSize (15, 15), velx, vely);
// 計算されたフローを描画(LK)
int dx,dy;
for (int i = 0; i < cols; i += threshold) {
for (int j = 0; j < rows; j += threshold) {
dx = (int) cvGetReal2D (velx, j, i);
dy = (int) cvGetReal2D (vely, j, i);
cvLine (src2, cvPoint (i, j), cvPoint (i + dx, j + dy), CV_RGB (255, 0, 0), 1, CV_AA, 0);
}
}
cvNamedWindow ("ImageLK", 0);
cvShowImage ("ImageLK", src2);
free(pBuffer);
free(pBuffer2);
}