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");
}
}
Я пробовал работать с этим кодом, меняя notify() на notifyAll() и поддерживая потоки List of CameraWorker и добавляя их. Но несмотря ни на что, приложение все еще зависает при вызове disconnectCamera()
.
Мои вопросы:
-
Как я могу изменить третий пример 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, но я всегда застреваю в одном месте.
Ответы
Ответ 1
Самый важный вопрос в вашей ситуации: работает ли он, если вы вообще не изменяете код - можете ли вы изменить разрешение (через меню) без сбоя приложения?
Если да, то ответ скорее всего прост - это та же ошибка в OpenCV, что и в версии Windows: перед изменением разрешения камеры или fps (и, скорее всего, с любым свойством) вам нужно взять хотя бы один (используйте 3-5, чтобы быть уверенным) перед изменением этого свойства.
Если нет, то, скорее всего, вы ничего не можете сделать самостоятельно - заполните отчет об ошибке и дождитесь комментариев. Единственная альтернатива - использовать другую библиотеку для захвата кадров с камеры и преобразовать ее в объект OpenCV.