如何将QImage转换为opencv Mat ?

时间:2023-01-31 04:22:48

I have searched on the internet but I cannot find a method of converting a QImage(or QPixmap) to a OpenCV Mat. How would I do this?.

我在网上搜索过,但找不到把QImage(或QPixmap)转换成OpenCV Mat的方法,我该怎么做呢?

Any help is appreciated.

任何帮助都是感激。

4 个解决方案

#1


5  

If the QImage will still exist and you just need to perform a quick operation on it then ou can construct a cv::Mat using the QImage memory

如果QImage仍然存在,并且您只需要对它执行一个快速操作,那么ou可以构造一个cv::使用QImage内存。

cv::Mat mat(image.rows(),image.cols(),CV_8UC3,image.scanline()); This assumes that the Qimage is 3channels, ie RGB888

简历::垫垫(image.rows(),image.cols(),CV_8UC3,image.scanline());这假设Qimage是3channel (RGB888)。

If the Qimage is going away then you need to copy the data, see Qimage to cv::Mat convertion strange behaviour

如果Qimage正在消失,那么您需要复制数据,参见Qimage到cv::Mat转换奇怪行为。

If QImage is Format_ARGB32_Premultiplied (the preffered format) then you will need to convert each pixel to openCV's BGR layout. The cv::cvtcolor() function can convert ARGB to RGB in the latest versions.
Or you can use QImage::convertToformat() to convert to RGB before copying the data

如果QImage是format_argb32_pre(preffered格式),那么您将需要将每个像素转换为openCV的BGR布局。在最新版本中,cvtcolor()函数可以将ARGB转换为RGB。或者您可以使用QImage::convertToformat()在复制数据之前将其转换为RGB。

#2


8  

One year after you issued this question there've been great answers on the internet:

在你发布这个问题的一年之后,互联网上有了很好的答案:

But the way I see it, if you're working with Qt and OpenCV at the same time then type QImage is probably just for displaying, that case you might want to use QPixmap since it's optimized for displaying. So this is what I do:

但我看到的是,如果你同时使用Qt和OpenCV然后键入QImage可能只是为了显示,你可能想要使用QPixmap因为它是为了显示而优化的。这就是我所做的:

  1. Load image as cv::Mat, if you'd like to display the image, convert to QPixmap using the non-copy method introduced in the second article.
  2. 如果您想要显示图像,请使用第二篇文章中介绍的非复制方法转换到QPixmap。
  3. Do your image processing in cv::Mat.
  4. 在简历中做你的图像处理::Mat。
  5. Any time during the workflow you can call upon something like Mat2QPixmap() to get realtime result.
  6. 在工作流中,您可以调用Mat2QPixmap()来获得实时结果。
  7. Never convert QPixmap to cv::Mat, there's no sense doing it considering the purpose of each type.
  8. 永远不要把QPixmap转换成cv::Mat,考虑每种类型的用途是没有意义的。

#3


1  

My attempt in OpenCV 3.1+ style code:

我在OpenCV 3.1+风格代码的尝试:

void qimage_to_mat(const QImage& image, cv::OutputArray out) {

    switch(image.format()) {
        case QImage::Format_Invalid:
        {
            Mat empty;
            empty.copyTo(out);
            break;
        }
        case QImage::Format_RGB32:
        {
            Mat view(image.height(),image.width(),CV_8UC4,(void *)image.constBits(),image.bytesPerLine());
            view.copyTo(out);
            break;
        }
        case QImage::Format_RGB888:
        {
            Mat view(image.height(),image.width(),CV_8UC3,(void *)image.constBits(),image.bytesPerLine());
            cvtColor(view, out, COLOR_RGB2BGR);
            break;
        }
        default:
        {
            QImage conv = image.convertToFormat(QImage::Format_ARGB32);
            Mat view(conv.height(),conv.width(),CV_8UC4,(void *)conv.constBits(),conv.bytesPerLine());
            view.copyTo(out);
            break;
        }
    }
}

void mat_to_qimage(cv::InputArray image, QImage& out)
{
    switch(image.type())
    {
        case CV_8UC4:
        {
            Mat view(image.getMat());
            QImage view2(view.data, view.cols, view.rows, view.step[0], QImage::Format_ARGB32);
            out = view2.copy();
            break;
        }
        case CV_8UC3:
        {
            Mat mat;
            cvtColor(image, mat, COLOR_BGR2BGRA); //COLOR_BGR2RGB doesn't behave so use RGBA
            QImage view(mat.data, mat.cols, mat.rows, mat.step[0], QImage::Format_ARGB32);
            out = view.copy();
            break;
        }
        case CV_8UC1:
        {
            Mat mat;
            cvtColor(image, mat, COLOR_GRAY2BGRA);
            QImage view(mat.data, mat.cols, mat.rows, mat.step[0], QImage::Format_ARGB32);
            out = view.copy();
            break;
        }
        default:
        {
            throw invalid_argument("Image format not supported");
            break;
        }
    }
}

#4


-1  

I'd save the image to disk and reopen it from cv ;)

我将图像保存到磁盘并从cv中重新打开;

@^ I've tried the previous solution. It doesn't seem to working with me. Although I'm getting some image, it looks like some bar code information kind of image. I guess there are some mismatch of parameters.

@ ^我试过以前的解决方案。这似乎与我无关。虽然我得到了一些图像,它看起来像一些条码信息的图像。我想参数不匹配。

#1


5  

If the QImage will still exist and you just need to perform a quick operation on it then ou can construct a cv::Mat using the QImage memory

如果QImage仍然存在,并且您只需要对它执行一个快速操作,那么ou可以构造一个cv::使用QImage内存。

cv::Mat mat(image.rows(),image.cols(),CV_8UC3,image.scanline()); This assumes that the Qimage is 3channels, ie RGB888

简历::垫垫(image.rows(),image.cols(),CV_8UC3,image.scanline());这假设Qimage是3channel (RGB888)。

If the Qimage is going away then you need to copy the data, see Qimage to cv::Mat convertion strange behaviour

如果Qimage正在消失,那么您需要复制数据,参见Qimage到cv::Mat转换奇怪行为。

If QImage is Format_ARGB32_Premultiplied (the preffered format) then you will need to convert each pixel to openCV's BGR layout. The cv::cvtcolor() function can convert ARGB to RGB in the latest versions.
Or you can use QImage::convertToformat() to convert to RGB before copying the data

如果QImage是format_argb32_pre(preffered格式),那么您将需要将每个像素转换为openCV的BGR布局。在最新版本中,cvtcolor()函数可以将ARGB转换为RGB。或者您可以使用QImage::convertToformat()在复制数据之前将其转换为RGB。

#2


8  

One year after you issued this question there've been great answers on the internet:

在你发布这个问题的一年之后,互联网上有了很好的答案:

But the way I see it, if you're working with Qt and OpenCV at the same time then type QImage is probably just for displaying, that case you might want to use QPixmap since it's optimized for displaying. So this is what I do:

但我看到的是,如果你同时使用Qt和OpenCV然后键入QImage可能只是为了显示,你可能想要使用QPixmap因为它是为了显示而优化的。这就是我所做的:

  1. Load image as cv::Mat, if you'd like to display the image, convert to QPixmap using the non-copy method introduced in the second article.
  2. 如果您想要显示图像,请使用第二篇文章中介绍的非复制方法转换到QPixmap。
  3. Do your image processing in cv::Mat.
  4. 在简历中做你的图像处理::Mat。
  5. Any time during the workflow you can call upon something like Mat2QPixmap() to get realtime result.
  6. 在工作流中,您可以调用Mat2QPixmap()来获得实时结果。
  7. Never convert QPixmap to cv::Mat, there's no sense doing it considering the purpose of each type.
  8. 永远不要把QPixmap转换成cv::Mat,考虑每种类型的用途是没有意义的。

#3


1  

My attempt in OpenCV 3.1+ style code:

我在OpenCV 3.1+风格代码的尝试:

void qimage_to_mat(const QImage& image, cv::OutputArray out) {

    switch(image.format()) {
        case QImage::Format_Invalid:
        {
            Mat empty;
            empty.copyTo(out);
            break;
        }
        case QImage::Format_RGB32:
        {
            Mat view(image.height(),image.width(),CV_8UC4,(void *)image.constBits(),image.bytesPerLine());
            view.copyTo(out);
            break;
        }
        case QImage::Format_RGB888:
        {
            Mat view(image.height(),image.width(),CV_8UC3,(void *)image.constBits(),image.bytesPerLine());
            cvtColor(view, out, COLOR_RGB2BGR);
            break;
        }
        default:
        {
            QImage conv = image.convertToFormat(QImage::Format_ARGB32);
            Mat view(conv.height(),conv.width(),CV_8UC4,(void *)conv.constBits(),conv.bytesPerLine());
            view.copyTo(out);
            break;
        }
    }
}

void mat_to_qimage(cv::InputArray image, QImage& out)
{
    switch(image.type())
    {
        case CV_8UC4:
        {
            Mat view(image.getMat());
            QImage view2(view.data, view.cols, view.rows, view.step[0], QImage::Format_ARGB32);
            out = view2.copy();
            break;
        }
        case CV_8UC3:
        {
            Mat mat;
            cvtColor(image, mat, COLOR_BGR2BGRA); //COLOR_BGR2RGB doesn't behave so use RGBA
            QImage view(mat.data, mat.cols, mat.rows, mat.step[0], QImage::Format_ARGB32);
            out = view.copy();
            break;
        }
        case CV_8UC1:
        {
            Mat mat;
            cvtColor(image, mat, COLOR_GRAY2BGRA);
            QImage view(mat.data, mat.cols, mat.rows, mat.step[0], QImage::Format_ARGB32);
            out = view.copy();
            break;
        }
        default:
        {
            throw invalid_argument("Image format not supported");
            break;
        }
    }
}

#4


-1  

I'd save the image to disk and reopen it from cv ;)

我将图像保存到磁盘并从cv中重新打开;

@^ I've tried the previous solution. It doesn't seem to working with me. Although I'm getting some image, it looks like some bar code information kind of image. I guess there are some mismatch of parameters.

@ ^我试过以前的解决方案。这似乎与我无关。虽然我得到了一些图像,它看起来像一些条码信息的图像。我想参数不匹配。