OpenCV 调用 Android 摄像头这一块,我之前研究了好几天,都是一片黑,毫无头绪。后来发现 OpenCV4 要想调用摄像头,必须继承自 OpenCV 的 CameraActivity !!! CameraActivity.java 的源码如下,可以看出大部分代码都是为了 Android M(6.0)以上请求权限而生的,只有两个地方非常关键 CvCameraViewListener CvCameraViewListener2 下面使用 Camera2 来实现拍照功能( 注意:Camera2 只能用于 Android 5.0 以上的手机 ) 布局文件很简单,核心就是这个 JavaCamera2View 视图
OpenCV4 调用摄像头黑屏问题
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); } }
实现要领
public interface CvCameraViewListener { /** * This method is invoked when camera preview has started. After this method is invoked * the frames will start to be delivered to client via the onCameraFrame() callback. * @param width - the width of the frames that will be delivered * @param height - the height of the frames that will be delivered */ public void onCameraViewStarted(int width, int height); /** * This method is invoked when camera preview has been stopped for some reason. * No frames will be delivered via onCameraFrame() callback after this method is called. */ public void onCameraViewStopped(); /** * This method is invoked when delivery of the frame needs to be done. * The returned values - is a modified frame which needs to be displayed on the screen. * TODO: pass the parameters specifying the format of the frame (BPP, YUV or RGB and etc) */ public Mat onCameraFrame(Mat inputFrame); }
public interface CvCameraViewListener2 { /** * This method is invoked when camera preview has started. After this method is invoked * the frames will start to be delivered to client via the onCameraFrame() callback. * @param width - the width of the frames that will be delivered * @param height - the height of the frames that will be delivered */ public void onCameraViewStarted(int width, int height); /** * This method is invoked when camera preview has been stopped for some reason. * No frames will be delivered via onCameraFrame() callback after this method is called. */ public void onCameraViewStopped(); /** * This method is invoked when delivery of the frame needs to be done. * The returned values - is a modified frame which needs to be displayed on the screen. * TODO: pass the parameters specifying the format of the frame (BPP, YUV or RGB and etc) */ public Mat onCameraFrame(CvCameraViewFrame inputFrame); }; /** * This class interface is abstract representation of single frame from camera for onCameraFrame callback * Attention: Do not use objects, that represents this interface out of onCameraFrame callback! */ public interface CvCameraViewFrame { /** * This method returns RGBA Mat with frame */ public Mat rgba(); /** * This method returns single channel gray scale Mat with frame */ public Mat gray(); };
示例程序
Java代码
public class OpencvCameraActivity extends CameraActivity { private static final String TAG = "OpencvCam"; private OpencvCameraActivity activity = this; private JavaCamera2View javaCameraView; private CameraBridgeViewBase.CvCameraViewListener2 cvCameraViewListener2 = new CameraBridgeViewBase.CvCameraViewListener2() { @Override public void onCameraViewStarted(int width, int height) { Log.i(TAG, "onCameraViewStarted width=" + width + ", height=" + height); } @Override public void onCameraViewStopped() { Log.i(TAG, "onCameraViewStopped"); } @Override public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) { return inputFrame.rgba(); } } private BaseLoaderCallback baseLoaderCallback = new BaseLoaderCallback(this) { @Override public void onManagerConnected(int status) { Log.i(TAG, "onManagerConnected status=" + status + ", javaCameraView=" + javaCameraView); switch (status) { case LoaderCallbackInterface.SUCCESS: { if (javaCameraView != null) { javaCameraView.setCvCameraViewListener(cvCameraViewListener2); // 禁用帧率显示 javaCameraView.disableFpsMeter(); javaCameraView.enableView(); } } break; default: super.onManagerConnected(status); break; } } }; // 复写父类的 getCameraViewList 方法,把 javaCameraView 送到父 Activity,一旦权限被授予之后,javaCameraView 的 setCameraPermissionGranted 就会自动被调用。 @Override protected List<? extends CameraBridgeViewBase> getCameraViewList() { Log.i(TAG, "getCameraViewList"); List<CameraBridgeViewBase> list = new ArrayList<>(); list.add(javaCameraView); return list; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_camera3); javaCameraView = findViewById(R.id.javaCameraView); } @Override public void onPause() { Log.i(TAG, "onPause"); super.onPause(); if (javaCameraView != null) { javaCameraView.disableView(); } } @Override public void onResume() { Log.i(TAG, "onResume"); super.onResume(); if (OpenCVLoader.initDebug()) { Log.i(TAG, "initDebug true"); baseLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS); } else { Log.i(TAG, "initDebug false"); OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION, this, baseLoaderCallback); } } }
布局文件
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="https://schemas.android.com/apk/res/android" xmlns:app="https://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <org.opencv.android.JavaCamera2View android:id="@+id/javaCameraView" android:layout_width="match_parent" android:layout_height="match_parent" app:camera_id="back" app:show_fps="true" /> </FrameLayout>
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算