OpenCV的Android环境具体搭建过程,请参考
Android 使用OpenCV的三种方式(Android Studio),并不在本文的范围之内。本文将OpenCV需要的依赖打成了opencvlib-release.aar包,关于aar包的打包和使用,请参考
Android Studio中打包aar并引用及打jar包
。
本文旨在介绍OpenCV打开相机,获取缓冲帧并保存的方法。OpenCV中用于显示相机缓冲界面的类为JavaCameraView,该类间接继承自SurfaceView。
相机显示的JavaCameraView的显示的代码如下:
//初始化CameraView
mCameraView = new JavaCameraView(this, mCameraIndex);
mCameraView.setMaxFrameSize(size.width, size.height);
mCameraView.setCvCameraViewListener(this);
第一行传入Context对象及相机编号,第二行设置缓冲帧的宽高,第三行设置了
CvCameraViewListener2的回调。
CvCameraViewListener2的三个实现方法:
1、onCameraStarted(int width, int height)
相机预览开始回调,width,height分别表示帧的款和高。在本实例中,可以再menu选项中修改相机的分辨率,具体效果读者可以自己运行附件体验。
注意:初始化相机是一个异步过程,在在调用了JavaCameraView的enableView方法后,并不能马上使用,需要在onCameraStarted方法中进行后续操作。例如本例中存储像素的矩阵初始化:
mBgr
=
new
Mat()
;
这行代码需要在JavaCameraView初始化完成后调用,否则你可能会得到一个.so库的link错误:
java.lang.UnsatisfiedLinkError: No implementation found for void org.opencv.core.Mat.n_delete(long) (tried Java_org_opencv_core_Mat_n_1delete and Java_org_opencv_core_Mat_n_1delete__J)
看下Mat类的源码:
public Mat() {
this.nativeObj = n_Mat();
}
再往下看:
private static native long
n_Mat()
;
我们会发现,原来n_Mat()是一个native方法,Mat对象是一个C++对象,而这个C++类的在
libopencv_java3.so包中,在加载完该.so包之前我们的Mat类是不能使用的。
2、onCameraViewStopped()
官方文档对该方法的描述为:
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.
从文档来看,本方法在相机缓冲帧本停止时调用,但停止的原因可能包括不可预见的异常停止。在该方法中可以做相机缓冲界面的善后工作。
3、public Mat onCameraFrame(CvCameraViewFrame inputFrame)
该方法获取到相机缓冲的每一帧,包含了缓冲帧的RGBA像素矩阵,实例中实现:
@Override
public Mat onCameraFrame(final CvCameraViewFrame inputFrame) {
final Mat rgba = inputFrame.rgba();
if (mIsPhotoPending) {
mIsPhotoPending = false;
takePhoto(rgba);
}
if (mIsCameraFrontFacing) {
// Mirror (horizontally flip) the preview.
Core.flip(rgba, rgba, 1);
}
return rgba;
}