【问题标题】:How to copy frame data from FFmpegSource2 (FFMS2) FFMS_Frame struct to OpenCV Mat?如何将帧数据从 FFmpegSource2 (FFMS2) FFMS_Frame 结构复制到 OpenCV Mat?
【发布时间】:2013-10-03 21:07:22
【问题描述】:

我正在尝试使用 FFmpegSource2 (FFMS2) 读取视频文件,然后使用 OpenCV 处理帧。将帧数据从 FFMS_GetFrame 函数返回的 FFMS_Frame 结构复制到 OpenCV Mat 的正确有效方法是什么?

非常感谢您。

【问题讨论】:

    标签: opencv ffmpeg frame mat


    【解决方案1】:

    目前我正在使用以下适用于 BGR 颜色格式的过程。

    步骤 1. 我使用 FFMS_SetOutputFormatV2 和 FFMS_GetPixFmt( "bgra" ) 将 FFMS 的输出像素格式设置为 BGR。

    int anPixFmts[2];
    anPixFmts[0] = FFMS_GetPixFmt( "bgra" );
    anPixFmts[1] = -1;
    
    if( FFMS_SetOutputFormatV2( pstFfmsVidSrc, anPixFmts
        , pstFfmsFrameProps->EncodedWidth, pstFfmsFrameProps->EncodedHeight
        , FFMS_RESIZER_BICUBIC, &stFfmsErrInfo ) )
    {
        // handle error
    }
    

    第 2 步。使用 FFMS_GetFrame 读取所需的帧。

    int nCurFrameNum = 5;
    const FFMS_Frame *pstCurFfmsFrame = FFMS_GetFrame( pstFfmsVidSrc, nCurFrameNum, &stFfmsErrInfo );
    

    步骤 3. 将数据从 pstCurFfmsFrame 复制到 OpenCV Mat、oMatA:

    Mat oMatA;
    oMatA = Mat::zeros( pstCurFfmsFrame->EncodedHeight, pstCurFfmsFrame->EncodedWidth, CV_8UC3 );
    int nDi = 0;
    for( int nRi = 0; nRi < oMatA.rows; nRi++ )
    {
        for( int nCi = 0; nCi < oMatA.cols; nCi++ )
        {
           oMatA.data[oMatA.step[0] * nRi + oMatA.step[1] * nCi + 0] = pstCurFfmsFrame->Data[0][nDi++]; // B
           oMatA.data[oMatA.step[0] * nRi + oMatA.step[1] * nCi + 1] = pstCurFfmsFrame->Data[0][nDi++]; // G
           oMatA.data[oMatA.step[0] * nRi + oMatA.step[1] * nCi + 2] = pstCurFfmsFrame->Data[0][nDi++]; // R
           nDi++;
        }
    }
    

    必须更改此代码以支持其他颜色格式(例如 YV12 等平面格式使用多个 pstCurFfmsFrame->Data 平面)。可能有人可以提供一个完整的功能来支持大多数颜色格式,以及一种将数据从 pstCurFfmsFrame->Data 复制到 OpenCV Mat 的有效方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-22
      • 1970-01-01
      • 1970-01-01
      • 2016-08-16
      相关资源
      最近更新 更多