Немного предыстории:
Я работаю над проектом, который читает два изображения 4k, использует opencv, чтобы начать процесс сшивания изображений для создания панорамы (я использую это для получения значений, которые будут использоваться позже),затем я передаю данные, полученные из opencv, в ядро CUDA и выполняю вычисления (сложение и умножение) для окончательного сшивания изображений.
Там, где начинается проблема:
Первоначально япередавал скачанный cv::Mat
в класс с именем video_widget
, который наследует QGLWidget, и отображал изображение там без проблем.Поскольку очень важно ускорить этот процесс, мне было интересно, есть ли способ сократить время загрузки данных из GPU в CPU и вместо этого просто отображать данные прямо из GPU.
У меня естьисследовал, и, возможно, я недостаточно знаю о своей проблеме, чтобы задавать правильные вопросы, но из того, что я вижу, это кажется возможным.Кто-нибудь может помочь, пожалуйста?
Когда я только начал, я изменил методы с передачи загруженного cv::Mat
на пропуск cv::cuda::GpuMat
, с которого загружались данные.Я понимаю, что теперь это неправильно, поскольку я пишу это, зная о том, как обрабатываются данные в графическом процессоре ... но в любом случае.После обработки изображения я пропускаю его через сигнальный слот, который вызывает метод update_frame для созданного QGLWidget, затем обновляется глобальный cv::cuda::GpuMat
, затем вызывается updateGL()
, который, как я знаю, вызывает paintGL()
.Итак, внутри paintGL()
я попробовал пару вещей, которые все потерпели неудачу:
- Просто изменил строку с принятия в
cv::Mat
на cv::cuda::GpuMat
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, current_frame_gpu.cols, current_frame_gpu.rows, 0.0f, GL_BGR, GL_UNSIGNED_BYTE, current_frame_gpu.data);
это мгновенно закончилось неудачей, поэтому я начал (догадываться) менять разные форматы, чтобы посмотреть, не в этом ли проблема ... Без кубиков.
Создал QOpenGLTexture и скопировал данные из cv::cuda::GpuMat
к этому и попытался связать его, вызвав this->bindTexture()
, но каждый раз в этой строке или около нее не получалось.
Пробовал
cv::ogl::Texture2D tex;
tex.copyFrom(current_frame_gpu);
tex.bind();
но это тоже не удалось .. Я действительно не знаю, что делать, и я чувствую, что ресурсы по этой теме не относятся к моей проблеме.
Правильный код при пропуске cv::Mat
:
void video_widget::paintGL(){
//Clear the buffer
glClear(GL_COLOR_BUFFER_BIT);
//Update the texture
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, current_frame.cols,
current_frame.rows, 0.0f, GL_BGR, GL_UNSIGNED_BYTE, current_frame.data);
//Maps each texture coordinate to the vertices in object space
float x_offset = 60.0;
float y_offset = -10.0;
glBegin(GL_QUADS);
glTexCoord2f(0, 1);
glVertex2i(left + dx + x_offset, bottom + dy - y_offset);
glTexCoord2f(0, 0);
glVertex2i(left + dx + x_offset, top + dy - y_offset);
glTexCoord2f(1, 0);
glVertex2i(right + dx + x_offset, bottom + dy - y_offset);
glTexCoord2f(1, 1);
glVertex2i(right + dx + x_offset, top + dy - y_offset);
glEnd();
//Some settings checks...
...
...
glFlush();
}