如何设置OpenCV的相机以纵向和全屏显示预览
How to set OpenCV's camera to display preview in both portrait orientation and full screen
我正在尝试创建一个 Android 应用程序。它始终以纵向模式显示相机预览,并对(某些)帧执行一些繁重的图像处理操作。因此,我正在使用 OpenCV(两者都是 OpenCV4Android 和本机 C/C++ 组件)。问题是,当使用 CameraBridgeViewBase 或 JavaCameraView 类 时,OnCameraFrame 返回的帧处于横向模式。
现在,如果 Activity 被定义为使用横向模式(就像 OpenCV 的示例应用程序一样),预览看起来不错,但是任何额外的 UI 视图都会倾斜 90 度(并且如前所述之前,设备应该 运行 我的 App 处于纵向模式)。
如果 Activity 设置为纵向模式,UI 视图显然看起来是正确的,但相机预览会倾斜 90 度。
如果我尝试通过像这样操作 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 声誉,我无法附上屏幕截图。另外,我知道之前有人在 SO 上问过一些类似的问题,但是 none 的答案似乎完全解决了这个问题。
我找到了解决办法:
创建一个从 CameraBridgeViewBase 扩展的自定义相机 class,其扩展方式与 JavaCameraView 从它扩展的方式类似(大多数部分甚至相同),但是在实现内部 JavaCameraFrame class 时,替换 returns 一个 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;
}
有一个很好的例子here (The first answer, courtesy of Zarokka)。性能有所下降,但远不如在 OnCameraFrame 中旋转输出垫时严重(无论如何都不能完全解决问题)。我在 640*480 分辨率预览帧大小(全屏)上使用它,它看起来不错,即使不是那么新的设备也能流畅运行。
我正在尝试创建一个 Android 应用程序。它始终以纵向模式显示相机预览,并对(某些)帧执行一些繁重的图像处理操作。因此,我正在使用 OpenCV(两者都是 OpenCV4Android 和本机 C/C++ 组件)。问题是,当使用 CameraBridgeViewBase 或 JavaCameraView 类 时,OnCameraFrame 返回的帧处于横向模式。
现在,如果 Activity 被定义为使用横向模式(就像 OpenCV 的示例应用程序一样),预览看起来不错,但是任何额外的 UI 视图都会倾斜 90 度(并且如前所述之前,设备应该 运行 我的 App 处于纵向模式)。
如果 Activity 设置为纵向模式,UI 视图显然看起来是正确的,但相机预览会倾斜 90 度。
如果我尝试通过像这样操作 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 声誉,我无法附上屏幕截图。另外,我知道之前有人在 SO 上问过一些类似的问题,但是 none 的答案似乎完全解决了这个问题。
我找到了解决办法: 创建一个从 CameraBridgeViewBase 扩展的自定义相机 class,其扩展方式与 JavaCameraView 从它扩展的方式类似(大多数部分甚至相同),但是在实现内部 JavaCameraFrame class 时,替换 returns 一个 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;
}
有一个很好的例子here (The first answer, courtesy of Zarokka)。性能有所下降,但远不如在 OnCameraFrame 中旋转输出垫时严重(无论如何都不能完全解决问题)。我在 640*480 分辨率预览帧大小(全屏)上使用它,它看起来不错,即使不是那么新的设备也能流畅运行。