zebra
zebra

Reputation: 6531

How to push an OpenCV image viewing window into a QT GUI with Visual studio?

I want to create a GUI with 2 rectangles for viewing videos (one where you see the input video, one where you see the post-processed video).

I want it to be integrated into a QT-made GUI, but I want these video areas to be populated from OpenCV, as an alternative to OpenCV's cv::nameWindow method.

How can I do this?

Upvotes: 8

Views: 9713

Answers (2)

ypnos
ypnos

Reputation: 52407

Here is code that converts a cv::Mat into a QImage. Methods are for 24bit RGB or grayscale floating point, respectively.

QImage Mat2QImage(const cv::Mat3b &src) {
        QImage dest(src.cols, src.rows, QImage::Format_ARGB32);
        for (int y = 0; y < src.rows; ++y) {
                const cv::Vec3b *srcrow = src[y];
                QRgb *destrow = (QRgb*)dest.scanLine(y);
                for (int x = 0; x < src.cols; ++x) {
                        destrow[x] = qRgba(srcrow[x][2], srcrow[x][1], srcrow[x][0], 255);
                }
        }
        return dest;
}


QImage Mat2QImage(const cv::Mat_<double> &src)
{
        double scale = 255.0;
        QImage dest(src.cols, src.rows, QImage::Format_ARGB32);
        for (int y = 0; y < src.rows; ++y) {
                const double *srcrow = src[y];
                QRgb *destrow = (QRgb*)dest.scanLine(y);
                for (int x = 0; x < src.cols; ++x) {
                        unsigned int color = srcrow[x] * scale;
                        destrow[x] = qRgba(color, color, color, 255);
                }
        }
        return dest;
}

Then, you can use the QImage inside a Qt widget. See borges' answer.

Upvotes: 8

borges
borges

Reputation: 3687

The basic workflow to do what you desire is:

  1. Open the video with OpenCV API (cvCreateFileCapture, for example)
  2. Grab IplImage frames from video (cvQueryFrame)
  3. Convert them to QImage (see attached code bellow)
  4. Show QImage on within a QLabel (QLabel::setPixmap and QPixmap::fromImage)
  5. Loop the frame update (using a QTimer, for example, with video framerate)

Code to convert IplImage to QImage (assuming RGB32Bits images):

QImage *IplImageToQImage(IplImage *input)
{
    if (!input)
        return 0;

    QImage image(input->width, input->height, QImage::Format_RGB32);

    uchar* pBits = image.bits();
    int nBytesPerLine = image.bytesPerLine();

    for (int n = 0; n < input->height; n++)
    {
        for (int m = 0; m < input->width; m++)
        {
            CvScalar s = cvGet2D(input, n, m);
            QRgb value = qRgb((uchar)s.val[2], (uchar)s.val[1], (uchar)s.val[0]);

            uchar* scanLine = pBits + n * nBytesPerLine;
            ((uint*)scanLine)[m] = value;
        }
    }

    return image;
}

The understanding of the code above should be straightforward. Any doubts just let us know.

This "low level" option allows you to manipulate each individual frame before displaying it. If you just want to display a video via Qt, you can use the Phonon framework.

Upvotes: 11

Related Questions