Я показываю изображение 2800x2200 с камеры со скоростью 15 кадров в секунду на Qt.
Он отправляет данные в формате BGR, поэтому я преобразовал формат BGR в формат RGB с помощью функции QImage::rgbSwapped().
Но на моем ПК это занимает около 83 мс, что приводит к большому отставанию.
Я пытался использовать QGLWidget, и он работает хорошо, но замедляет работу других виджетов, например, панели разделения, панели ползунка и так далее.
Есть ли способ напрямую отображать формат BGR или ускорить rgbSwapped() в Qt?
Я думаю, что подход OpenGL является наиболее многообещающим, я бы попытался выяснить, почему он так сильно замедляет работу пользовательского интерфейса (слишком много работы для каждого кадра?)
Да, это немного тяжело, когда в представлении около 20 виджетов.
Ваш выбор: шейдеры OpenGL V.S. OpenCV. Я сомневаюсь, что вы действительно можете написать как самую быструю, так и кросс-платформенную реализацию вручную.
Вы можете сделать это с помощью встроенной функции OpenCV, например:
QImage matToQImage(const cv::Mat &mat)
{
if (mat.channels() == 1) { // if grayscale image
return QImage((uchar*)mat.data, mat.cols, mat.rows, static_cast<int>(mat.step), QImage::Format_Grayscale8).copy();
}
if (mat.channels() == 3) { // if 3 channel color image
cv::Mat rgbMat;
cv::cvtColor(mat, rgbMat, cv::COLOR_BGR2RGB); // invert BGR to RGB
return QImage((uchar*)rgbMat.data, mat.cols, mat.rows, static_cast<int>(mat.step), QImage::Format_RGB888).copy();
}
return QImage();
}
Теперь он будет работать достаточно быстро.
Ну, на самом деле, я просто не хочу использовать OpenCV только для одной функции. :(
По какой причине вы не хотите использовать OpenCV для преобразования BGR в RGB? Он работает очень быстро, чем любые другие функции, которые я знаю. Если вы не хотите использовать OpenCV, то почему вы ставите тег opencv на свой вопрос?
Это большие изображения, поэтому они всегда занимают некоторое время, но вы можете ускорить rgbSwapped, выполнив это на rvalueref, например так:
img = std::move(img).rgbSwapped();
Один хак, который вы можете попробовать, если вы вводите RGB32, использует QImage::reinterpretAsFormat(QImage::RGBX8888). В архитектурах с прямым порядком байтов (x86 и современные ARM) это будет выполнять ту же функцию rgbSwapped(), но не касаясь ни одного пикселя. Однако подпрограммы, рисующие его, будут менее оптимизированы :/
Наконец, rgbSwapped для форматов, отличных от RGB32, значительно оптимизирован в Qt 5.12 или 5.13 (не могу вспомнить, где он приземлился).
Вы используете std::move? Так будет быстрее, т.е.
std::move(image).rgbSwapped()