2017-10-09 97 views
0

我有一個非常簡單的應用程序寫在QT中,我想通過使用QMediaPlayer來顯示電影,但在顯示任何幀之前我想檢測它的一些對象並標記它們通過在其上畫一個矩形。修改和顯示在QAbstractVideoSoSface中獲取的QVideoFrame

我讀過http://doc.qt.io/qt-5/videooverview.html,我可以訪問每個框架的子類QAbstractVideoSurface,所以我決定。

class VideoSurface : public QAbstractVideoSurface { 
    Q_OBJECT 

    bool present(const QVideoFrame &frame) override { 
     if (surfaceFormat().pixelFormat() != frame.pixelFormat() 
       || surfaceFormat().frameSize() != frame.size()) { 
      setError(IncorrectFormatError); 
      stop(); 

      return false; 
     } else { 
      currentFrame = frame; 

      return true; 
     } 
    } 

    ... 
} 

現在,我在該成員函數正在接收幀,我想通過借鑑它在哪裏檢測到的物體的地方矩形修改,然後,我想在屏幕上顯示它們(優選在某些插件) 。

我該怎麼做?

  1. 如果我VideoSurface類包含QWidget成爲會員?或者我應該子類QWidget其中將包含VideoSurface

  2. 在這兩種情況下,我怎樣才能顯示這個框架?我應該先將它轉換爲QImage然後再顯示(這對我來說很方便,因爲我的檢測系統與QImage一起工作,但效率會如何)?我知道我不能在繪畫事件之外繪畫,所以我不能在present函數中繪畫,那麼究竟應該在哪裏繪製這個繪畫函數,以及我可以如何調用它?

  3. 我應該在哪裏檢測這些對象並修改框架?在present函數中,還是在繪圖函數中?

回答

0
  1. 這是給你的,取決於你喜歡如何構建類。我寧願有一個單獨的小部件,其中包含指向VideoSurface的指針,並繪製由VideoSurface的某個成員函數返回的數據(取決於您在2中的解決方案)。

  2. a)QImage對於某些目的,如果你已經在你的檢測代碼中使用它,那麼你已經擁有了內存中的所有東西,並且可以處理它。與所有與性能有關的擔憂一樣:測試並確定性能是否足夠適合您。如果不是,您可能還必須考慮以不同的方式進行檢測。我曾參與過一個項目,我們在移動設備的相機流上處理從類似VideoSurface轉換而來的QImage(對於分辨率相對較低的圖像),並且性能足夠好,以至於我們還沒有打算使用其他技術。該項目中的VideoSurface類的源代碼(Neuronify)is hosted here。 b)您的present()函數可能會發出一個信號,您可以從其他對象連接到的信號,從VideoSurface獲取最新數據並保存它,直到它們的繪製函數被調用。或者,您可以將數據直接應用於某些接受圖像數據的小部件。有關這方面的示例,請參見Use of QAbstractVideoSurface。但是,如果您需要在某個時候提高性能,您可能希望在不同的線程上執行該操作,以防止在處理數據時鎖定GUI。如果你這樣做,你需要決定是否必須處理每一幀,或者如果某些幀可以跳過處理來改善播放的FPS。在後一種情況下,你可能不應該在present()函數中這樣做,因爲這可能會使媒體播放器無法在處理舊幀時爲您提供更多幀。