Qt調用OpenCV實現錄製視頻檔案中的幾個問題

來源:互聯網
上載者:User

這幾天需要做一個視頻檔案錄製功能。用Qt調用OpenCV代碼搞定。

其中線程相關的過程省略不寫,與CvVideoWriter產生的部分網上有很多,也省略不寫。下面只記錄這個寫入單幀的函數:

第一版:

//ATTENTION: 調用來自另一線程bool ETVideoController::writeVideo(const ETVideoSource &source, QSize size, CvVideoWriter *pWriter){    QImage img(source.getOneFrame());    // pImageWrite與img共用記憶體    IplImage* pImageWrite = cvCreateImageHeader(        cvSize(size.width(), size.height()), 8, 3);    pImageWrite->imageData = reinterpret_cast<char*>(img.bits());    cvCvtColor(pImageWrite, pImageWrite, CV_RGB2BGR);    // 寫入一幀    cvWriteFrame(pWriter, pImageWrite);    cvReleaseImageHeader(&pImageWrite);    return true;}

這一版本的代碼沒有考慮到輸入的源映像非24位元影像的情況,也沒有考慮到輸入的源映像與視頻大小不一致的情況。所以錄製後的視頻出現了花屏的情況。為改善這一問題,我把代碼改成了如下形式:

第二版:

//ATTENTION: 調用來自另一線程bool ETVideoController::writeVideo(const ETVideoSource &source, QSize size, CvVideoWriter *pWriter){    // 將映像預先轉化成24位    QImage img(source.getOneFrame().convertToFormat(QImage::Format_RGB888));    img = img.scaled(size);    // pImageWrite與img共用記憶體    IplImage* pImageWrite = cvCreateImageHeader(        cvSize(size.width(), size.height()), 8, 3);    pImageWrite->imageData = reinterpret_cast<char*>(img.bits());    cvCvtColor(pImageWrite, pImageWrite, CV_RGB2BGR);    // 寫入一幀    cvWriteFrame(pWriter, pImageWrite);    cvReleaseImageHeader(&pImageWrite);    return true;}

其中cvWriteFrame函數在調用時發生記憶體錯誤。上網各種搜尋,沒有找到有用的答案,初步判斷因為img對象在其複製建構函式、賦值運算子調用的過程中,Qt執行的是淺複製,而對於Qt來說,它會自動判斷在需要深複製的時候再進行一次深複製以使它們看起來像完全不同的對象一樣。Qt這種機制使得OpenCV訪問了非法的記憶體位址,所以造成記憶體出錯。於是,我將代碼改成了最終的版本

第三版:

//ATTENTION: 調用來自另一線程bool ETVideoController::writeVideo(const ETVideoSource &source, QSize size, CvVideoWriter *pWriter){    QImage img = source.getOneFrame();    QImage imgDest(size, QImage::Format_RGB888); // 建立一個新圖片,使用指定的大小和24位格式        {        QPainter p(&imgDest); // 使用QPainter描畫圖片        p.drawImage(imgDest.rect(), img);    } // 析構    // pImageWrite與img共用記憶體    IplImage* pImageWrite = cvCreateImageHeader(        cvSize(size.width(), size.height()), 8, 3);    pImageWrite->imageData = reinterpret_cast<char*>(imgDest.bits());    cvCvtColor(pImageWrite, pImageWrite, CV_RGB2BGR);    // 寫入一幀    cvWriteFrame(pWriter, pImageWrite);    cvReleaseImageHeader(&pImageWrite);    return true;}

Painter p外面的大括弧是不可以省略的,因為我們利用在右大括弧}處自動調用p的解構函式的特性。經調試,上述代碼可以正常運行。


(■著作權聲明: 原創內容,轉載僅限非商業用途,並需註明出處: http://blog.csdn.net/LoveASPDotNet)



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.