OpenCV4 调用摄像头黑屏问题
OpenCV 调用 Android 摄像头这一块,我之前研究了好几天,都是一片黑,毫无头绪。后来发现 OpenCV4 要想调用摄像头,必须继承自 OpenCV 的 CameraActivity !!!
CameraActivity.java 的源码如下,可以看出大部分代码都是为了 Android M(6.0)以上请求权限而生的,只有两个地方非常关键
-
protected List<? extends CameraBridgeViewBase> getCameraViewList() { …… }
子 Activity 在继承 CameraActivity 后,需要复写该函数,把 JavaCamera2View 或 JavaCameraView 送入 List 作为返回值。 -
cameraBridgeViewBase.setCameraPermissionGranted()
相机视图初始情况下是黑屏的,即不工作状态。只有当权限授予完毕,调用了 setCameraPermissionGranted 之后,OpenCV 才开始调用相机并把数据输出到 SurfaceView 上。
public class CameraActivity extends Activity {
private static final int CAMERA_PERMISSION_REQUEST_CODE = 200;
protected List<? extends CameraBridgeViewBase> getCameraViewList() {
return new ArrayList<CameraBridgeViewBase>();
}
protected void onCameraPermissionGranted() {
List<? extends CameraBridgeViewBase> cameraViews = getCameraViewList();
if (cameraViews == null) {
return;
}
for (CameraBridgeViewBase cameraBridgeViewBase: cameraViews) {
if (cameraBridgeViewBase != null) {
cameraBridgeViewBase.setCameraPermissionGranted();
}
}
}
@Override
protected void onStart() {
super.onStart();
boolean havePermission = true;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(CAMERA) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{CAMERA}, CAMERA_PERMISSION_REQUEST_CODE);
havePermission = false;
}
}
if (havePermission) {
onCameraPermissionGranted();
}
}
@Override
@TargetApi(Build.VERSION_CODES.M)
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == CAMERA_PERMISSION_REQUEST_CODE && grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
onCameraPermissionGranted();
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
实现要领
- 首先,要继承 CameraActivity,之前已经说过了。这个基类会去申请权限,然后通知 javaCameraView 已获取到权限,可以正常使用。
- 复写父类的 getCameraViewList 方法,将 javaCameraView 回送回去,这样当权限已被赋予时,就可以通知到预览界面开始正常工作了。
- OpenCV 已经为我们实现了 Camera 和 Camera2 的函数,如果应用最低版本 minSdkVersion > 5.0,建议使用 JavaCamera2View 的相关函数,否则使用 JavaCameraView。
- 在 onResume 时判断 opencv 库是否加载完毕,然后启用预览视图。在 onPause 时由于界面被遮挡,此时应该暂停摄像头的预览以节省手机性能和电量损耗。
- 切换前后摄像头时,要先禁用,设置完后启用才会生效。
- Camera2 和 Camera 的绝大部分差异 OpenCV 均已经为我们屏蔽在类的内部了,唯一的差别就是两者实现的 CvCameraViewListener 监听器里的预览函数 onCameraFrame 的参数略有不同。从下面的源码可以看出 CvCameraViewListener2 的 inputFrame 由 Mat 类型改为了 CvCameraViewFrame 类型,它额外提供了一个转化为灰度图的接口。
CvCa

本文详细介绍了如何在Android设备上使用OpenCV4正确调用摄像头,包括解决黑屏问题的关键步骤,如继承CameraActivity,复写getCameraViewList方法,以及在权限授予后调用setCameraPermissionGranted。同时,提供了使用JavaCamera2View实现拍照功能的示例代码,并讲解了如何修改源码实现全屏预览。

1万+

被折叠的 条评论
为什么被折叠?



