Мне интересно, могу ли я извлечь выгоду из многопоточности потока VideoCapture, я использую OpenGL и OpenCV, и мое узкое место определенно заключается в получении и настройке текстуры потока моей видеокамеры.
...This goes in the Render Loop.
// 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( frame.empty() )
{
std::cout << "No luck with the VideoCapture..." << std::endl;
}
else
{
image = cvMat2TexInput( frame );
}
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;
}
...
Это функция, которая возвращает беззнаковый символ * для нашего текстурного ввода 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;
}
Если он более производительный, как бы я поступил?Я пробовал:
// Before main:
void multi( VideoCapture cap, Mat& frame )
{
try
{
cap >> frame;
}
catch( Exception& e )
{
std::cout << e.msg << std::endl;
}
}
// In main's render loop:
std::thread t1( multi, cap, std::ref( frame ) );
t1.join();
if( frame.empty() )
{
std::cout << "No luck with the VideoCapture..." << std::endl;
}
else
{
image = cvMat2TexInput( frame );
}
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;
}
Но у меня снижение на 10 FPS.Я также попытался перенести всю настройку видео с:
cap >> frame
на:
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;
}
в мою функцию multi void, но я вообще не получаю вывод, если неогромная утечка памяти.Я также попытался использовать два разных цикла, один внутри многопоточной функции и основной цикл рендеринга, но я вообще ничего не получил.
Так что мои вопросы на самом деле три:
Могу ли явыиграть от многопоточности для этого процесса?Если да, как бы я это реализовал?И еще один, связанный, но который может послужить мне для других процессов, как бы я назвал беззнаковый символ * ссылкой?Последнее было то, что я не смог сделать в своей многопоточной функции, я попробовал что-то вроде:
void multi( ...., unsigned char*& image ){ ... }
и назвал его так:
std::thread t1( multi, ...., std::ref( image ) )
или
std::thread t1( multi, ...., image )
но только утечки памяти!
Начиная с C ++ 11, я думаю, ОС не имеет значения, но я использую Windows 10 и Visual Studio 2017.
Спасибо!