我正在使用C ++ / OpenGL交互式应用程序,因此我决定使用OpenCV读取视频,以便可以将它们作为纹理从主机获取到GPU中。到目前为止,当使用像网络摄像机这样的持久输入时,我已经成功了,但是由于MP4文件的持续时间不长,所以我遇到了麻烦。我不知道该如何处理。我在主渲染循环中获取了帧,因此,如果我决定在视频结束流式传输时停止迭代,则我的应用程序将关闭,并且我不希望这样做,我想必须有一种解决方法,例如循环播放视频(我尝试通过检查 frame.empty()并重载VideoCapture或重置视频帧,但在cv :: cvtColor (!_ src.empty()) >),虽然我想解决的另一种解决方案是在渲染循环之前执行另一个循环来进行解码,但这并不是我使用此代码的最明智的选择:
// 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...
这是我的实用函数,用于将cvMat链接到OpenGL的未签名char *:
// 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;
}