Android4OpenCVを使用してライブ画像処理を行っていますが、カメラが提供できる最小の解像度を使用したいと考えています。デフォルトの解像度は、カメラが提供できる最大の解像度です。
ユーザーがメニューから解像度を変更できるようにする3 番目の例を見ています。その例を変更して、ユーザーがメニューを通過するのではなく、起動時に解像度を変更したいと思います。これを行うには、空のonCameraViewStarted()
関数に次の 2 行を追加するだけです。
public void onCameraViewStarted(int width, int height) {
android.hardware.Camera.Size res = mOpenCvCameraView.getResolutionList().get(mOpenCvCameraView.getResolutionList().size()-1);
mOpenCvCameraView.setResolution(res);
}
そして問題は、これは Android 4.2.2 を実行している私の Galaxy Nexus で完全に正常に動作することです。アプリが起動し、解像度が正しく設定されます。
ただし、Android 5.1 を実行している Nexus 7 タブレットでまったく同じアプリを実行すると、アプリは への呼び出しでハングしますsetResolution()
。実際には一度は問題なく動作しますが、2 回目に実行しようとするとハングします。アプリを完全に終了したり、実行中のアプリから削除したり、デバイスを再起動したりしても。他のユーザーも同じエラーを報告しているため、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 クラスによって開始される、上記のコードJavaCameraView.CameraWorker
の変数である内部クラスです。mThread
(注: このコードは 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");
}
}
私はそのコードをいじり、notify() を notifyAll() に変更し、CameraWorker スレッドのリストを維持し、それぞれに参加しようとしました。しかし、何があっても、アプリはdisconnectCamera()
通話中にハングします。
私の質問は次のとおりです。
起動時に解像度が設定されるように、3 番目の OpenCV4Android の例を変更するにはどうすればよいですか?
アプリがハングする原因は何ですか?
一部のデバイスでは機能するのに、他のデバイスでは機能しないのはなぜですか?
編集: コメントや回答を受け取っていないため、ここの OpenCV フォーラムにクロスポストしました。
編集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 に増やしてみましたが、いつも同じ場所でスタックしてしまいます。