[英]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
就足够了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.