3ヶ月後にこれが役に立つかどうかはわかりません。しかし、私はOpenCVを使って一連の画像を操作し、それをQTインタフェース上に表示する必要があるのと同じ種類のアプリケーションを持っています。かなりの周りでグーグルグーグルをした後、私は非常に滑らかなソリューションを見つけた。 OpenGLのglDrawPixelsを使用して、生の画像データを直接Qtインタフェースに描画します。最高の部分は、あなたは余分なコンバージョンコードを書く必要はありません。ビューポートと座標を設定するためのopenglの基本コード。 IplImage *ポインタを取得し、そのデータを使って画像を描画する関数を持つコードを調べてください。特定のサイズの画像を表示するには、パラメータ(特にWIDTHとHEIGHT変数)を微調整する必要があるかもしれません。 そして、私はあなたが使っているシステムをどのように構築しているのか分かりません。私はcmakeを使い、QtのOpenGLライブラリを使用していますが、OpenGLの依存関係をセットアップする必要がありました。
QGLWidgetから派生したクラスQIplImageを実装し、paintGLメソッドをオーバーライドしてピクセルデータをフレームに描画しました。
//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();
}
希望します。
BGRのことは間違いありません。 OpenCVに画像をBGR形式(QtのRGBと同等ですが、残念ながらQtにはBGR形式がありません)で保存するように依頼することで、この問題を回避しています。つまり、OpenCVのルーチンに注意する必要がありますが、問題ではありません。また、OpenGLのテクスチャオプションも見ていきます。ありがとう! – Calvin
FWIW、それは効率的かどうかわからないので、メソッドQImage :: rgbSwappedはRGBをBGRに変換します。http://qt-project.org/doc/qt-5.0/qtgui/qimage.html#rgbSwappedを参照してください。私はこのプロジェクトのソースコードからこれを学びました:http://code.google.com/p/qt-opencv-multithreaded/ –
@JongBorそれは、ディスプレイAPIがBGRAを使う傾向があるという問題であるRGB/BGRではないことを教えてください(QImageを含む)画像処理APIはBGRを使用しているので、画像全体を渡り、余分な「A」バイトをパディングする必要があります。 –