前言
上一章已经成功导入了opencv,但并没说如何展示从摄像头获取图像并展示出来,这章将简单的说说怎么展示,以及里面出现的问题作修正
一、使用opencv正常展示图像
首先准备一个空的activity页面,在其xml布局中添加JavaCameraView,这个view宽高都可以,不过,我为了在这个view下面添加功能按钮,所以给了高度限制
示例代码
<org.opencv.android.JavaCameraView
android: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()
{你自己的的JavaCameraView的名字}.connectCamera(width, height)
}
onPause中的代码
override fun onPause() {
super.onPause()
{你自己的的JavaCameraView的名字}.cameraView.releaseCamera()
}
onDestroy中的代码
override fun onDestroy() {
super.onDestroy()
{你自己的的JavaCameraView的名字}.cameraView.disableView()
}
做完上面的操作,运行到手机上,你的opencv就可以正常展示第一个图像。。。等等,似乎有一点点不对劲?
这个东西,为啥是歪着的?看来得作一些小小的调优
二、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
synchronized(this) {
if (result != null) {
var angle = 90
if (cameraView.getmCameraIndex() == CameraBridgeViewBase.CAMERA_ID_FRONT) {
angle = 270
}
var 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)
}
}
return result!!
}
})
写到这里,肯定有人稍微有些蒙蔽,我的javaCameraView里没有getmCameraIndex啊,因为这个参在opencv哪里是一个私有的参,你需要自己去手写一个方法调取,写的也很简单,直接在javaCameraView中添加一个方法就可以了
public int getmCameraIndex(){
return mCameraIndex;
}
2.如何旋转摄像头
上面的注释里写了需要吧前摄转270°,可是opencv里似乎没有直接转摄像头的方法,怎么办?自己来办,直接准备一个按钮,为其配置以下点击事件
{你的按钮的名字}.setOnClickListener {
if (cameraView.getmCameraIndex() == CameraBridgeViewBase.CAMERA_ID_FRONT) {
cameraView.setCameraIndex(CameraBridgeViewBase.CAMERA_ID_BACK)
} else {
cameraView.setCameraIndex(CameraBridgeViewBase.CAMERA_ID_FRONT)
}
cameraView.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读取人脸的教程混混?
Original: https://blog.csdn.net/weixin_47491668/article/details/124367410
Author: weixin_47491668
Title: Android从零开始配置opencv+tensorflow进行人脸识别+口罩识别(二:opencv展示当前图像并作适当调整)
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/520951/
转载文章受原作者版权保护。转载请注明原作者出处!