700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Android从零开始配置opencv+tensorflow进行人脸识别+口罩识别(二:opencv展示当前图像

Android从零开始配置opencv+tensorflow进行人脸识别+口罩识别(二:opencv展示当前图像

时间:2020-07-22 23:58:45

相关推荐

Android从零开始配置opencv+tensorflow进行人脸识别+口罩识别(二:opencv展示当前图像

前言

上一章已经成功导入了opencv,但并没说如何展示从摄像头获取图像并展示出来,这章将简单的说说怎么展示,以及里面出现的问题作修正

一、使用opencv正常展示图像

首先准备一个空的activity页面,在其xml布局中添加JavaCameraView,这个view宽高都可以,不过,我为了在这个view下面添加功能按钮,所以给了高度限制

示例代码

<org.opencv.android.JavaCameraViewandroid:id="@+id/cameraView"android:layout_width="@dimen/dp_300"android:layout_height="@dimen/dp_250"android:layout_gravity="center" />

添加后,在activity中对其生命周期作一下简单的绑定,我个人是写在onResume,onPause和onDestroy三个生命周期中去了

示例代码

onResume中的代码

override fun onResume() {super.onResume(){你自己的的JavaCameraView的名字}.connectCamera(width, height)}

onResume中的代码

override fun onResume() {super.onResume()//这里的width和height是view的宽高,方便去获取一个最佳的展示的分辨率,毕竟你不想在一个小格子里展示4k图,也不想在一个大格子里展示160x120分辨率的图 by yinjun{你自己的的JavaCameraView的名字}.connectCamera(width, height)}

onPause中的代码

override fun onPause() {super.onPause()//临时关闭camera,别锁屏还一直录,小心烧了你那4k摄像头 by yinjun{你自己的的JavaCameraView的名字}.cameraView.releaseCamera()}

onDestroy中的代码

override fun onDestroy() {super.onDestroy()//直接释放摄像头,页面都没了,还要摄像头干嘛?by yinjun{你自己的的JavaCameraView的名字}.cameraView.disableView()}

做完上面的操作,运行到手机上,你的opencv就可以正常展示第一个图像。。。等等,似乎有一点点不对劲?

![请添加图片描述](https://img-/a472609ad9e74433aa8b3df51d640aef.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAd2VpeGluXzQ3NDkxNjY4,size_20,color_FFFFFF,t_70,g_se,x_16

这个东西,为啥是歪着的?看来得作一些小小的调优

二、opencv抓取画面调优

1.错误的角度调整

首先,是吧图片给转过来,让其可以正常展示图片,JavaCameraView中有一个监听方法setCvCameraViewListener,这个监听器除了能监听当前摄像头是开启还是关闭以外,它的onCameraFrame方法所返回的mat就是javaCameraView中展示的东西,吧这个mat旋转,展示正确的图像,需要注意的地方都写注释里了

代码如下(示例):

cameraView.setCvCameraViewListener(object : CameraBridgeViewBase.CvCameraViewListener2 {override fun onCameraViewStarted(width: Int, height: Int) {Log.e("hehe", "开始")}override fun onCameraViewStopped() {Log.e("hehe", "结束")}override fun onCameraFrame(inputFrame: CameraBridgeViewBase.CvCameraViewFrame?): Mat {var result: Mat? = null//因为里面要干的事情有点多,这个回调又相当于子线程干完活要回主线程作展示,所以这里最好加个锁 by yinjunsynchronized(this) {if (result != null) {//先把图片摆正var angle = 90//这里注意一下,如果直接旋转90度,不做其他处理会导致调用前摄像头时直接上下翻转,所以要根据当前是不是前摄像头来改旋转值by yinjunif (cameraView.getmCameraIndex() == CameraBridgeViewBase.CAMERA_ID_FRONT) {angle = 270}//记得,吧你那图像的宽高一起改一下,不改?等着看扁扁图吧 by yinjunvar size = Size(result.width().toDouble(), result.height().toDouble())Imgproc.warpAffine(result, result, Imgproc.getRotationMatrix2D(Point((result.width() / 2).toDouble(), (result.height() / 2).toDouble()), angle.toDouble(), -1.0), size)}}//这个返回的mat就是你要用来展示的图像,你可用对其作其他更改,比如变灰,加框什么的操作之后再返回,但这就是后话了return result!!}})

写到这里,肯定有人稍微有些蒙蔽,我的javaCameraView里没有getmCameraIndex啊,因为这个参在opencv哪里是一个私有的参,你需要自己去手写一个方法调取,写的也很简单,直接在javaCameraView中添加一个方法就可以了

public int getmCameraIndex(){return mCameraIndex;}

2.如何旋转摄像头

上面的注释里写了需要吧前摄转270°,可是opencv里似乎没有直接转摄像头的方法,怎么办?自己来办,直接准备一个按钮,为其配置以下点击事件

{你的按钮的名字}.setOnClickListener {//现在是前摄,切回后摄,现在是后摄,切回前摄 by yinjunif (cameraView.getmCameraIndex() == CameraBridgeViewBase.CAMERA_ID_FRONT) {cameraView.setCameraIndex(CameraBridgeViewBase.CAMERA_ID_BACK)} else {cameraView.setCameraIndex(CameraBridgeViewBase.CAMERA_ID_FRONT)}//设定完新的摄像头下标后,就可用停用,然后重启摄像头了 by yinjuncameraView.releaseCamera();cameraView.connectCamera(width, height)}

结尾

上述操作完成后,你就可以正常使用opencv展示摄像头出现的图像了,并且自由切换前后摄像头了,opencv的mat的宽高是通过connectCamera(width, height)中传入的宽高,在你摄像头支持分辨率中找到一个最佳的分辨率,所以不需要担心我这8k摄像头的手机,会不会一直拿8k图像,读爆我的内存之类的,不会,至此,opencv部分的操作基本上就大功告成了,后面会说如何接入tensorflow以及如何用tensorflow-lite作人脸识别和口罩识别并展示出是否佩戴口罩

ps:本来早就准备好一起上,但opencv对人连带口罩时的读取识别度太低了,dlib表现不错,但dlib性能问题堪忧,而且还因为用的一个模型比较大,用在移动端上有点内存杀手的意思,所以选内存占用更小的tensorflow-lite,但tensorflowlite的人脸识别的模型构建我还没看,估计要一段时间了,可能会先出一个opencv读取人脸的教程混混?

Android从零开始配置opencv+tensorflow进行人脸识别+口罩识别(二:opencv展示当前图像并作适当调整)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。