2014-11-09 16 views
8

मैं मीडिया फाउंडेशन IMFSourceReaderCallback कैमरे से वीडियो फ्रेम हथियाने के लिए कार्यान्वयन का उपयोग कर रहा हूं, और फिर लूप में फ्रेम प्रस्तुत करने के लिए ओपनसीवी imshow का उपयोग कर रहा हूं।
हालांकि मुझे फ्रेम लंबवत फिसल गया है ...
क्या यह एक बग है? क्या मुझे इससे बचने के लिए कुछ विशेषता निर्धारित करनी चाहिए?
यहाँ मेरी कोड है:मीडिया फाउंडेशन द्वारा कब्जा कर लिया गया वीडियो लंबवत दर्पण

प्रारंभ:

IMFAttributes* pDeviceAttrs, *pReaderAttrs; 
     hr = MFCreateAttributes(&pDeviceAttrs, 1); 
     if (FAILED(hr)) goto Exit; 
     hr = pDeviceAttrs->SetGUID(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID); 
     if (FAILED(hr)) goto Exit; 
//... 
// Correct source provider is activated through ActivateObject 
// 
     hr = MFCreateAttributes(&pReaderAttrs, 2); 
     if (FAILED(hr)) goto Exit; 

     pReaderAttrs->SetUnknown(MF_SOURCE_READER_ASYNC_CALLBACK,(IUnknown*)this); 
     pReaderAttrs->SetUINT32(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, TRUE); 

     hr = MFCreateSourceReaderFromMediaSource(pMediaSource, pReaderAttrs, &m_pReader); 
     if (FAILED(hr)) goto Exit; 
// Correct profile is set 

OnReadSample कार्यान्वयन:

:

HRESULT hr = S_OK; 
     LONG defaultStride = 0; 
     LONG stride = 0; 
     BYTE *pBuffer = NULL; 

     EnterCriticalSection(&m_critSec); 
     if (NULL != pSample) 
     { 
      IMFMediaBuffer* pMediaBuffer; 
      DWORD dataSize = 0; 
      // In case of a single buffer, no copy would happen 
      hr = pSample->ConvertToContiguousBuffer(&pMediaBuffer); 
      if (FAILED(hr)) goto Cleanup; 
      pMediaBuffer->GetCurrentLength(&dataSize); 

      hr = pMediaBuffer->Lock(&pBuffer, &dataSize, &dataSize); 
      if (FAILED(hr)) goto Cleanup; 

      // todo: use a backbuffer to avoid sync issues 
      if (NULL == m_pLatestFrame) m_pLatestFrame = (BYTE*)malloc(dataSize); 
      memcpy(m_pLatestFrame, pBuffer, dataSize); 
      ++m_frameNumber; 

      pMediaBuffer->Unlock(); 
      pMediaBuffer->Release(); 
     } 
Cleanup: 
     LeaveCriticalSection(&m_critSec); 

     // Async ReadFrame for the next buffer: 
     hr = m_pReader->ReadSample(
      (DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM, 
      0, 
      NULL, // actual 
      NULL, // flags 
      NULL, // timestamp 
      NULL // sample 
      ); 
     return hr; 

सीवी :: छवि के लिए रूपांतरण 0

कोई विचार?

अग्रिम धन्यवाद!

+1

नहीं, यह निश्चित रूप से आपके कानों के बीच एक बग है। बिटमैप्स सामान्य रूप से ऊपर की ओर संग्रहीत होते हैं, अंतिम स्कैनलाइन स्मृति में पहली बार होती है। जब तक biHeight नकारात्मक नहीं है। आप इसे सीवी सरणी में ठीक से परिवर्तित नहीं कर रहे हैं, कोड जिसे आपने पोस्ट नहीं किया था। –

+0

@ हंस पासेंट: धन्यवाद, ऊपर सीवी कोड जोड़ा गया। – rkellerm

+0

आपके द्वारा पोस्ट किया गया कोड विवरण प्राप्त करने के लिए शायद ही पूरा हो गया है, हालांकि मुझे लगता है कि हंस धारणा सही है, आप नीचे आरजीबी छवि को नीचे ले जा रहे हैं और फिर आप इसका इलाज करते हैं जैसे कि यह नीचे से नीचे था। –

उत्तर

3

एक बिटमैप को अंतिम स्कैन लाइन के साथ पहले संग्रहीत किया जाता है, इसलिए छवि उल्टा दिखाई देगी। सबसे आसान समाधान cv::flip

void Player::Present() 
{ 
    //... 
    color = cv::Mat(colorSize, 
       CV_8UC3, 
       static_cast<unsigned char*>(m_pColorCameraImpl->getLatestFrame())); 

    cv::Mat corrected; 
    flip(color, corrected, 0); 
    imshow(corrected); 
} 
+0

धन्यवाद, यह वही है जो मैं वर्तमान में करता हूं। मैंने सोचा कि क्या मैं बिना किसी अतिरिक्त फ्लिप के कॉन्फ़िगरेशन में कुछ बदल सकता हूं। – rkellerm

संबंधित मुद्दे