简体   繁体   中英

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?

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 .

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM