簡體   English   中英

使用 OpenCV 和 OpenGL 讀取 MP4

[英]Reading an MP4 with OpenCV and OpenGL

我正在使用 C++/OpenGL 交互式應用程序,我決定使用 OpenCV 來讀取視頻,以便我可以將它們從主機獲取到 GPU 作為紋理。 到目前為止,當使用像 web 相機這樣的持久輸入時,我已經成功了,但是我在處理 MP4 文件時遇到了問題,因為它們的持續時間是非永久的。 我不知道該怎么處理。 我在我的主渲染循環中獲取幀,所以如果我決定在視頻完成流式傳輸時停止迭代,我的應用程序將關閉並且我不希望這樣,我想必須有一種解決方法,比如循環視頻(我嘗試通過檢查frame.empty()並重載 VideoCapture 或重置視頻幀但只得到(._src:empty()) in cv::cvtColor ),我想到的另一個解決方案是之前做另一個循環我的渲染循環進行解碼,但這不是我使用此代碼的最性能明智的決定:

// Import openCV.
#include <opencv2/core/core.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui.hpp>

using namespace cv;

// Open the MP4 and its attributes.
std::string videoName = "D:\\\SomeVideo\\\Video.mp4";

    VideoCapture cap( videoName  );
    if( !cap.isOpened() )
    {

        std::cout << "Video file not loaded!" << std::endl;
        return -1;

    }

Mat frame;
cap >> frame;
int videoWidth = frame.rows;
int videoHeight = frame.cols;
unsigned char* image = cvMat2TexInput( frame );

// We create the texture that will store our video.
unsigned int video;
glGenTextures( 1, &video );
glBindtexture( GL_TEXTURE_2D, video );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

// Render Loop.
while( !glfwWindowShouldClose( window ) )
{

    glfwGetFramebufferSize( window, &WIDTH, &HEIGHT );

    // We set our video.
    try
    {

        cap >> frame;

        if( frame.empty() )
        {

            break;

        }

        else
        {

            image = cvMat2TexInput( frame );

        }

    }

    catch( Exception& e )
    {

        std::cout << e.msg << std::endl;

    }

    if( image )
    {

        glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, videoWidth, videoHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, image );

    }

    else
    {

        std::cout << "Failed to load video texture." << std::endl;

    }

    // Input.
    processInput( window );

    // Go on until I bind it to my program, here:
    glActiveTexture( GL_TEXTURE0 );
    glBindTexture( GL_TEXTURE_2D, video );

    // Finish all the boilerplate...

這是我的實用程序 function 將 cvMat 鏈接到 OpenGL 的無符號字符 *:

// Utility function to link OpenCV.
unsigned char* cvMat2TexInput( Mat& img )
{

    cvtColor( img, img, COLOR_BGR2RGB );
    transpose( img, img );
    flip( img, img, 1 );
    flip( img, img, 0 );
    return img.data;

}

您可以使用以下命令重置要讀取的幀索引:

cap.set(cv::CAP_PROP_POS_FRAMES, 0);

(來自下面鏈接的文檔): CAP_PROP_POS_FRAMES :接下來要解碼/捕獲的幀的基於 0 的索引

這樣做一次

frame.empty()

返回true就足夠了。

cv::VideoCapture.set()cv::VideoCaptureProperties 標志的文檔

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM