Non so se questo potrebbe essere utile a voi ora dopo 3 mesi. Ma sto avendo lo stesso tipo di applicazione in cui devo manipolare un flusso di immagini usando OpenCV e visualizzarlo su un'interfaccia QT. Dopo aver cercato su Google un po ', mi sono imbattuto in una soluzione molto lucida. Usa opengl's glDrawPixels per disegnare i dati grezzi dell'immagine direttamente sull'interfaccia Qt. La parte migliore, non devi scrivere alcun codice di conversione extra. Solo il codice di base per opengl per l'impostazione di una finestra e coordinate. Controlla il codice che ha una funzione che prende un puntatore IplImage * e usa quei dati per disegnare l'immagine. Potrebbe essere necessario modificare leggermente i parametri (in particolare le variabili WIDTH e HEIGHT) per visualizzare un'immagine con una dimensione specifica. E sì, non so quale sistema di generazione stai usando. Ho usato cmake e ho dovuto impostare le dipendenze per opengl anche se sto usando le librerie opengl di Qt.
Ho implementato una classe QIplImage che deriva da QGLWidget e sovrascrive il suo metodo paintGL per disegnare i dati dei pixel sul frame.
//File qiplimage.h
class QIplImage : public QGLWidget
{
Q_OBJECT
public:
QIplImage(QWidget *parent = 0,char *name=0);
~QIplImage();
void paintGL();
void initializeGL();
void resizeGL(int,int);
bool drawing;
public slots:
void setImage(IplImage);
private:
Ui::QIplImage ui;
IplImage* original;
GLenum format;
GLuint texture;
QColor bgColor;
char* name;
bool hidden;
int startX,startY,endX,endY;
QList<QPointF*> slopes;
QWidget* parent;
int mouseX,mouseY;
};
//End of file qiplimage.h
//file qiplimage.cpp
#include "qiplimage.h"
#include <Globals.h>
QIplImage::QIplImage(QWidget *parent) :
QGLWidget(parent)
{
}
QIplImage::QIplImage(QWidget *parent,char* name): QGLWidget(parent)
{
ui.setupUi(this);
//This is required if you need to transmit IplImage over
// signals and slots.(That's what I am doing in my application
qRegisterMetaType<IplImage>("IplImage");
resize(384,288);
this->name=name;
this->parent=parent;
hidden=false;
bgColor= QColor::fromRgb(0xe0,0xdf,0xe0);
original=cvCreateImage(cvSize(this->width(),this->height()),IPL_DEPTH_8U,3);
cvZero(original);
switch(original->nChannels) {
case 1:
format = GL_LUMINANCE;
break;
case 2:
format = GL_LUMINANCE_ALPHA;
break;
case 3:
format = GL_BGR;
break;
default:
return;
}
drawing=false;
setMouseTracking(true);
mouseX=0;mouseY=0;
initializeGL();
}
void QIplImage::initializeGL()
{
qglClearColor(bgColor);
//glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0,this->width(),this->height(),0.0f,0.0f,1.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_TEXTURE_2D);
glGenTextures(3,&texture);
glBindTexture(GL_TEXTURE_2D,texture);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glBindTexture(GL_TEXTURE_2D,texture); glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,this->width(),this->height(),0,GL_BGR,GL_UNSIGNED_BYTE,NULL);
glDisable(GL_TEXTURE_2D);
}
void QIplImage::setImage(IplImage image){
original=ℑ
//cvShowImage(name,original);
updateGL();
}
void QIplImage::paintGL(){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
if(!hidden){
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0f,this->width(),this->height(),0.0f,0.0f,1.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,texture);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,original->width,original->height,0,GL_BGR_EXT,GL_UNSIGNED_BYTE,original->imageData);
glBegin(GL_QUADS);
glTexCoord2i(0,1); glVertex2i(0,this->height());
glTexCoord2i(0,0); glVertex2i(0,0);
glTexCoord2i(1,0); glVertex2i(this->width(),0);
glTexCoord2i(1,1); glVertex2i(this->width(),this->height());
glEnd();
glFlush();
}
}
void QIplImage::resizeGL(int width,int height){
glViewport(0,0,this->width(),this->height());
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0f,this->width(),this->height(),0.0f,0.0f,1.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
Spero che questo aiuti.
La cosa BGR è sicuramente fastidiosa; lo stiamo facendo ora chiedendo a OpenCV di memorizzare immagini in formato BGR (che è equivalente a Qt RGB, purtroppo Qt non ha un formato BGR). Ciò significa che dobbiamo fare attenzione con alcune delle routine di OpenCV, ma non dovrebbe essere un problema. Cercherò anche l'opzione texture OpenGL. Grazie! – Calvin
FWIW, poiché non so se sia efficiente: metodo QImage :: rgbSwapped converte RGB in BGR, vedi http://qt-project.org/doc/qt-5.0/qtgui/qimage.html#rgbSwapped. Ho imparato questo dal codice sorgente di questo progetto: http://code.google.com/p/qt-opencv-multithreaded/ –
@JongBorLeem non è l'RGB/BGR che è il problema è che le API di visualizzazione tendono a utilizzare BGRA (incluso QImage) mentre le API di imageprocessing utilizzano BGR - quindi è necessario scorrere l'intera immagine e copiarla estrapolando il byte extra "A" –