动态人脸检测前提是需要打开摄像头。

网上看了很多教程,我知道的有两种方式打开摄像头:

JavaCameraView mCameraView = new JavaCameraView(this, -1);
setContentView(mCameraView);
mCameraView.setCvCameraViewListener(this); mCameraView.enableView();

第2种:在布局文件中添加 CameraBridgeViewBase

mCameraView = (CameraBridgeViewBase) findViewById(R.id.java_surface_view);
mCameraView.setCvCameraViewListener(this);
mCameraView.enableView();

以上两种获取摄像头实时视频流方式需要 implements  CameraBridgeViewBase.CvCameraViewListener

public class FaceTrackingActivity extends AppCompatActivity implements CameraBridgeViewBase.CvCameraViewListener {
  @Overrid
  protected void onCreate(Bundle savedInstanceState) {
...
} @Override
public void onCameraViewStarted(int width, int height) { } @Override
public void onCameraViewStopped() { } @Override
public Mat onCameraFrame(Mat inputFrame) {
return null;
}
}
onCameraFrame 函数中将捕获视频每一帧。
这样我在预览视频的时候,发现很难控制大小,以及摄像头的方向。
后来我直接采用以往的camera类去操作视频流。
以上参考:http://blog.csdn.net/tobacco5648/article/details/51615632

实时处理摄像头预览帧视频参考:http://blog.csdn.net/yanzi1225627/article/details/8605061

定义 SurfaceView

    <SurfaceView
android:id="@+id/java_surface_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
        mSurfaceView = (SurfaceView) findViewById(R.id.java_surface_view);
mSurfaceHolder = mSurfaceView.getHolder(); // mSurfaceView 不需要自己的缓冲区
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
// mSurfaceView添加回调
mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) { //SurfaceView创建
try {
cameraManager = new CameraManager(FaceTrackingActivity.this, mObjectDetects, cimbt, mSurfaceHolder);
cameraManager.openDriver();
cameraManager.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
} @Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override
public void surfaceDestroyed(SurfaceHolder holder) { //SurfaceView销毁
holder.removeCallback(this); // Camera is being used after Camera.release() was called
cameraManager.stopPreview();
cameraManager.closeDriver(); }
});

我这里独立出来了一个 CameraManager 类,本来我想把检测的代码写在 CameraManager 类之外,然而并没有实现:

CameraManager 类中  implements Camera.PreviewCallback 可以实现 onPreviewFrame 对实时数据处理:

    @Override
public void onPreviewFrame(byte[] bytes, Camera camera) {
Camera.Size previewSize = camera.getParameters().getPreviewSize(); Bitmap bitmap = ByteToBitmap(bytes, previewSize);
//Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);//将data byte型数组转换成bitmap文件 final Matrix matrix = new Matrix();//转换成矩阵旋转90度
if (cameraPosition == 1) {
matrix.setRotate(90);
} else {
matrix.setRotate(-90);
}
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);//旋转图片 Mat grayscaleImage = new Mat(previewSize.height, previewSize.width, CvType.CV_8UC4);
int absoluteFaceSize = (int) (previewSize.height * 0.2); if (bitmap != null) {
Mat inputFrame = new Mat();
Utils.bitmapToMat(bitmap, inputFrame); if (!bitmap.isRecycled()) {
bitmap.recycle();
} // Create a grayscale image
Imgproc.cvtColor(inputFrame, grayscaleImage, Imgproc.COLOR_RGBA2RGB); MatOfRect mRect = new MatOfRect(); int maxRectArea = 0 * 0;
Rect maxRect = null; int facenum = 0; for (ObjectDetector detector : mObjectDetects) {
// 检测目标
Rect[] object = detector.detectObjectImage(inputFrame, mRect);
Log.e(TAG, object.length + ""); for (Rect rect : object) {
++facenum;
// 找出最大的面积
int tmp = rect.width * rect.height;
if (tmp >= maxRectArea) {
maxRectArea = tmp;
maxRect = rect;
}
}
} Bitmap rectBitmap = null;
if (facenum != 0) {
// 剪切最大的头像
//Log.e("剪切的长宽", String.format("高:%s,宽:%s", maxRect.width, maxRect.height));
Rect rect = new Rect(maxRect.x, maxRect.y, maxRect.width, maxRect.height);
Mat rectMat = new Mat(inputFrame, rect); // 从原始图像拿
rectBitmap = Bitmap.createBitmap(rectMat.cols(), rectMat.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(rectMat, rectBitmap); Bitmap resizeBmp = cimbt.resizeBitmap(rectBitmap, cimbt.getWidth(), cimbt.getHeight());
cimbt.setBitmap(resizeBmp);
} else {
cimbt.clearnImage();
cimbt.setText("没有检测到人脸");
}
} }

补充:在初始化相机时激活onPreviewFrame

camera.setPreviewCallback(this);
//camera.setOneShotPreviewCallback(this); // 激活 onPreviewFrame 执行一次

整个人脸静态动态检测源代码: https://github.com/haoxr/faceDetection

动态检测截图:

Android+openCV 动态人脸检测的更多相关文章

  1. python中使用Opencv进行人脸检测

    这两天学习了人脸识别,看了学长写的代码,边看边码边理解搞完了一边,再又是自己靠着理解和记忆硬码了一边,感觉还是很生疏,就只能来写个随笔加深一下印象了. 关于人脸识别,首先需要了解的是级联分类器Casc ...

  2. 【转载】opencv实现人脸检测

    全文转载自CSDN的博客(不知道怎么将CSDN的博客转到博客园,应该没这功能吧,所以直接复制全文了),转载地址如下 http://blog.csdn.net/lsq2902101015/article ...

  3. OpenCV学习系列(一) Mac下OpenCV + xcode人脸检测实现

    # OpenCV学习系列(一) Mac下OpenCV + xcode人脸检测实现 [-= 博客目录 =-] 1-学习目标 1.1-本章介绍 1.2-实践内容 1.3-相关说明 2-学习过程 2.1-环 ...

  4. OpenCV实现人脸检测

    OpenCV实现人脸检测(转载)  原文链接:https://www.cnblogs.com/mengdd/archive/2012/08/01/2619043.html 本文介绍最基本的用OpenC ...

  5. Android 中使用 dlib+opencv 实现动态人脸检测

    1 概述 完成 Android 相机预览功能以后,在此基础上我使用 dlib 与 opencv 库做了一个关于人脸检测的 demo.该 demo 在相机预览过程中对人脸进行实时检测,并将检测到的人脸用 ...

  6. 利用html5、websocket和opencv实现人脸检测

    最近学习人脸识别相关的东西,在MFC下使用OpenCV做了一个简单的应用.训练需要较多的数据,windows应用程序终究还是不方便,于是想着做成CS模式:检测识别都放在服务器端,视频获取和显示都放在网 ...

  7. 基于OpenCv的人脸检测、识别系统学习制作笔记之三

    1.在windows下编写人脸检测.识别系统.目前已完成:可利用摄像头提取图像,并将人脸检测出来,未进行识别. 2.在linux下进行编译在windows环境下已经能运行的代码. 为此进行了linux ...

  8. 基于OpenCv的人脸检测、识别系统学习制作笔记之一

    基于OpenCv从视频文件到摄像头的人脸检测 在OpenCv中读取视频文件和读取摄像头的的视频流然后在放在一个窗口中显示结果其实是类似的一个实现过程. 先创建一个指向CvCapture结构的指针 Cv ...

  9. Python学习--使用dlib、opencv进行人脸检测标注

    参考自https://www.pyimagesearch.com/2017/04/03/facial-landmarks-dlib-opencv-python/ 在原有基础上有一部分的修改(image ...

随机推荐

  1. Listen 指令

    L:44

  2. Linux磁盘空间被未知资源耗尽

      在linux中,当我们使用rm在linux上删除了大文件,但是如果有进程打开了这个大文件,却没有关闭这个文件的句柄,那么linux内核还是不会释放这个文件的磁盘空间,最后造成磁盘空间占用100%, ...

  3. 笔记本装双系统!win10+Linux!所有的坑自己一个个爬过来,纪念一下。

    笔记本装双系统!win10+Linux!所有的坑自己一个个爬过来,纪念一下. 2018年09月16日 21:27:19 Corax_2ven 阅读数:14038   写在前面,装了大概5遍,装了删删了 ...

  4. docker_监控

    目录 Docker 自带的监控子命令 sysdig Weave Scope cAdvisor Prometheus Prometheus 的架构 多维数据模型 Docker 自带的监控子命令 ps d ...

  5. 记录一次被bc利用跳转过程分析

    挖公司的项目站,发现站点一访问就直接跳转到了赌博站,有点懵逼,简单分析下hc利用过程: 公司项目站:http://***.com 当我访问它: 通过http:***.com直接跳转到了306648.c ...

  6. 彻底理解cookie,session,token

    发展史 1.很久很久以前,Web 基本上就是文档的浏览而已, 既然是浏览,作为服务器, 不需要记录谁在某一段时间里都浏览了什么文档,每次请求都是一个新的HTTP协议, 就是请求加响应,  尤其是我不用 ...

  7. windows下创建启动脚本bat

    最主要是运用bat命令. call执行命令 比如 启动solr的服务,以前要进去solr的目录,然后bin/solr start    这样很麻烦.可以写个脚本放到桌面. call %CATALINA ...

  8. 深入学习c++(虚函数遇到析构函数就退化了)

    1. 在构造函数和析构函数中调用的虚函数并不具备虚函数的特性 因为基类的构造函数先构造, 析构函数后析构

  9. 深入学习javaScript闭包(闭包的原理,闭包的作用,闭包与内存管理)

    前言 虽然JavaScript是一门完整的面向对象的编程语言,但这门语言同时也拥有许多函数式语言的特性. 函数式语言的鼻祖是LISP,JavaScript在设计之初参考了LISP两大方言之一的Sche ...

  10. Latex "Error: Extra alignment tab has been changed to \cr. "

    Latex 编译时出现 Error: Extra alignment tab has been changed to \cr.  是因为\begin{tabular}后面的参数指定为7列,而实际排了8 ...