2014-01-14 59 views
6

我想實現在Android提高OpenCV的性能的Android - 快速目標跟蹤

我的邏輯快速對象跟蹤應用程序是如下

  1. 刪除所有顏色,除了所需的顏色範圍。
  2. 平滑的圖像使用高斯模糊
  3. 查找與HoughCircles

的應用程序之類的工作正常,但表現糟糕,我想至少快5倍,以加快自己的表現最大半徑的圓。我借用了這個鏈接的大部分邏輯。

Fast Object Tracking example

public void apply(Mat src, Mat dst) { 
    Mat mIntermediateMat = new Mat(src.rows(), src.cols(), CvType.CV_8UC1); 

    Mat mHsv = new Mat(src.size(), CvType.CV_8UC3); 
    Mat mHsv2 = new Mat(src.size(), CvType.CV_8UC3); 

    Imgproc.cvtColor(src, mHsv, Imgproc.COLOR_RGB2HSV, 3); 

    Core.inRange(mHsv, new Scalar(0, 86, 72), new Scalar(39, 255, 255), mHsv); // red 
    Core.inRange(mHsv, new Scalar(150, 125, 100), new Scalar(180,255,255), mHsv2); // red 
    Core.bitwise_or(mHsv, mHsv2, mHsv); 

    /// Reduce the noise so we avoid false circle detection 
    Imgproc.GaussianBlur(mHsv, mHsv, new Size(7, 7), 2); 
    Imgproc.HoughCircles(mHsv, mIntermediateMat, Imgproc.CV_HOUGH_GRADIENT,2.0,100); 

    int maxRadious = 0; 
    Point pt = new Point(0,0); 
    if (mIntermediateMat.cols() > 0) { 
     for (int x = 0; x < mIntermediateMat.cols(); x++) 
     { 
      double vCircle[] = mIntermediateMat.get(0,x); 

      if (vCircle == null) 
       break; 

      int radius = (int)Math.round(vCircle[2]); 
      if (radius > maxRadious) { 
       maxRadious = radius; 
       pt = new Point(Math.round(vCircle[0]), Math.round(vCircle[1])); 
      } 

     } 
     int iLineThickness = 5; 
     Scalar red = new Scalar(255, 0, 0); 
     // draw the found circle 
     Core.circle(dst, pt, maxRadious, red, iLineThickness); 
    } 

} 

我一直在想辦法提高自己的表現,我想上可能是可行的和顯著建議。

1)使用多線程。我可以使用一個線程從相機捕捉,一個線程處理圖像。從OpenCV Android Release notes我看到「使用TBB啓用多線程支持(只有少數功能在此刻進行了優化)」。但我不明白這一點。 TBB僅適用於英特爾芯片嗎?哪些功能可用? Android和OpenCV有相關的例子嗎?

2)使用更強大的Android設備。我目前使用前置攝像頭在2012年Nexus 7上運行。對於哪些規格對我來說很重要,我並不十分清楚。 Nexus 7(2012)採用1.3GHz四核Nvidia Tegra 3 CPU; 416MHz的Nvidia GeForce ULP GPU。

如果我要運行在當前最快的Android手機上,它會產生多大的差異?

哪些功能最相關的這種類型的應用程序

  1. CPU。
  2. GPU。
  3. 核心數量。
  4. 相機的幀速率。

3)使用Native C++代碼會對我的性能產生積極影響嗎?

4)我可以使用OpenCV嗎?

回答

6

0)我會描述(或測量運行時間)所有你用來檢查你需要優化的函數,然後計劃進一步的優化。 1)多線程可以提高幀速率,但不會延遲(一個核心進程一個幀x毫秒,你有N個核心,所以你有N幀非常快,那麼你必須再次等待x毫秒)。我不確定OpenCV,但據我所知,高斯模糊和Hough變換不使用多核。

2)英特爾TBB不僅用於英特爾芯片,人們還將其用於ARM和AMD芯片。請參閱 OpenCV configure with TBB for ARM (Ubuntu, 3.0.63)

3-4)您使用的算法非常簡單,一切都可以由您自己實現,無需OpenCV。而OpenCV Hough變換或高斯模糊速度相當快。 C++比Python快,但是在「整個程序運行時」方面。 Python OpenCV僅僅是C++庫之上的包裝器,所以它們的「單獨」性能是相似的。

+3

之外,我認爲CPU速度和芯片組是目前基於OpenCV的的方案中最重要的東西(沒有太大的多核GPU計算爲OpenCV的-機器人還)。並嘗試減少預覽分辨率,如果你沒有辦法。 – flankechen

+0

感謝您的回答,我嘗試了多線程,但看不到任何重大改進。也許我的實現有問題。我會問一個新問題。我將不得不嘗試爲TBB找到更多資源,並按照您的建議嘗試配置文件。我認爲你的答案和flankechen的投入一起解答了我的大部分問題。順便說一下,這是Java和不是Python –

3

首先,就像之前所說的那樣,剖析你的代碼。 Android SDK分析器非常棒,可能是我嘗試過的最好的。

這裏有幾件事情,會很容易讓你看到一些改進:

  • 不要聲明(實例)的數據結構(墊,標量,點)的處理代碼中(代碼是要求捕獲的每張圖片)。嘗試重用它們。

  • 您不需要使用圖像的全尺寸進行對象跟蹤,您可以調整每個圖像幀的大小(縮小比例),或使用圖像ROI:處理圖像的較小區域。

  • 您的Nexus 7支持OpenCV NEON優化,這些是NVIDIA Tegra硬件支持的優化,請仔細研究。基本上,您需要使用支持NEON的OpenCV進行編譯,如果您查找它,您會發現文檔。

編輯:

因爲你提到高斯​​模糊是一個問題,你可以嘗試other types of blur (median, normalized box)其運行速度更快,也可能會增加滑動窗口(又名內核)大小(第三個參數)時,內核越大,圖像越快。

http://docs.opencv.org/doc/tutorials/imgproc/gausian_median_blur_bilateral_filter/gausian_median_blur_bilateral_filter.html

+0

謝謝,我已經認識到,你的第一點是至關重要的,如果我在循環中實例化它們可能會導致緩衝區錯誤。我會嘗試實施你的其他兩個建議。我正在嘗試在NDK中用C++做更多的事情,看看它是否可以提高我的幀速率。 –

+0

瓶頸似乎是GaussianBlur。我嘗試使用定製的fastblur解決方案,但似乎沒有區別,可能是因爲我先轉換爲位圖並從位圖轉換而來。我將繼續嘗試尋找更快的模糊解決方案 –