昨天使用javacv写了个实时人脸检测的简单程序,网上找了很多代码,但是觉得都太冗余了,大多是人脸检测和对比之类的代码一起写的,加上javacv版本不同,有些函数和数据结构不同,看的我一脸混乱,我只是想要一个单独的人脸检测有人脸检测功能的代码而已,所以这里简单剥离了一下,只留下了最核心的人脸检测部分的代码(不是识别或者匹配)。

    我这里使用的是javacv1.2+myeclipse blue
2014,(javacv0.8之前的版本貌似要使用opencv+javacv才行,0.8以后貌似不用引入opencv了)。



ps:之前我在同一个项目中同时导入了javacv1.2的包和opencv3.2/build/java/opencv_320.jar包。发现javacv的包和opencv的包里面的类发生了冲突,两个包中都有Mat,但是像个包中的类(Mat)互不相通,一时间搞得代码相当混乱,这里建议opencv和javacv还是分开用,不要再同一个项目中同时导入。

   
首先是javacv包的下载,这个直接在百度下载就行了,下载之后解压,将javacv-1.2-bin目录下的opencv.jar,javacv.jar,javacpp.jar,opencv_windows_x86_64.jar(如果是32位程序,这个包换成opencv_windows_x86.jar导入),这四个包直接导入eclispse就行,简单快捷。之后我们就可以开始使用javacv了。


    首先我们获取电脑摄像头,这里javacv封装好了,我们几句就可以调用:
OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0); //初始化摄像头
grabber.start(); //开始获取摄像头数据 Frame frame=grabber.grab();//获取摄像头图像的一帧
 
获取到的图片,我们用FrameCanvas来展示,这是一个窗口,其中可以传入Frame类型的数据,这个窗口将展示Frame代表的图像,当然你可以使用swing或者awt来展示,只是用FrameCanvas简单太多了,只要下面几行代码就可以实现一张图片的展示:
CanvasFrame canvas = new CanvasFrame("人脸检测");//新建一个窗口
canvas.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置关闭窗口时销毁窗口
canvas.showImage(frame);//在canvas窗口上显示frame代表的图像
    将这两部分结合起来,我们可以实现实时展示摄像头内容的功能:
            OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0);
grabber.start(); //开始获取摄像头数据 CanvasFrame canvas = new
CanvasFrame("人脸检测");//新建一个窗口
canvas.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); while(true) {
if(!canvas.isEnabled()) {//窗口是否关闭 grabber.stop();//停止抓取 System.exit(0);//退出 }
Frame frame=grabber.grab(); canvas.showImage(frame);//获取摄像头图像并放到窗口上显示, 这里的Frame
frame=grabber.grab(); frame是一帧视频图像 Thread.sleep(50);//50毫秒刷新一次图像 }

    整个架子搭好了,我们只需要对获取到的每一帧图像拿去做一下人脸检测,然后吧检测到人脸的区域画出来就行了。这一部分javacv已经做了很多很好的封装,写起来也相当简单,下面我们来实现人脸检测的代码:

   
整个检测的过程主要依赖CascadeClassifier来实现,opencv/source/data目录下lbpcascades,haarcascades_cuda和haarcascades目录下都有已经训练好的人脸检测器,各个xml文件的后缀名frontalface的文件为人脸检测器,如lbpcascades/lbpcascade_frontalface.xml,各个检测器的比较这里就不多说,有需要的同学可以网上查。

                CascadeClassifier cascade = new
CascadeClassifier("G:\\opencv3.2\\opencv\\sources\\data\\lbpcascades\\lbpcascade_frontalface.xml");//初始化人脸检测器
                RectVector faces=new RectVector();//创建用来装检测出来的人脸的容器
cascade.detectMultiScale(grayscr, faces);//检测人脸,grayscr为要检测的图片,faces用来存放检测结果
                for(int i=0;i<faces.size();i++)//遍历检测出来的人脸 { Rect
face_i=faces.get(i); rectangle(src, face_i, new Scalar(0, 0, 255,
1));//在原图上画出人脸的区域 }
完整的detectFace函数代码如下:
public static Mat detectFace(Mat src) { Mat grayscr=new Mat();
cvtColor(src,grayscr,COLOR_BGRA2GRAY);//摄像头是彩色图像,所以先灰度化下
equalizeHist(grayscr,grayscr);//均衡化直方图 RectVector faces=new RectVector();
cascade.detectMultiScale(grayscr, faces); for(int i=0;i<faces.size();i++) {
Rect face_i=faces.get(i); rectangle(src, face_i, new Scalar(0, 0, 255, 1)); }
return src; }
到这里,人脸检测的函数就写完了,接下来只要将这个函数应用到,摄像头获取的每一帧图像中去就可以实时检测人脸了。
public static void JavavcCameraTest() throws Exception, InterruptedException {
    OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0); grabber.start();
//开始获取摄像头数据 CanvasFrame canvas = new CanvasFrame("人脸检测");//新建一个窗口
canvas.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); while(true) {
if(!canvas.isEnabled()) {//窗口是否关闭 grabber.stop();//停止抓取 System.exit(0);//退出 }
Frame frame=grabber.grab(); Mat
scr=convertor.convertToMat(frame);//将获取的frame转化成mat数据类型 detectFace(scr);//人脸检测
frame=convertor.convert(scr);//将检测结果重新的mat重新转化为frame
canvas.showImage(frame);//获取摄像头图像并放到窗口上显示,frame是一帧视频图像
Thread.sleep(50);//50毫秒刷新一次图像 } }
到这里,简单的实时人脸检测就完成了,效果如下:













友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:ixiaoyang8@qq.com
QQ群:637538335
关注微信