简体   繁体   English

如何将Grayscale / binary Mat转换为QImage?

[英]How to convert Grayscale/binary Mat to QImage?

I have started learning Qt and is trying to make a simple video Player which will load the video and will play it. 我已经开始学习Qt并且正在尝试制作一个简单的视频播放器,它将加载视频并播放它。 It worked perfectly fine. 它工作得非常好。 Now added thresholding functionality to it. 现在添加了阈值功能。 The threshold value will be obtained from the spinBox. 阈值将从spinBox获得。 Code is written in such a way that thresholding operation will be done with value in spinBox except at value 0 (where normal video is displayed). 代码以这样的方式编写,即除了值0(显示正常视频)之外,将对spinBox中的值进行阈值处理操作。 So this is my function for the same: 所以这是我的功能:

void Player::run()
{

while(!stop )
{

    if(!capture.read(frame))
        stop = true;
    // convert RGB to gray
    if(frame.channels() == 3)
    {
        if(thresh == 0)
         {
            cvtColor(frame, RGBframe, CV_BGR2RGB);
            img = QImage((const unsigned char*)(RGBframe.data),
                          RGBframe.cols,RGBframe.rows,QImage::Format_RGB888);

         }
        else
        {
            Mat temp;
            cvtColor(frame, temp, CV_BGR2GRAY);
            threshold(temp, binary, thresh, 255, 0);
            img = QImage((const unsigned char*)(binary.data),
                              binary.cols, binary.rows, QImage::Format_Indexed8);




            bool save = img.save("/home/user/binary.png");

             cout<<"threshold value = "<<thresh<<endl;

            //imshow("Binary", binary);
        }
     }
     else
     {
        if(thresh == 0) // original Image
        {
            img = QImage((const unsigned char*)(frame.data),
                             frame.cols,frame.rows,QImage::Format_Indexed8);

        }
        else // convert to Binary Image
        {

            threshold(frame, binary, thresh, 255, 0);

            img = QImage((const unsigned char*)(binary.data),
                              binary.cols, binary.rows, QImage::Format_Indexed8);
        }




     }

     emit processedImage(img);
     this->msleep(delay);
}
}  

for spinBox value equals 0 it runs fine but when spinBox value is incremented I get only black screen. 对于spinBox值等于0它运行正常但是当spinBox值递增时我只得到黑屏。 I tried imshow(cv:: Mat binary) and it is showing the correct binary image but when I try to save QImage img it is some random black and white pixels (though of same size of original frame). 我试过imshow(cv:: Mat binary) ,它显示正确的二进制图像但是当我尝试保存QImage img它是一些随机的黑白像素(尽管原始帧的大小相同)。

It seems that you're missing the color table for your indexed image. 您似乎缺少索引图像的颜色表。 You need to add a color table (before the while loop): 您需要添加一个颜色表(在while循环之前):

 QVector<QRgb> sColorTable(256); 
 for (int i = 0; i < 256; ++i){ sColorTable[i] = qRgb(i, i, i); }

and after you create the QImage from the binary Mat you need to add 并且从二进制Mat创建QImage后,您需要添加

 img.setColorTable(sColorTable);

Or, as pointed out by @KubaOber , from Qt 5.5 you can also use the format QImage::Format_Grayscale8 : 或者,正如@KubaOber所指出的,从Qt 5.5开始,你也可以使用格式QImage::Format_Grayscale8

// From Qt 5.5
QImage image(inMat.data, inMat.cols, inMat.rows, 
             static_cast<int>(inMat.step),
             QImage::Format_Grayscale8);

In general, you can wrap all Mat to QImage conversion in a function. 通常,您可以在函数中包装所有MatQImage转换。 Below there is the bug corrected and updated version of cvMatToQImage originally found here . 下面是最初在此处找到的cvMatToQImage错误更正更新版本。

You can then remove all the conversion to QImage from your code and use this function instead. 然后,您可以从代码中删除所有到QImage的转换,并使用此函数。

QImage cvMatToQImage(const cv::Mat &inMat)
{
    switch (inMat.type())
    {
        // 8-bit, 4 channel
    case CV_8UC4:
    {
        QImage image(inMat.data,
            inMat.cols, inMat.rows,
            static_cast<int>(inMat.step),
            QImage::Format_ARGB32);

        return image;
    }

    // 8-bit, 3 channel
    case CV_8UC3:
    {
        QImage image(inMat.data,
            inMat.cols, inMat.rows,
            static_cast<int>(inMat.step),
            QImage::Format_RGB888);

        return image.rgbSwapped();
    }

    // 8-bit, 1 channel
    case CV_8UC1:
    {
#if QT_VERSION >= 0x050500

        // From Qt 5.5
        QImage image(inMat.data, inMat.cols, inMat.rows, 
                     static_cast<int>(inMat.step),
                     QImage::Format_Grayscale8);
#else
        static QVector<QRgb>  sColorTable;

        // only create our color table the first time
        if (sColorTable.isEmpty())
        {
            sColorTable.resize(256);
            for (int i = 0; i < 256; ++i)
            {
                sColorTable[i] = qRgb(i, i, i);
            }
        }

        QImage image(inMat.data,
            inMat.cols, inMat.rows,
            static_cast<int>(inMat.step),
            QImage::Format_Indexed8);

        image.setColorTable(sColorTable);
#endif
    }

    default:
        qWarning() << "cvMatToQImage() - cv::Mat image type not handled in switch:" << inMat.type();
        break;
    }

    return QImage();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM