Android Camera API 与 OpenCV API

来源:互联网 发布:jquery数组中移除元素 编辑:程序博客网 时间:2024/05/29 15:45

Sample程序里面涉及到了两种模式,一种是完全使用android系统的自带Camera API,还有一种是将摄像头处理部分替换为OpenCV的API,总的来说,第二种更为简单和整洁一些。下面简单的记录一下我的理解。

首先是android系统摄像头取像并形成预览的过程:
要显示预览画面,当然要先有个界面吧,因此,一个SurfaceView是必不可少的。而为了配合SurfaceView工作,就要有一个SurfaceHolder。所以定义一个类,继承SurfaceView,并实现SurfaceHolder.callback接口。初始化工作等等不提。
SurfaceView有两个主要方法,SurfaceCreated和SurfaceChanged。这两个方法会依次自动执行,所以主要工作都在这两个方法中完成。

首先是Created,这个最先执行,可以在里面完成摄像头的打开:mCamera = Camera.open();

然后就到了Changed过程,可以把主要任务都放到这里。
1)得到Camera的配置参数,主要是支持的摄像分辨率都有哪些。
2)将这些分辨率组合与屏幕(SurfaceView)的大小(会作为参数传入)相比较,选出最接近的哪一种组合,比如我的G7得到的是432*768。将这些参数配置给Camera。
3)开启Camera的预览功能:依次setPreviewDisplay和startPreview()。
到此算是完成了基本的准备工作,要显示图像?继续。。
4)为Camera添加预览的回调函数:setPreviewCallback(),参数为一个预览回调类或其子类:PreviewCallback()。感觉是当摄像头取得了图像数据并后便会执行callback类的onPreviewFrame方法,其中图像数据会被当作参数传入,是一个byte[] data。可以取得这个矩阵,然后在另一个线程中进行数据处理。
5)要将摄像头得到的图像数据预览在屏幕上,就要把图像数据转化为位图bitmap,转化的过程就是主要的数据处理过程,在这里根据以后的需要完成不同的功能,最后返回一个位图bmp。后面的显示过程可以这样:通过surfaceHolder得到一个画布Canvas canvas = mHolder.lockCanvas(),将位图画在canvas上,最后通过surfaceHolder将canvas解锁并推送到屏幕上。至此一帧数据图像就显示在了屏幕上。
摄像头会继续捕获图像,继而不断的触发回调函数,实现实时的图像预览效果。

调用OpenCV的API也可以实现这个过程,其基本流程与上面的过程相似,也是在SurfaceView的结构上实现的。主要的不同是其使用了一个VideoCapture类取代了原来的Camera类,不仅如此,这个类还封装了了参数设置、回调函数等功能。所以在省去了为Camera设置回调函数的这部分工作,其捕获的图像数据可以通过在图像处理函数中使用capture.retrieve方法获得。所以其基本过程就可以概括为:打开摄像头、设置预览分辨率、直接处理捕获数据,绘制画布并显示。

Sample中的其他部分主要是在Java项目中调用本地函数的方法,其Native文件主要进行的工作就是比较耗时和复杂的数据处理部分,针对的就是将原始的视频输入数据转变为满足要求的位图这一部分任务,也是继续研究的重点。


0 0