Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何将QImage转换为opencv Mat_C++_Qt_Opencv - Fatal编程技术网

C++ 如何将QImage转换为opencv Mat

C++ 如何将QImage转换为opencv Mat,c++,qt,opencv,C++,Qt,Opencv,我在互联网上搜索过,但找不到将QImage(或QPixmap)转换为OpenCVMat的方法。我该怎么做 非常感谢您的帮助。如果QImage仍然存在,您只需对其执行快速操作,就可以使用QImage内存构建cv::Mat: cv::Mat Mat(image.height(),image.width(),cv_8UC3,(cv::Scalar*)image.scanLine(0)) 这假设QImage为3通道,即RGB888 如果QImage正在消失,则需要复制数据,请参阅 如果QImage是预乘

我在互联网上搜索过,但找不到将
QImage
(或
QPixmap
)转换为OpenCV
Mat
的方法。我该怎么做


非常感谢您的帮助。

如果QImage仍然存在,您只需对其执行快速操作,就可以使用QImage内存构建cv::Mat:

cv::Mat Mat(image.height(),image.width(),cv_8UC3,(cv::Scalar*)image.scanLine(0))

这假设QImage为3通道,即RGB888

如果QImage正在消失,则需要复制数据,请参阅

如果QImage是预乘格式(首选格式),则需要将每个像素转换为OpenCV的BGR布局。cv::cvtcolor()函数可以在最新版本中将ARGB转换为RGB。

或者,您可以在复制数据之前使用转换为RGB。

我会将图像保存到磁盘,然后从cv重新打开它;)


@^我已经尝试过前面的解决方案。它似乎不适合我。虽然我得到了一些图像,它看起来像一些条形码信息的图像。我想可能有一些参数不匹配。

在你提出这个问题一年后,互联网上已经有了很好的答案:

但在我看来,如果您同时使用Qt和OpenCV,那么键入
QImage
可能只是用于显示,在这种情况下,您可能需要使用
QPixmap
,因为它对显示进行了优化。我就是这么做的:

  • 将图像加载为
    cv::Mat
    ,如果要显示图像,请使用第二篇文章中介绍的非复制方法转换为
    QPixmap
  • cv::Mat
    中进行图像处理
  • 在工作流期间的任何时候,您都可以调用类似于
    Mat2QPixmap()
    的函数来获得实时结果
  • 永远不要将
    QPixmap
    转换为
    cv::Mat
    ,考虑到每种类型的用途,这样做毫无意义

  • 我尝试使用OpenCV 3.1+样式代码:

    void qimage_to_mat(const QImage& image, cv::OutputArray out) {
    
        switch(image.format()) {
            case QImage::Format_Invalid:
            {
                cv::Mat empty;
                empty.copyTo(out);
                break;
            }
            case QImage::Format_RGB32:
            {
                cv::Mat view(image.height(),image.width(),CV_8UC4,(void *)image.constBits(),image.bytesPerLine());
                view.copyTo(out);
                break;
            }
            case QImage::Format_RGB888:
            {
                cv::Mat view(image.height(),image.width(),CV_8UC3,(void *)image.constBits(),image.bytesPerLine());
                cvtColor(view, out, cv::COLOR_RGB2BGR);
                break;
            }
            default:
            {
                QImage conv = image.convertToFormat(QImage::Format_ARGB32);
                cv::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:
            {
                cv::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:
            {
                cv::Mat mat;
                cvtColor(image, mat, cv::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:
            {
                cv::Mat mat;
                cvtColor(image, mat, cv::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;
            }
        }
    }
    

    Qt 5.11(可能还有一些早期版本)对此给出了答案:


    再次假设QImage为RGB888(即QImage::Format_RGB888)

    这是一个@PushMaster-不完全是一个复制品,单步执行的问题只会起到相反的作用我必须使用扫描线在图像中的每个指针上循环吗?@user1576633不,QImage连续存储在扫描线(),没有参数,指向图像数据的开头如果QImage正在消失,为什么不简单地将此mat克隆到另一个mat?此外,我找不到完全没有参数的scanLine()重载。您建议的方式是抛出一个编译错误,上面写着:“行”:不是“QImage”的成员,对于“cols”和“scanLine”也是如此。
        cv::Mat mat(image.height(), image.width(),CV_8UC3, image.bits());  
        // image.scanline() does not exist, 
        //and height/width is interchanged for a matrix