2014-08-27 73 views
0

我有幾個視覺算法,它們在實時相機流上表現不錯,足夠使用;然而,當我在視頻文件上運行這些算法時,它並不是很好;流減慢太多,雖然它是罰款時,在視覺算法,這是通過調用VideoAlgoVision->execute(grabbedFrame, &CurrentROI);使用Qt和OpenCV讀取和處理視頻文件的高效方法

這裏執行不運行是怎麼看的視頻至今:

////////////////////////////////////////////////////////////////// 

void VisionUnit_widget::Play() 
{ 
    if(IsVideoPause) 
    { 
     ui->pausePushButton->setEnabled(true); 
     ui->playPushButton->setEnabled(false); 
     IsVideoPause = false; 
     TimerOpen->start((int) (1000/FPS_open)); 

     return; 
    } 
    else 
    { 
     ui->pausePushButton->setEnabled(true); 
     ui->stopPushButton ->setEnabled(true); 
     ui->rewPushButton ->setEnabled(true); 
     ui->ffdPushButton ->setEnabled(true); 
     ui->videoSlider ->setEnabled(true); 

     ui->playPushButton ->setEnabled(false); 

     if(!VideoCap) 
      VideoCap = new VideoCapture(FileName.toStdString()); 
     else 
      VideoCap->open(FileName.toStdString()); 

     if(VideoCap->isOpened()) 
     { 
      FrameH = (int) VideoCap->get(CV_CAP_PROP_FRAME_HEIGHT); 
      FrameW = (int) VideoCap->get(CV_CAP_PROP_FRAME_WIDTH); 
      FPS_open = (int) VideoCap->get(CV_CAP_PROP_FPS); 
      NumFrames = (int) VideoCap->get(CV_CAP_PROP_FRAME_COUNT); 

      ui->videoSlider->setMaximum((int)NumFrames); 

      ui->videoSlider->setEnabled(true); 
      READCOUNT = 0; 
      TimerOpen->start((int) (1000/FPS_open)); 
     } 
    }  
} 


////////////////////////////////////////////////////////////////// 

void VisionUnit_widget::Pause() 
{ 
    ui->playPushButton->setEnabled(true); 
    ui->pausePushButton->setEnabled(false); 
    TimerOpen->stop(); 
    IsVideoPause = true; 
} 


////////////////////////////////////////////////////////////////// 

void VisionUnit_widget::Stop() 
{ 
    ui->stopPushButton->setEnabled(false); 
    ui->playPushButton->setEnabled(false); 
    ui->pausePushButton->setEnabled(false); 
    ui->rewPushButton->setEnabled(false); 
    ui->ffdPushButton->setEnabled(false); 

    FileName = ""; 

    TimerOpen->stop(); 

    READCOUNT = 0; 

    ui->videoSlider->setSliderPosition(0); 
    ui->videoSlider->setEnabled(false); 

    ui->frameLabel->setText("No camera connected"); 

    delete TimerOpen; 
    TimerOpen = 0; 

    if(VideoCap) 
    { 
     delete VideoCap; 
     VideoCap = 0; 
    } 

    if(VideoAlgoVision) 
    { 
     delete VideoAlgoVision; 
     VideoAlgoVision = 0; 
    } 
} 


////////////////////////////////////////////////////////////////// 

void VisionUnit_widget::Read() 
{ 
    READCOUNT++; 

    // Update Video Player's slider 
    ui->videoSlider->setValue(READCOUNT); 

    if(READCOUNT >= NumFrames) // if avi ends 
    { 
     Pause(); 
     return; 
    } 

    Mat grabbedFrame; 


    // Get next frame 
    if(VideoCap->isOpened() && VideoCap->read(grabbedFrame)) 
    { 
     // Execute the vision filter 
     if(VideoAlgoVision) 
      VideoAlgoVision->execute(grabbedFrame, &CurrentROI); 

     // Convert Mat to QImage 
     QImage frame = MatToQImage(grabbedFrame); 

     // Update the display 
     UpdateFrame(frame); 
    } 
} 


////////////////////////////////////////////////////////////////// 

QImage VisionUnit_widget::MatToQImage(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 
    else 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 
    { 
     return QImage(); 
    } 
} 

所以,我的問題是不是有更好的方式來閱讀包含視頻處理在內的Qt和OpenCV視頻文件?我應該在運行時適應QTimer時機嗎?我從TimerOpen->start((int) (1000/FPS_open));開始它,但顯然視覺算法會減慢整個事情。任何想法?

在視覺算法上可能會有一些優化,但我的觀點是他們在我的網絡攝像頭和IP攝像頭上表現不錯,讓我覺得我的閱讀/使用視頻文件的方式有問題。

THX

回答

0

您沒有提供完整的代碼,但是我想你已經連接TimerOpentimeout()信號VisionUnit_widget::Read()插槽。如果是這種情況,您正在積累1000/FPS_open和處理時間。

更改您的德興至像下面這樣將解決這個問題:

int fSpace = 1000/FPS; 
QTime timer; 
timer.start(); 

forever { 
    if(timer.elapsed() < fSpace) 
     msleep(1); 

    timer.restart(); 

    ..Process the frame.. 
} 

,也許最好是這個移動從主線程另一個線程。

+0

它沒有什麼意義......在你的無限循環中,幀處理之前的代碼等價於我在TimerOpen和Read之間建立的直接連接... connect(TimerOpen,SIGNAL(timeout()),this ,SLOT(讀())); 「你正在積累1000/FPS_open和處理時間」是什麼意思?無論如何,我懷疑你的代碼會改變我的問題,這似乎是笨拙的。對於您可能正確的線程,計劃在下一次迭代中使用。謝謝。 – CTZStef 2014-08-28 14:53:56