【问题标题】:How to push an OpenCV image viewing window into a QT GUI with Visual studio?如何使用 Visual Studio 将 OpenCV 图像查看窗口推送到 QT GUI?
【发布时间】:2012-02-10 11:20:48
【问题描述】:

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

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

我该怎么做?

【问题讨论】:

  • 我不知道,如何在Qt中集成opencv的窗口,但是如果你在任何阶段得到IplImage,它可以很容易地转换为QImageQPixMap ,可以显示在QLabel
  • 作为 Lol4t0,我不知道如何将 OpenCV 的视频集成到一些 QWidget 中。但我可以回答如何轻松手动执行此操作。这真的很简单。
  • @borges 那么请回答:)

标签: c++ visual-studio-2010 qt opencv


【解决方案1】:

这是将 cv::Mat 转换为 QImage 的代码。方法分别用于 24bit 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;
}

然后,您可以在 Qt 小部件中使用 QImage。请参阅博尔赫斯的回答。

【讨论】:

  • 是否有任何社区在 Qt 和 OpenCV 的集成方面工作得更多?还是就这样(我的意思是你的代码)?!我也是新手,我目前的兴趣是这个。谢谢!
  • 好吧,现在 highgui 模块可选地构建了 Qt 支持(imshow 将为您提供一个漂亮的 Qt 窗口,带有用于缩放/平移、保存到文件等的按钮)。它起源于 Google Summer of Code 项目。所以 OpenCV 本身现在在 highgui 模块中具有集成它们的功能。据我所知,它没有通过 API 公开。我不知道他们是否有这样做的计划。不过,这会很有意义。
【解决方案2】:

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

  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;
}

对上面代码的理解应该是直截了当的。如有任何疑问,请告诉我们。

此“低级别”选项允许您在显示每个单独的帧之前对其进行操作。如果只想通过 Qt 显示视频,可以使用Phonon framework

【讨论】:

  • 好答案!但是,他要求 C++,你使用 OpenCV 的 C API。另外我认为如果你想检查图像中的每个像素,cvGet2D 并不是很有效!
  • 如果您使用 RGB888 作为 Qimage,您可以直接使用输入图像。或者使用 cvtColor() 转换为 BGRA 以获得更好的 qimage 性能
  • 问题是它比使用 cvShowImage 慢得多(在它自己的窗口中)
猜你喜欢
  • 2012-08-10
  • 2013-04-10
  • 1970-01-01
  • 1970-01-01
  • 2013-02-01
  • 2019-07-04
  • 1970-01-01
  • 2023-03-10
相关资源
最近更新 更多