Multithreading Qt+;OpenCV-在QLabel上显示图像

Multithreading Qt+;OpenCV-在QLabel上显示图像,multithreading,qt,opencv,Multithreading,Qt,Opencv,我正在尝试从摄像头捕获实时视图,并将其重定向到QLabel上。 但只有半视图(见下文): 左侧窗口使用cv::imshow()显示,这非常有效。 我在另一个线程中捕获Mat,然后发出一个带有Qimage作为参数的信号,然后将图像设置为插槽中的QLabel 代码如下: while(true){ cam >> mat; cv::imshow("name",mat); emit send_UIupdate(mat2qimage(mat)); } 在插槽中将图像设

我正在尝试从摄像头捕获实时视图,并将其重定向到QLabel上。 但只有半视图(见下文):

左侧窗口使用cv::imshow()显示,这非常有效。 我在另一个线程中捕获Mat,然后发出一个带有Qimage作为参数的信号,然后将图像设置为插槽中的QLabel

代码如下:

while(true){
    cam >> mat;
    cv::imshow("name",mat);
    emit send_UIupdate(mat2qimage(mat));
}
在插槽中将图像设置为Qlabel:

void Dialog::updateUI(const QImage &img){
    label->setPixmap(QPixmap::fromImage(img));
}
使用以下命令将Mat转换为QImage:

QImage camera::mat2qimage(const cv::Mat& mat) {
    cv::Mat rgb;
    cv::cvtColor(mat, rgb, CV_BGR2RGB);
    return QImage((const unsigned char*)(rgb.data), rgb.cols, rgb.rows, QImage::Format_RGB888);
}
要解决此问题,有什么建议吗???

您可以尝试以下方法:

QImage MainWindow::putImage(const 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();
    }
    else
    {
        qDebug() << "ERROR: Mat could not be converted to QImage.";
        return QImage();
    }
}
QImage主窗口::putImage(const Mat&Mat)
{
//8位无符号,通道数=1
如果(材料类型()==CV_8UC1)
{
//设置颜色表(用于将颜色索引转换为qRgb值)
矢量彩色表;

对于(int i=0;i我认为问题来自以下代码:

while(true){
    cam >> mat;
    cv::imshow("name",mat);
    emit send_UIupdate(mat2qimage(mat));
}
您的应用程序冻结是因为您正在循环,并且从不让Qt进行必要的处理。 参考链接:

你知道,Qt有它的mine事件循环,因此,如果你在函数中使用while(true)循环,Qt可能永远不会收到事件

尝试删除while循环,并使用Qtimer,正如@CTZStef所说的那样

以下源代码可能对您有所帮助:

在mat2qimage函数中,您应该返回一份副本


返回QImage((const unsigned char*)(rgb.data)、rgb.cols、rgb.rows、Image::Format_RGB888)。copy();

我不认为while循环会导致您所述的问题。他提到Mat是在一个单独的线程中捕获的。我很难看出这是如何回答原始问题的?您能解释一下吗?
VideoCapture cap("video.avi");
Mat frame;
QImage img;
QPixmap pixel;
while(cap.isOpened())
{
    cap >> frame;
    img= QImage((uchar*) frame.data, frame.cols, frame.rows, frame2.step, QImage::Format_RGB888);
    pixel = QPixmap::fromImage(img);
    ui->label->setPixmap(pixel);
}