雷って幻想的だよね?

宗教:C++、C#、ラノベ好きの戯言です。

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);


}