How to covert QT QImage into OpenCV IplImage and vise-versa.

These days,I am working on developing an application for “High Voltage Electron Microscope”.Basically it takes images from “High Voltage Electron Microscope” and do tomographic reconstruction and 3D reconstruction…etc I use QT4 for user interface and and OpenCV for image processing functionalities and OpenGL as core frameworks.

I came up with big obstacle since it utilise many frameworks and have to handle conversion in between many image-data-structures.Eg : QImage in QT4 , IplImage in OpenCV and some custom image data structure for internal algorithms.

I came up with following conversion between QImage to IplImage.Hope it will helpful to someone whose spending hours on google.

IplImage* QImage2IplImage(QImage *qimg)
{

IplImage *imgHeader = cvCreateImageHeader( cvSize(qimg->width(), qimg->height()), IPL_DEPTH_8U, 4);
imgHeader->imageData = (char*) qimg->bits();

uchar* newdata = (uchar*) malloc(sizeof(uchar) * qimg->byteCount());
memcpy(newdata, qimg->bits(), qimg->byteCount());
imgHeader->imageData = (char*) newdata;
//cvClo
return imgHeader;
}

QImage*  IplImage2QImage(IplImage *iplImg)
{
int h = iplImg->height;
int w = iplImg->width;
int channels = iplImg->nChannels;
QImage *qimg = new QImage(w, h, QImage::Format_ARGB32);
char *data = iplImg->imageData;

for (int y = 0; y < h; y++, data += iplImg->widthStep)
{
for (int x = 0; x < w; x++)
{
char r, g, b, a = 0;
if (channels == 1)
{
r = data[x * channels];
g = data[x * channels];
b = data[x * channels];
}
else if (channels == 3 || channels == 4)
{
r = data[x * channels + 2];
g = data[x * channels + 1];
b = data[x * channels];
}

if (channels == 4)
{
a = data[x * channels + 3];
qimg->setPixel(x, y, qRgba(r, g, b, a));
}
else
{
qimg->setPixel(x, y, qRgb(r, g, b));
}
}
}
return qimg;

}

29 thoughts on “How to covert QT QImage into OpenCV IplImage and vise-versa.

  1. Ohhh .. “Hope it will helpful to someone whose spending hours on google.” .. indeed.
    Thank you 🙂

    1. hi Ashok, could you tell me what conversion didnt work ?
      Is it QImage to IplImage or IplImage to QImage ?
      I have only shown here general methods to get an idea how to do the conversion.You might have to extend these for handle various color-channels and bitrates.

  2. Hi
    I am trying to convert QImage to IplImage with depth 8 and channels 3. But i am getting gray image only and also the image is not clear. Is there anyway to get color image. If possible help me with code.

    Thanks

  3. Im googling how to solve the speed of IplImage to QImage transform because my case is very slow. Can your method achieve 30 fps? The following is mine.

    frame = cvQueryFrame(capture);
    cvCvtColor(frame,frame,CV_BGR2RGB);
    m_i = QImage((unsigned char *)frame->imageDataOrigin,frame->width,frame->height,QImage::Format_RGB888);

    1. hi,
      i think your method is much faster because you directly using a memory buffer.I assign pixel data for each pixel inside two loops,so performance overhead there!

  4. Hey just, FYI, you have a typo in your code for converting from a QImage to an IPLImage: when you initialize imgHeader you are setting the dimensions to be (qimg->width(), qimg->width()). Second parameter should be height.

  5. Excellent job, that has helped me a lot! The only modification I’ve had to make on your code (I only used the Ipl->QImage portion) consisted in inverting the “R” and “B” coordinates.

  6. Hey , thanks for the code,, this i s really helpful ..
    but i have a small problem with this code. Look in my application i am converting a QImage to IplImage and then performing the Face Detection using LibFace , the problem is that some low quality images creates application crash . Do you have any idea.

    1. hay harshi ,glad it helped you.Sorry I havent worked with LibFace.But we use this conversion and OpenCV-edge-detection on low quality microscopic images.It works just fine.

  7. Hi,

    I used your IplImage2QImage function to convert the following IplImage:

    IplImage *marker_inside=cvCreateImage(cvSize(50,50),IPL_DEPTH_8U,1);

    and display it in a QLabel.

    QLabel *imgDisplayLabel = new QLabel(“LOADING…”);
    imgDisplayLabel->setPixmap(QPixmap::fromImage(IplImage2QImage(marker_inside)));
    imgDisplayLabel->setGeometry(QRect(312, 454, 21, 20));

    But I’m getting the “error: C2664: ‘QPixmap::fromImage’ : cannot convert parameter 1 from ‘QImage *’ to ‘const QImage &’
    Reason: cannot convert from ‘QImage *’ to ‘const QImage’
    No constructor could take the source type, or constructor overload resolution was ambiguous”

    How to avoid this?

    thanks

    1. check fromImage() method signature.It takes a reference of QImage.You are passing a pointer (QImage*). de-reference it before passing – like QPixmap::fromImage(*(IplImage2QImage(marker_inside)));

      1. Thanks a lot for the instant reply. mainwindow.obj:-1: error: LNK2005: “class QImage * __cdecl IplImage2QImage(struct _IplImage *)” (?IplImage2QImage@@YAPAVQImage@@PAU_IplImage@@@Z) already defined in main.obj I have added “#ifndef” safety to all headers.

      2. make sure you havent defined IplImage2QImage() twice in your source code.It seems you have defined it in both mainwindow.cpp and main.cpp

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s