2014-11-09 6 views
8

Ich verwende Media Foundation IMFSourceReaderCallback Implementierung für das Ergreifen von Video-Frames von der Kamera, und dann OpenCV imshow, um die Frames in einer Schleife zu präsentieren.
Allerdings bekomme ich die Frames vertikal umgedreht ...
Ist das ein Fehler? Sollte ich ein Attribut setzen, um dies zu vermeiden?
Hier ist mein Code:Video erfasst von Media Foundation ist vertikal spiegelrot

Initialisierung:

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 Umsetzung:

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; 

Umstellung auf cv :: Bild:

void SourceReaderImpl::GetLatestFrame(BYTE** ppLatestFrame) 
    { 
     EnterCriticalSection(&m_critSec); 
     *ppLatestFrame = m_pLatestFrame; 
     LeaveCriticalSection(&m_critSec); 
    } 

void* CameraWrapperImpl::getLatestFrame() 
{ 
    BYTE* pLatestFrame = NULL; 
    m_pMfReader->GetLatestFrame(&pLatestFrame); 
    return pLatestFrame; 
} 

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

Irgendeine Idee?

Vielen Dank im Voraus!

+1

Nein, das ist sicherlich ein Bug zwischen Ihren Ohren. Bitmaps werden normalerweise auf dem Kopf stehend gespeichert, die letzte Scanlinie ist zuerst im Speicher. Es sei denn, biHeight ist negativ. Sie konvertieren es nicht ordnungsgemäß in das CV-Array, Code, den Sie nicht veröffentlicht haben. –

+0

@Hans Passant: danke, fügte den obigen cv-code hinzu. – rkellerm

+0

Der Code, den Sie gepostet haben, ist nicht vollständig, um Details zu erhalten, aber ich nehme an, dass Hans Annahme richtig ist, Sie nehmen das RGB-Bild von unten nach oben und dann behandeln Sie es als ob es von oben nach unten war. –

Antwort

3

Eine Bitmap wird zuerst mit der letzten Scanzeile gespeichert, sodass das Bild auf dem Kopf steht. Die einfachste Lösung ist, 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

danke, das ist, was ich derzeit tue. Ich habe mich nur gefragt, ob ich etwas in der Konfiguration ändern kann, ohne einen zusätzlichen Flip. – rkellerm

Verwandte Themen