JavaCV的摄像头实战之八:人脸检测

// 释放检测结果资源

objects.close();

// 将标注过的图片转为帧,返回

return converter.convert(grabbedImage);

}

  • 以上就是接口DetectService.java的全部:三个方法定义,两个静态方法,接下来就是接口的实现类了

人脸检测功能的实现类

  • 前面的DetectService接口仅定义了三个方法:初始化(init)、检测(convert)、资源释放(releaseOutputResource),现在开发这个接口的实现类HaarCascadeDetectService.java,实现真正的人脸检测功能

  • 完整代码如下,核心是init方法中实例化的分类器classifier,以及负责处理每一帧的convert方法,这里面会中调用刚才写的静态方法DetectService.detect,把原始帧转换成标注了检测结果的帧:

package com.bolingcavalry.grabpush.extend;

import lombok.extern.slf4j.Slf4j;

import org.bytedeco.javacpp.Loader;

import org.bytedeco.javacv.Frame;

import org.bytedeco.javacv.OpenCVFrameConverter;

import org.bytedeco.opencv.opencv_core.Mat;

import org.bytedeco.opencv.opencv_objdetect.CascadeClassifier;

import java.io.File;

import java.net.URL;

/**

  • @author willzhao

  • @version 1.0

  • @description Haar检测的实现类

  • @date 2021/12/3 8:09

*/

@Slf4j

public class HaarCascadeDetectService implements DetectService {

/**

  • 每一帧原始图片的对象

*/

private Mat grabbedImage = null;

/**

  • 原始图片对应的灰度图片对象

*/

private Mat grayImage = null;

/**

  • 分类器

*/

private CascadeClassifier classifier;

/**

  • 转换器

*/

private OpenCVFrameConverter.ToMat converter = new OpenCVFrameConverter.ToMat();

/**

  • 模型文件的下载地址

*/

private String modelFileUrl;

/**

  • 构造方法,在此指定模型文件的下载地址

  • @param modelFileUrl

*/

public HaarCascadeDetectService(String modelFileUrl) {

this.modelFileUrl = modelFileUrl;

}

/**

  • 音频采样对象的初始化

  • @throws Exception

*/

@Override

public void init() throws Exception {

// 下载模型文件

URL url = new URL(modelFileUrl);

File file = Loader.cacheResource(url);

// 模型文件下载后的完整地址

String classifierName = file.getAbsolutePath();

// 根据模型文件实例化分类器

classifier = new CascadeClassifier(classifierName);

if (classifier == null) {

log.error(“Error loading classifier file [{}]”, classifierName);

System.exit(1);

}

}

@Override

public Frame convert(Frame frame) {

// 由帧转为Mat

grabbedImage = converter.convert(frame);

// 灰度Mat,用于检测

if (null==grayImage) {

grayImage = DetectService.buildGrayImage(grabbedImage);

}

// 进行人脸检测,根据结果做处理得到预览窗口显示的帧

return DetectService.detect(classifier, converter, frame, grabbedImage, grayImage);

}

/**

  • 程序结束前,释放人脸检测的资源

*/

@Override

public void releaseOutputResource() {

if (null!=grabbedImage) {

grabbedImage.release();

}

if (null!=grayImage) {

grayImage.release();

}

if (null==classifier) {

classifier.close();

}

}

}

主程序PreviewCameraWithDetect

  • 《JavaCV的摄像头实战之一:基础》一文创建的simple-grab-push工程中已经准备好了父类AbstractCameraApplication,所以本篇继续使用该工程,创建子类实现那些抽象方法即可

  • 编码前先回顾父类的基础结构,如下图,粗体是父类定义的各个方法,红色块都是需要子类来实现抽象方法,所以接下来,咱们以本地窗口预览为目标实现这三个红色方法即可:

在这里插入图片描述

  • 新建文件PreviewCameraWithDetect.java,这是AbstractCameraApplication的子类,其代码很简单,接下来按上图顺序依次说明

  • 先定义CanvasFrame类型的成员变量previewCanvas,这是展示视频帧的本地窗口:

protected CanvasFrame previewCanvas

  • 还要定义DetectService类型的成员变量,用于稍后的检测操作,并在构造方法中对改成员变量赋值:

/**

  • 检测工具接口

*/

private DetectService detectService;

/**

  • 不同的检测工具,可以通过构造方法传入

  • @param detectService

*/

public PreviewCameraWithDetect(DetectService detectService) {

this.detectService = detectService;

}

  • 然后是初始化操作,除了previewCanvas的实例化和参数设置,还要调用检测服务的初始化方法:

@Override

protected void initOutput() throws Exception {

previewCanvas = new CanvasFrame(“摄像头预览”, CanvasFrame.getDefaultGamma() / grabber.getGamma());

previewCanvas.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

previewCanvas.setAlwaysOnTop(true);

// 检测服务的初始化操作

detectService.init();

}

  • 接下来是output方法,定义了拿到每一帧视频数据后做什么事情,这里会交给检测服务去处理,将处理结果在本地窗口显示:

@Override

protected void output(Frame frame) {

// 原始帧先交给检测服务处理,这个处理包括物体检测,再将检测结果标注在原始图片上,

// 然后转换为帧返回

Frame detectedFrame = detectService.convert(frame);

// 预览窗口上显示的帧是标注了检测结果的帧

previewCanvas.showImage(detectedFrame);

}

  • 由于检测服务也会耗时,所以这里调整每帧输出后的等待时间,以免预览时卡顿,请依照自己电脑CPU性能调整,我这里改为原有时长的八分之一:

@Override

protected int getInterval() {

return super.getInterval()/8;

}

  • 最后是处理视频的循环结束后,程序退出前要做的事情,即关闭本地窗口,另外还要调用检测服务的releaseOutputResource来释放其相关资源:

@Override

protected void releaseOutputResource() {

if (null!= previewCanvas) {

previewCanvas.dispose();

}

// 检测工具也要释放资源

detectService.releaseOutputResource();

}

  • 至此,用本地窗口预览摄像头的功能已开发完成,再写上main方法,注意参数100表示预览持续时间是100秒,modelFileUrl是模型文件在GitHub上的地址(注释掉的那个是人体的,您也可以试试):

public static void main(String[] args) {

String modelPath = “https://raw.github.com/opencv/opencv/master/data/haarcascades/haarcascade_frontalface_alt.xml”;

// String modelPath = “https://raw.github.com/opencv/opencv/master/data/haarcascades/haarcascade_upperbody.xml”;

new PreviewCameraWithDetect(new HaarCascadeDetectService(modelPath)).action(1000);

}

  • 运行main方法即可启动程序,如下图,预览窗口中如果有人像,人脸上就会出现红框(为了不侵犯群众演员的肖像权,手动对面部做了马赛克处理):

在这里插入图片描述

  • 至此,本地窗口预览集成人脸检测的功能就完成了,得益于JavaCV的强大,整个过程是如此的轻松愉快,接下来请继续关注欣宸原创,《JavaCV的摄像头实战》系列还会呈现更多丰富的应用;

  • 本文涉及的所有代码都能在接下来的介绍的GitHub仓库中找到

源码下载

  • 《JavaCV的摄像头实战》的完整源码可在GitHub下载到,地址和链接信息如下表所示(https://github.com/zq2599/blog_demos):

| 名称 | 链接 | 备注 |

| :-- | :-- | :-- |

| 项目主页 | https://github.com/zq2599/blog_demos | 该项目在GitHub上的主页 |

| git仓库地址(https) | https://github.com/zq2599/blog_demos.git | 该项目源码的仓库地址,https协议 |

| git仓库地址(ssh) | git@github.com:zq2599/blog_demos.git | 该项目源码的仓库地址,ssh协议 |

  • 这个git项目中有多个文件夹,本篇的源码在javacv-tutorials文件夹下,如下图红框所示:

在这里插入图片描述

  • javacv-tutorials里面有多个子工程,《JavaCV的摄像头实战》系列的代码在simple-grab-push工程下:

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
且无助。**

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

[外链图片转存中…(img-SyEuzcqx-1714807541278)]

[外链图片转存中…(img-flfxhV9k-1714807541278)]

[外链图片转存中…(img-SDsrvGaT-1714807541278)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

  • 24
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值