Я работаю в интерактивном приложении C ++ / OpenGL, и я решил использовать OpenCV для чтения видео, чтобы я мог передать их с хоста в графический процессор в качестве текстуры.До сих пор мне удавалось использовать постоянный ввод, такой как веб-камера, но у меня проблемы с файлами MP4, так как они имеют постоянную продолжительность.Я не знаю, как справиться с этим.Я получаю кадры в цикле рендеринга моего основного файла, поэтому, если я решу остановить итерации, когда потоковое видео закончится, мое приложение закроется, и я не хочу этого, я думаю, что должен быть обходной путь, такой как зацикливание видео (Я попытался проверить, если frame.empty () и либо перегружать VideoCapture, либо сбросить видеокадр, но получил только (! _ Src.empty ()) в 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...
А вот моя служебная функция длясвяжите 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;
}