2016-05-14 48 views
0

我有一個網絡攝像頭演示與Qt和OpenCV。基本上,它會顯示攝像頭的提要,並且當一個按鈕被點擊時,它會啓動一個長(三秒鐘)線程的線程。QImage破壞與OpenCV

問題是,當我點擊按鈕時,QImage立即得到損壞as you can see here,我再也看不到視頻輸入了。信號&插槽工作(我看到控制檯中的輸出),但我不能在這裏發現問題。

任何人都可以幫忙嗎?

window::window() : QMainWindow(NULL, 0) 
{ 
    std::cout << "constructor start" << std::endl; 

    setWindowTitle("Video"); 

    button = new QPushButton("Long Job"); 
    connect(button, SIGNAL(clicked()), this, SLOT(longjob())); 

    image = new QLabel(); 
    image->setAlignment(Qt::AlignCenter); 

    layout = new QVBoxLayout(); 
    layout->addWidget(image); 
    layout->addWidget(button); 

    mainwidget = new QWidget(); 
    mainwidget->setLayout(layout); 

    resize(800, 600); 

    setCentralWidget(mainwidget); 

    cap = cv::VideoCapture(0); 

    timer = new QTimer(); 
    timer->setInterval(100); 
    timer->start(); 
    connect(timer, SIGNAL(timeout()), this, SLOT(newframe())); 

    std::cout << "constructor end" << std::endl; 
} 

void window::newframe() 
{ 
    std::cout << "FRAME " << count++ << std::endl; 

    cv::Mat frame; 
    cap >> frame; 

    image->setPixmap(QPixmap::fromImage(showImage(frame))); // converts perfectly 
} 

void window::longjob() 
{ 

    std::cout << "START THREAD" << std::endl; 

    w = new worker(); 

    connect(w, SIGNAL(resultReady(double)), this, SLOT(detected(double))); 

    w->start(); 

    return; 
} 

void window::detected(double d) 
{ 
    disconnect(w, SIGNAL(resultReady(double)), this, SLOT(detected(double))); 

    std::cout << "DETECTED " << d << std::endl; 

    delete w; 

    frames.clear(); 
} 

class worker : public QThread 
{ 
    Q_OBJECT 

public: 

    worker(); 

    ~worker(); 

    void run() Q_DECL_OVERRIDE; 

signals: 
    void resultReady(double d); 
}; 

worker::worker() : QThread() 
{ 

} 

worker::~worker() 
{ 
    std::cout << "THREAD EXIT" << std::endl; 
} 

void worker::run() 
{ 
    std::cout << "THREAD RUN" << std::endl; 

    double d = longOpenCVJob(); 

    emit resultReady(d); 
} 
+0

'showImage()'實現在哪裏? – karlphillip

+0

這裏是一個[顯示如何創建一個Qt窗口來顯示用OpenCV加載的視頻]的應用程序(https://github.com/karlphillip/GraphicsProgramming/tree/master/cvVideo)。需要進行微調以使其從相機流式傳輸視頻。 – karlphillip

+1

http://stackoverflow.com/questions/17127762/cvmat-to-qimage-and-back – Evgeniy

回答

0

我會用showImage()這樣的代碼:

QImage window::showImage(cv::Mat mat) 
{ 
    cv::Mat tmp; 
    mat.convertTo(tmp, CV_8U); 
    cvtColor(tmp, tmp, CV_BGR2RGB); 
    QImage img = QImage((const unsigned char *)(tmp.data), tmp.cols, tmp.rows, tmp.step, QImage::Format_RGB888); 
    return img; 
} 
+1

QImage不會對tmp.data進行深層複製。所以它會在tmp破壞,即函數返回後失效。看看這裏:http://doc.qt.io/qt-5/qimage.html#QImage-3:「...緩衝區必須在QImage和所有副本的整個生命週期內保持有效......」 – Evgeniy