2014-02-20 62 views
1

我正在使用DirectShow訪問視頻流,然後使用SampleGrabber過濾器和接口從每個幀獲取樣本以進一步進行圖像處理。我使用回調函數,所以在每個新幀之後都會調用它。我基本上只是從PlayCap示例應用程序工作,並添加了一個示例過濾器到圖形。ISampleGrabber :: BufferCB到IplImage;在OpenCV中顯示亂碼圖像 - C++

我遇到的問題是我試圖在不同的OpenCV窗口上顯示抓取的樣本。但是,當我嘗試將緩衝區中的信息轉換爲IplImage時,我得到了亂七八糟的像素。對於BufferCB調用的代碼如下,SANS任何適當的錯誤處理:

STDMETHODIMP BufferCB(double Time, BYTE *pBuffer, long BufferLen) 
{ 
    AM_MEDIA_TYPE type; 
    g_pGrabber->GetConnectedMediaType(&type); 
    VIDEOINFOHEADER *pVih = (VIDEOINFOHEADER *)type.pbFormat; 

    BITMAPINFO* bmi = (BITMAPINFO *)&pVih->bmiHeader; 
    BITMAPINFOHEADER* bmih = &(bmi->bmiHeader); 
    int channels = bmih->biBitCount/8; 

    mih->biPlanes = 1; 
    bmih->biBitCount = 24; 
    bmih->biCompression = BI_RGB; 

    IplImage *Image = cvCreateImage(cvSize(bmih->biWidth, bmih->biHeight), IPL_DEPTH_8U, channels);  

    Image->imageSize = BufferLen; 
    CopyMemory(Image->imageData, pBuffer, BufferLen); 
    cvFlip(Image); 

    //openCV Mat creation 
    Mat cvMat = Mat(Image, true); 
    imshow("Display window", cvMat);     // Show our image inside it. 
    waitKey(2); 


    return S_OK; 
} 

我的問題是,我在這裏做得不對,這將使圖像顯示的是這樣的:

我是否缺少標題信息?

回答

1

引用的代碼是解決方案的一部分。您可以在此創建具有8位像素數據和未知通道/組件數的特定寬度/高度的圖像對象。然後從另一個未知格式的緩衝區複製數據。

它唯一能夠很好地工作的機會是所有的未知數都可以毫不費力地匹配。所以你基本上需要開始檢查Sample Grabber的輸入引腳上的媒體類型。那麼,如果它不是你想要的,你必須分別更新你的代碼。 SG的下游連接以及它是否特別連接到視頻渲染器可能也很重要。

+0

好吧,我已經開始研究如何構建圖。基本上,我給它一個源代碼,添加一個示例抓取器過濾器,然後渲染源上的引腳。然後它將圖形編譯爲 Source - > Sample Grabber - > MJPEG decompressor - > Color space converter - > Video renderer。所以,本質上,從樣本中獲得的字節被編碼爲MJPEG。我使用GraphEdit工具來查看是否可以重新排列過濾器,以便SampleGrabber工具位於渲染器之前,但不是骰子。是否有解碼字節的簡寫方式,或者是否應該更改過濾器圖? – Scratch17

+0

是的,這解釋了這個效果:你取JPEG字節並將它們重新解釋爲RGB,這是一個非工作者。您可以實際重新排列過濾器。但是,在編程上,你通常設置Sample Grabber只接受你感興趣的RGB類型,例如請參閱「設置媒體類型」下的[這裏](http://msdn.microsoft.com/en-us/library/windows/desktop/dd407288%28v=vs.85%29.aspx)。 –

+0

太好了,那就是答案,謝謝!我不知道通過設置圖形將自動將SampleGrabber構建到正確位置的類型來獲取這種數據。非常感謝! – Scratch17