2014-11-09 12 views
8

Utilizzo l'implementazione di Media Foundation IMFSourceReaderCallback per l'acquisizione di fotogrammi video dalla fotocamera, quindi OpenCV imshow per presentare i fotogrammi in un ciclo.
Tuttavia, i fotogrammi vengono capovolti verticalmente ...
Si tratta di un errore? Devo impostare qualche attributo per evitare questo?
Ecco il mio codice:Il video acquisito da Media Foundation è speculare verticale

inizializzazione:

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

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; 

conversione cv :: immagine a:

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

Qualche idea?

Grazie in anticipo!

+1

No, questo è sicuramente un insetto tra le tue orecchie. Le bitmap vengono normalmente memorizzate capovolte, l'ultima scanline è la prima in memoria. A meno che biHeight sia negativo. Non lo stai convertendo correttamente nell'array CV, codice che non hai pubblicato. –

+0

@Hans Passant: grazie, ha aggiunto il codice cv sopra. – rkellerm

+0

Il codice che hai postato non è completo per ottenere i dettagli, tuttavia suppongo che l'ipotesi di Hans sia corretta, stai prendendo l'immagine RGB dal basso verso l'alto e poi la tratterai come se fosse il massimo. –

risposta

3

Una bitmap viene memorizzata per prima con l'ultima riga di scansione, quindi l'immagine verrà visualizzata al contrario. La soluzione più semplice è chiamare 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

grazie, questo è quello che faccio attualmente. Mi chiedevo solo se posso cambiare qualcosa nella configurazione senza un capovolgimento extra. – rkellerm

Problemi correlati