Android4OpenCV: настройка разрешения при запуске

Я использую Android4OpenCV для обработки изображения в реальном времени, и я хотел бы использовать наименьшее разрешение, которое может предложить камера. Разрешение по умолчанию является самым большим, что может предложить камера.

Я смотрю третий пример , который позволяет пользователю изменять разрешения через меню. Я хотел бы изменить этот пример, чтобы изменить разрешение при запуске, а не требовать, чтобы пользователь прошел через меню. Для этого я просто добавляю две строки к пустой функции 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. Приложение запустится, и разрешение установлено правильно.

Однако, когда я запускаю то же самое приложение на планшете Nexus 7, работая под управлением Android 5.1, приложение зависает при вызове 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"); } } 

Я попробовал futzing с этим кодом, изменив notify () на notifyAll () и поддерживая поток List of CameraWorker и присоединяя его. Но несмотря ни на что, приложение все еще зависает при вызове disconnectCamera() .

Мои вопросы:

  • Как изменить третий пример OpenCV4Android, чтобы его разрешение было задано при запуске?

  • Что заставляет приложение зависать?

  • Почему это работает на некоторых устройствах, но не на других?

Изменить: я не получил никаких комментариев или ответов, поэтому я перекрестился на форумах OpenCV здесь .

Редактирование 2 : Согласно предложению Кириэля, я попытался установить разрешение после нескольких кадров:

 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, но я всегда застрял в одном месте.

Solutions Collecting From Web of "Android4OpenCV: настройка разрешения при запуске"

Самый важный вопрос в вашей ситуации – работает ли он, если вы вообще не модифицируете код – можете ли вы изменить разрешение (через меню) без сбоя приложения?
Если да, то ответ скорее всего прост – это та же ошибка в OpenCV, что и в версии Windows: перед изменением разрешения камеры или fps (и, скорее всего, с любым свойством) вам нужно взять хотя бы один (используйте 3-5, чтобы быть уверенным) Перед изменением этого свойства.
Если нет, скорее всего, вы ничего не можете сделать самостоятельно – заполните отчет об ошибке и дождитесь комментариев. Единственная альтернатива – использовать другую библиотеку для захвата кадров с камеры и преобразовать ее в объект OpenCV.