如何使用Visual Studio将OpenCV图像查看窗口推入QT GUI?

zeb*_*bra 8 c++ qt opencv visual-studio-2010

我想创建一个带有2个矩形的GUI来观看视频(一个用于查看输入视频,一个用于查看经过后处理的视频).

我希望它能够集成到QT制作的GUI中,但我希望从OpenCV中填充这些视频区域,作为OpenCV cv::nameWindow方法的替代方案.

我怎样才能做到这一点?

bor*_*ges 10

做你想做的基本工作流程是:

  1. 使用OpenCV API打开视频(例如cvCreateFileCapture)
  2. 从视频中获取IplImage帧(cvQueryFrame)
  3. 将它们转换为QImage(参见附后的代码)
  4. 在QLabel中显示QImage(QLabel :: setPixmap和QPixmap :: fromImage)
  5. 循环帧更新(例如,使用QTimer,使用视频帧速率)

将IplImage转换为QImage的代码(假设RGB32Bits图像):

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;
}
Run Code Online (Sandbox Code Playgroud)

理解上面的代码应该是直截了当的.任何疑惑只是让我们知道.

此"低级别"选项允许您在显示每个帧之前对其进行操作.如果您只想通过Qt显示视频,可以使用Phonon框架.

  • 好答案!但是,他要求使用C++,你使用的是OpenCV的C API.另外我认为如果想要覆盖图像中的每个像素,cvGet2D效率都不高! (2认同)

ypn*_*nos 8

这是将cv :: Mat转换为QImage的代码.方法分别用于24位RGB或灰度浮点.

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;
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以在Qt小部件中使用QImage.见borges的回答.