繁体   English   中英

Media Foundation捕获的视频是垂直镜像的

[英]Video captured by Media Foundation is vertical mirrorred

我正在使用Media Foundation IMFSourceReaderCallback实现从摄像机抓取视频帧,然后使用OpenCV 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;

转换为cv :: image:

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

任何的想法?

提前致谢!

位图首先与最后一条扫描线一起存储,因此图像将倒置显示。 最简单的解决方案是调用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);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM