2014-11-09 2 views
8

카메라에서 비디오 프레임을 가져 오는 데 Media Foundation IMFSourceReaderCallback 구현을 사용하고 OpenCV imshow을 사용하여 루프에 프레임을 표시합니다.
그러나 프레임이 세로로 뒤집 혔습니다.
이것은 버그입니까? 이 문제를 피하기 위해 몇 가지 속성을 설정해야합니까?
여기 내 코드입니다 :Media Foundation에서 캡처 한 비디오가 세로로 표시됩니다.

초기화 :

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 구현 :

,321 : 이력서 :: 이미지

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가 부정적이지 않으면. CV 배열로 제대로 변환하지 않았습니다. 코드는 게시하지 않았습니다. –

+0

@ 한자 Passant : 감사합니다. 위의 cv 코드를 추가했습니다. – rkellerm

+0

게시 한 코드는 세부 정보를 얻기가 거의 완료되지 않았지만 Hans 가정은 정확하다고 가정합니다. 맨 아래쪽 RGB 이미지를 맨 아래로 가져 가면서 맨 아래에있는 것처럼 취급합니다. –

답변

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

관련 문제