upgrade Qt4.8 a Qt5.12 QOpenGLwidget
-
Ciao a tutti, non ho ottenuto risposte dul forum principale così provo qui. Ho eseguito l'upgrade da Qt4.8 a Qt5.12 di una mia vecchia app su Linux. Tra le altre cose utilizza le openCV per convertire un video stream preso da una webcam e lo mostra su una tab ... nel vecchio programma con QtGLWidget che ora è obsoleto e si usa al suo posto QtOpenGLWidget .... in effetti è più pratico e snello nel caso di subclass come il mio. La mia SubClass fa solo lo start e lo stop della ripresa, e nel caso di mancanza di stream visualizza una immagine.png. Per eseguire il render utilizzo le TEXTURE .... non sono per nulla bravo con il rendering, non è il mio campo .... la conversione della classe funziona ma lo stream video a tratti viene renderizzato invece che in una unica finestra in sei diverse (split video) ma solo per un istante poi comincia a fluire regolarmente ... questo succede ad intervalli regolari come ci fosse un buffer che andasse in overflow .... le opencv sono installate con il supporto qt e se utilizzo le finestre native qt opencv per lo stram video, il video esce perfettamente e nitido ... ragione per cui penso il problema dia tutto nella mia Sub-classe e nell'uso che faccio del TEXTURE solo che non vedo dove stia il problema .... allego il codice .cpp
#include "mainwindow.h" #include "ui_mainwindow.h" #include "glwidg.h" #include <QThread> #include <QtCore> #include <QtConcurrent/QtConcurrent> #include <QtConcurrent/QtConcurrentRun> #include <QFuture> #include <QFutureWatcher> #include <QtWidgets> #include <QtWidgets/QAction> #include <QtWidgets/QWidget> #include <QtWidgets/QWidgetAction> #include <QtWidgetsDepends> #include <QtWidgetsVersion> #include <QTableWidget> #include <QTableWidgetItem> #include <QTableWidgetSelectionRange> #include <QTableView> #include <opencv2/opencv.hpp> #include <opencv2/highgui.hpp> #include <iostream> #include <math.h> #include <stdio.h> #include <opencv2/opencv.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/core/core.hpp> #include <sstream> #include <string.h> #include <GL/glu.h> #include <GL/glut.h> #include <GL/freeglut.h> #include <GL/glu.h> #include <QtOpenGL/QGLWidget> #include <QtOpenGL/QtOpenGL> #include <QtOpenGL/QGLBuffer> #include <GLES3/gl3.h> #include <QOpenGLFunctions> #include <QtOpenGL/QGLBuffer> #include <QtOpenGL/QtOpenGL> #include <QTime> #include <QTimer> #include <QDebug> QImage camera000; GLuint texture[1]; QImage GL_formatt; QImage qform; QImage qform1; int cambio1 = 0; cv::Mat imma2; cv::Mat imma3; int play = 0; GLwidg::GLwidg(QWidget *parent) : QOpenGLWidget(parent) { this->setAttribute(Qt::WA_DeleteOnClose); update(); } int GLwidg::xAtPress = 0; int GLwidg::yAtPress = 0; int GLwidg::xsend = 0; int GLwidg::ysend = 0; cv::Point GLwidg::SendMousePoint(0,0); void GLwidg::mouseMoveEvent(QMouseEvent * event) { xAtPress = event->x(); yAtPress = event->y(); xsend = round(xAtPress*1.422222222); ysend = round(yAtPress*1.2); SendMousePoint = cv::Point(xsend, ysend); emit MousePoint(SendMousePoint); } void GLwidg::paintGL() { //makeCurrent(); glClear(GL_COLOR_BUFFER_BIT); if (cambio1 == 0) { qform1.load("/home/mine/images/image480.png"); qq1frame = qform1.scaled(this->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); } else { qq1frame = qform1.scaled(this->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); } qqframe = qq1frame.mirrored(false, true); if(!qqframe.isNull()) /* use for render image but when active */ { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); qqframe = qqframe.scaled(QSize(480,360), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); // or do 2D texture mapping glMatrixMode(GL_MODELVIEW); /**/ glEnable(GL_DEPTH_TEST); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0,qqframe.width(),qqframe.height(),0); glMatrixMode(GL_MODELVIEW); //glDisable(GL_DEPTH_TEST); glLoadIdentity(); glEnable(GL_TEXTURE_2D); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexImage2D( GL_TEXTURE_2D, 0, 4, qqframe.width(), qqframe.height(), 0, GL_BGRA, GL_UNSIGNED_BYTE, qqframe.bits() ); glBegin(GL_QUADS); glTexCoord2f(0,0); glVertex2f(0,qqframe.height()); glTexCoord2f(0,1); glVertex2f(0,0); glTexCoord2f(1,1); glVertex2f(qqframe.width(),0); glTexCoord2f(1,0); glVertex2f(qqframe.width(),qqframe.height()); glEnd(); glDisable(GL_TEXTURE_2D); glDisable(GL_DEPTH_TEST); glFlush(); } if(qqframe.isNull()) { qform1.load("/home/mine/images/image480.png"); qq1frame = qform1.scaled(this->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); } update(); //qDebug() << "x: " << qqframe.width() << "y: " << qqframe.height(); } void GLwidg::donextcam() /* never use*/ { update(); } /// la funzione viene chiamata da un Qthread dove gira l'elaborazione video opencv, //serve per aggiornare i frame frame video - la chiamata arriva da mainwindows in questo modo: //connect(mThr, SIGNAL(_imma_orig(QImage)), ui->glwidg, SLOT(imma_orig_r1(QImage)), Qt::DirectConnection); //-- mthr è il Qthread con opencv/ void GLwidg::imma_orig_r1(QImage qi1) { //qDebug() << "new image to render ....."; cambio1 = 1; qform1 = qi1; //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //makeCurrent(); //paintGL(); update(); } void GLwidg::stopcam1(bool st1) /* use only for stop webcam, uso la funzione per chiudere il flusso video */ { if (st1) { cambio1 = 0; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //paintGL(); update(); } else { cambio1 = 1; } }
spero qualcuno mi possa dare l'indicazione corretta.
-
il problema non era in QOpenGLwidget che funzsiona bene così come impostato .... il problema era sulla conversione cv::mat to QImage .... la funzione richiede una const mentre la mia funzione dava un valore non cost di matrice .... dichiarando la matrice come static tutto si è risolto.