c++ - 将 cv::mat 转换为 QImage

标签 c++ qt opencv qt5

如标题所说,我正在尝试将 cv::mat 转换为 QImage。我正在做的是在垫子上使用 equalizeHist() 函数,然后将其转换为 QImage 以显示在 Qt 的小部件窗口中。我知道垫子可以正常工作并正确加载图像,因为均衡后的图像将使用 imshow() 显示在新窗口中,但是当将此垫子转换为 QImage 时,我无法将其显示在窗口中。我相信问题出在从垫子到 QImage 的转换上,但找不到问题所在。下面是我的代码片段的一部分。

Mat image2= imread(directoryImage1.toStdString(),0);
//cv::cvtColor(image2,image2,COLOR_BGR2GRAY);
Mat histEquImg;
equalizeHist(image2,histEquImg);
imshow("Histogram Equalized Image 2", histEquImg);
//QImage img=QImage((uchar*) histEquImg.data, histEquImg.cols, histEquImg.rows, histEquImg.step, QImage::Format_ARGB32);
imageObject= new QImage((uchar*) histEquImg.data, histEquImg.cols, histEquImg.rows, histEquImg.step, QImage::Format_RGB888);
image = QPixmap::fromImage(*imageObject);
scene=new QGraphicsScene(this); //create a frame for image 2
scene->addPixmap(image); //put image 1 inside of the frame
ui->graphicsView_4->setScene(scene); //put the frame, which contains image 3, to the GUI
ui->graphicsView_4->fitInView(scene->sceneRect(),Qt::KeepAspectRatio); //keep the dimension ratio of image 3

没有错误发生,程序也没有崩溃。 提前致谢。

最佳答案

你的问题是 QImage 到 cv::Mat 的转换,当在 cv::imread 中使用标志 0 意味着读数是灰度时,你是使用格式为 QImage::Format_RGB888 的转换。我使用以下函数将 cv::Mat 转换为 QImage:

static QImage MatToQImage(const cv::Mat& mat)
{
    // 8-bits unsigned, NO. OF CHANNELS=1
    if(mat.type()==CV_8UC1)
    {
        // Set the color table (used to translate colour indexes to qRgb values)
        QVector<QRgb> colorTable;
        for (int i=0; i<256; i++)
            colorTable.push_back(qRgb(i,i,i));
        // Copy input Mat
        const uchar *qImageBuffer = (const uchar*)mat.data;
        // Create QImage with same dimensions as input Mat
        QImage img(qImageBuffer, mat.cols, mat.rows, mat.step, QImage::Format_Indexed8);
        img.setColorTable(colorTable);
        return img;
    }
    // 8-bits unsigned, NO. OF CHANNELS=3
    if(mat.type()==CV_8UC3)
    {
        // Copy input Mat
        const uchar *qImageBuffer = (const uchar*)mat.data;
        // Create QImage with same dimensions as input Mat
        QImage img(qImageBuffer, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);
        return img.rgbSwapped();
    }
    return QImage();
}

在那之后,我看到您在评论时对 QGraphicsViewQGraphicsScene 的工作方式有误解:将包含图像 3 的框架放入 GUI,使用 ui->graphicsView_4->setScene(scene); 设置的不是帧而是场景,场景应该只设置一次,最好在构造函数中设置。

// constructor
scene = new QGraphicsScene(this);
ui->graphicsView->setScene(scene);

所以当你想加载图像时,只需使用场景:

cv::Mat image= cv::imread(filename.toStdString(), CV_LOAD_IMAGE_GRAYSCALE);

cv::Mat histEquImg;
equalizeHist(image, histEquImg);

QImage qimage = MatToQImage(histEquImg);
QPixmap pixmap = QPixmap::fromImage(qimage);
scene->addPixmap(pixmap);
ui->graphicsView->fitInView(scene->sceneRect(), Qt::KeepAspectRatio);

<支持> 完整的示例可以在下面的 link 中找到.

关于c++ - 将 cv::mat 转换为 QImage,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52583391/

相关文章:

c++ - 我如何在 QT 中将 QLabel 堆叠在一起?

c++ - 将字符串和变量打印到 glwindow

c++ - 静态类变量——与构造函数一起使用

python - Python ctypes 的数组输出?

qt - QML 的组件和实例化器之间的区别?

c++ - Qt 信号槽不工作

opencv - 精明的边缘与骨架化

qt - OpenGL 纹理映射内存泄漏

python - 检测图像中线的起点和终点(numpy 数组)

c++ - 委托(delegate)应该有一个虚拟析构函数吗?