Как настроить камеру OpenCV для предварительного просмотра в книжной и полноэкранной ориентации
Я пытаюсь создать приложение для Android. который отображает предварительный просмотр камеры в портретном режиме все время и выполняет некоторые тяжелые операции по обработке изображений (некоторые из) его кадров. Следовательно, я использую OpenCV (как его OpenCV4Android, так и нативные компоненты C/C++). Проблема заключается в том, что при использовании классов CameraBridgeViewBase или JavaCameraView кадр, возвращаемый OnCameraFrame, находится в ландшафтном режиме.
Теперь, если для Activity определено использование ландшафтного режима (как и для примеров приложений OpenCV), предварительный просмотр выглядит нормально, но любые дополнительные виды пользовательского интерфейса наклонены на 90 градусов (и, как упоминалось ранее, устройство должно запускать мое приложение в портретном режиме).
Если для Activity задан портретный режим, пользовательский интерфейс, очевидно, будет выглядеть правильно, но предварительный просмотр камеры будет наклонен на 90 градусов.
Если я попытаюсь повернуть каждый кадр, манипулируя изображением Matrix на OnCameraFrame следующим образом:
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
mRgba = inputFrame.rgba();
Core.transpose(mRgba,mRgbaT);
Core.flip(mRgbaT, mRgbaT, -1);
Imgproc.resize(mRgbaT, mRgbaT, mRgba.size());
return mRgbaT;
}
затем кадр каждой камеры заполняет ширину устройства, а не его высоту (и, как результат, он выглядит растянутым), плюс - это значительно замедляет частоту кадров. Попытка изменить размер изображения до полноэкранного (или любого размера, отличного от исходного размера кадра) приводит к тому, что изображение вообще не отображается (черный экран), и выдается следующее исключение:
E/CameraBridge(11183): Utils.matToBitmap() throws an exception: /home/reports/ci/slave_desktop/50-SDK/opencv/modules/java/generator/src/cpp/utils.cpp:97: error: (-215) src.dims == 2 && info.height == (uint32_t)src.rows && info.width == (uint32_t)src.cols in function void Java_org_opencv_android_Utils_nMatToBitmap2(JNIEnv*, jclass, jlong, jobject, jboolean)
Итак, мой вопрос: как я могу отобразить предварительный просмотр камеры OpenCV как в портретном режиме, так и в полноэкранном режиме?
К сожалению, из-за моей репутации новичка ТАК я не могу прикрепить снимки экрана. Кроме того, я знаю о том, что несколько схожих вопросов задавали ранее в SO, но ни один из ответов, похоже, не решает проблему полностью.
1 ответ
Я нашел решение: создать собственный класс камеры, который расширяется от CameraBridgeViewBase аналогично тому, как JavaCameraView расширяет его (большинство частей даже идентичны), но при реализации внутреннего класса JavaCameraFrame замените метод, который возвращает объект Mat в что-то вроде этого:
public Mat rgba() {
Imgproc.cvtColor(mYuvFrameData, mRgba, Imgproc.COLOR_YUV2BGR_NV12, 4);
if (mRotated != null)
mRotated.release();
mRotated = mRgba.t();
Core.flip(mRotated, mRotated, -1);
return mRotated;
}
Здесь есть отличный пример (первый ответ, любезно предоставленный KTLind). Есть некоторое снижение производительности, но это удаленно не так серьезно, как при вращении выходного Mat в OnCameraFrame (что в любом случае не решает проблему полностью). Я использую его с размером кадра предварительного просмотра с разрешением 640*480 (на весь экран), и он выглядит хорошо и работает плавно, даже не на новых устройствах.