Ich weiß nicht, ob dies jetzt nach 3 Monaten für Sie nützlich sein könnte. Aber ich habe die gleiche Art von Anwendung, wo ich einen Strom von Bildern mit OpenCV bearbeiten und auf einer QT-Oberfläche anzeigen muss. Nachdem ich ziemlich viel gegoogelt hatte, stieß ich auf eine sehr glatte Lösung. Verwenden Sie opengls glDrawPixels, um Rohbilddaten direkt auf der Qt-Oberfläche zu zeichnen. Der beste Teil, Sie müssen keinen zusätzlichen Conversion-Code schreiben. Nur der grundlegende Code für opengl zum Einrichten eines Ansichtsfensters und einer Koordinate. Sehen Sie sich den Code mit einer Funktion an, die einen IplImage * -Zeiger verwendet und diese Daten zum Zeichnen des Bildes verwendet. Möglicherweise müssen Sie die Parameter (insbesondere die WIDTH- und HEIGHT-Variablen) etwas anpassen, um ein Bild mit einer bestimmten Größe anzuzeigen. Und ja, ich weiß nicht, welches Build-System Sie verwenden. Ich benutzte cmake und musste Abhängigkeiten für opengl einrichten, obwohl ich OpenGL-Bibliotheken von Qt verwende.
Ich habe eine Klasse QIplImage implementiert, die von QGLWidget abgeleitet ist und ihre paintGL-Methode überschreibt, um die Pixeldaten auf den Frame zu zeichnen.
//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();
}
Hoffe, dass hilft.
Die BGR-Sache ist sicher nervig; Wir umgehen es jetzt, indem wir OpenCV bitten, Bilder im BGR-Format zu speichern (was Qt's RGB entspricht; leider hat Qt kein BGR-Format). Das bedeutet, dass wir mit einigen Routinen von OpenCV vorsichtig sein müssen, aber das sollte kein Problem sein. Ich werde auch in die OpenGL-Textur-Option schauen. Vielen Dank! – Calvin
FWIW, da ich nicht weiß, ob es effizient ist: Methode QImage :: rgbSwapped konvertiert RGB in BGR, siehe http://qt-project.org/doc/qt-5.0/qtgui/qimage.html#rgbSwapped. Ich habe das aus dem Quellcode dieses Projekts gelernt: http://code.google.com/p/qt-opencv-multithreaded/ –
@JongBorLeem Es ist nicht das RGB/BGR-Problem, dass die Anzeige-APIs dazu neigen, BGRA zu verwenden (einschließlich QImage), während Bildverarbeitungs-APIs BGR verwenden - also müssen Sie das gesamte Bild durchgehen und es kopieren das zusätzliche 'A' Byte –