2015-05-07 76 views
14

我使用Android4OpenCV來進行一些實時圖像處理,並且我想使用相機可以提供的最小分辨率。默認分辨率是相機可以提供的最大分辨率。Android4OpenCV:啓動時的設置分辨率

我正在查看3rd example,它允許用戶通過菜單更改分辨率。我想修改該示例以在啓動時更改分辨率,而不是要求用戶瀏覽菜單。要做到這一點,我只需添加兩行到其他空onCameraViewStarted()功能:

public void onCameraViewStarted(int width, int height) { 
    android.hardware.Camera.Size res = mOpenCvCameraView.getResolutionList().get(mOpenCvCameraView.getResolutionList().size()-1); 
    mOpenCvCameraView.setResolution(res); 
} 

而事實是,這工作完全正常在我的Galaxy Nexus,運行Android 4.2.2。該應用程序啓動,分辨率設置正確。

但是,當我在運行Android 5.1的Nexus 7平板電腦上運行完全相同的應用時,該應用掛在setResolution()的呼叫上。實際上,它一次可以正常工作,但是第二次嘗試運行時會掛起 - 即使您完全退出應用程序,將其從正在運行的應用程序中刪除,或者重新啓動設備。其他用戶也報告了同樣的錯誤,所以它不只是Nexus 7設備 - 事實上,我的Galaxy Nexus似乎是唯一可以運行的設備。

具體而言,應用程序進入setResolution()功能,然後調用org.opencv.android.JavaCameraView.disconnectCamera(),它看起來像這樣:

(注:此代碼是內部的OpenCV4Android圖書館,這不是我的代碼)

protected void disconnectCamera() { 
    /* 1. We need to stop thread which updating the frames 
    * 2. Stop camera and release it 
    */ 
    Log.d(TAG, "Disconnecting from camera"); 
    try { 
     mStopThread = true; 
     Log.d(TAG, "Notify thread"); 
     synchronized (this) { 
      this.notify(); 
     } 
     Log.d(TAG, "Wating for thread"); 
     if (mThread != null) 
      mThread.join(); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } finally { 
     mThread = null; 
    } 

    /* Now release camera */ 
    releaseCamera(); 
} 

看着日誌,我可以看到線程卡在synchronized(this)行。該對對象進行同步的唯一的另一件事是內JavaCameraView.CameraWorker類,這是在上面的代碼中mThread變量,由JavaCameraView類開始:

(注意:這個代碼是內部的OpenCV4Android庫,這是不是我的代碼)

private class CameraWorker implements Runnable { 

    public void run() { 
     do { 
      synchronized (JavaCameraView.this) { 
       try { 
        JavaCameraView.this.wait(); 
       } catch (InterruptedException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 

      if (!mStopThread) { 
       if (!mFrameChain[mChainIdx].empty()) 
        deliverAndDrawFrame(mCameraFrame[mChainIdx]); 
       mChainIdx = 1 - mChainIdx; 
      } 
     } while (!mStopThread); 
     Log.d(TAG, "Finish processing thread"); 
    } 
} 

我試着與該代碼把玩,更改通知()來notifyAll的(),並維持CameraWorker線程的列表,並加入每一個。但無論如何,該應用程序仍然掛在disconnectCamera()電話。

我的問題是:

  • 我怎麼能修改第三OpenCV4Android例如,使得其分辨率設置爲啓動?

  • 什麼導致應用程序掛起?

  • 爲什麼它可以在一些設備上工作,但不是其他設備?

編輯:我還沒有收到任何意見或答案,所以我crossposted到OpenCV的論壇here

編輯2:按照cyriel的建議下,我試着將分辨率設置後幾幀已經過去了:

int frames = 0; 
public Mat onCameraFrame(CvCameraViewFrame inputFrame) { 

    frames++; 

    if(frames == 6){ 
     android.hardware.Camera.Size res = mOpenCvCameraView.getResolutionList().get(mOpenCvCameraView.getResolutionList().size()-1); 
     mOpenCvCameraView.setResolution(res); 

    } 

    return inputFrame.rgba(); 
} 

然而,現在這卡在完全相同的地方,甚至在我的Galaxy Nexus,如果我在onCameraViewStarted()函數中設置分辨率,它就可以工作。我試圖增加幀數到7甚至100,但我總是卡在同一個地方。

回答

5

在您的情況,最重要的問題是它的工作,如果你完全不修改代碼 - 你可以更改分辨率(通過菜單)沒有崩潰的應用程序?
如果是比答案最有可能很簡單 - 它是在OpenCV中同樣的錯誤在Windows版本:你需要抓住不斷變化的攝像頭分辨率或FPS(最有可能的任何財產)前至少一個(使用3-5是確定)框架之前更改此屬性。
如果不是最有可能的,你可以自己做任何事情 - 填寫錯誤報告並等待評論。唯一的選擇是使用其他庫從相機抓取幀並將其轉換爲OpenCV對象。

+0

如果我根本不修改代碼,它確實有效。我也嘗試改變第一幀的分辨率,並導致相同的行爲。 –

+0

所以最有可能的是它與Windows版本中的錯誤相同。嘗試在5幀後更改分辨率 - 用戶很可能不會注意到這一點。我知道這不是一個完美的解決方案,但最有可能它是最好的解決方法。 – cyriel

+0

我編輯了我的問題,以顯示當我嘗試這種情況時會發生什麼,但這似乎也無法解決問題。 –