【OpenCV人脸识别入门教程之二】人脸检测

【OpenCV人脸识别入门教程之二】人脸检测本篇文章主要介绍了如何使用OpenCV实现人脸检测的功能。要实现人脸识别功能,首先要进行人脸检测,判断出图片中人脸的位置,才能进行下一步的操作。人脸检测的方法介绍OpenCV中的方法函数参数含义代码实现

大家好,又见面了,我是你们的朋友全栈君。

本篇文章主要介绍了如何使用OpenCV实现人脸检测。本文不具体讲解人脸检测的原理,直接使用OpenCV实现。

OpenCV版本:2.4.10;VS开发版本:VS2012。

一、OpenCV人脸检测

要实现人脸识别功能,首先要进行人脸检测,判断出图片中人脸的位置,才能进行下一步的操作。

1、OpenCV人脸检测的方法

在OpenCV中主要使用了两种特征(即两种方法)进行人脸检测,Haar特征和LBP特征。

在OpenCV中,使用已经训练好的XML格式的分类器进行人脸检测。在OpenCV的安装目录下的sources文件夹里的data文件夹里可以看到下图所示的内容:

【OpenCV人脸识别入门教程之二】人脸检测

上图中文件夹的名字“haarcascades”、“hogcascades”和“lbpcascades”分别表示通过“haar”、“hog”和“lbp”三种不同的特征而训练出的分类器:即各文件夹里的文件。”haar”特征主要用于人脸检测,“hog”特征主要用于行人检测,“lbp”特征主要用于人脸识别。打开“haarcascades”文件夹,如下图所示

【OpenCV人脸识别入门教程之二】人脸检测

图中的XML文件即是我们人脸检测所需要的分类器文件。在实际使用中,推荐使用上图中被标记的“haarcascade_frontalface_alt2.xml”分类器文件,准确率和速度都比较好。

2、OpenCV中的人脸检测的类

在OpenCV中,使用类“CascadeClassifier”进行人脸检测

CascadeClassifier faceCascade;   //实例化对象

所需要使用的函数:

faceCascade.load("../data/haarcascade_frontalface_alt2");  //加载分类器
faceCascade.detectMultiScale(imgGray, faces, 1.2, 6, 0, Size(0, 0));  //多尺寸检测人脸

实现人脸检测主要依赖于detectMultiScale()函数,下面简单说一下函数参数的含义,先看函数原型:

CV_WRAP virtual void detectMultiScale( const Mat& image,
                                   CV_OUT vector<Rect>& objects,
                                   double scaleFactor=1.1,
                                   int minNeighbors=3, int flags=0,
                                   Size minSize=Size(),
                                   Size maxSize=Size() );

各参数含义:

  • const Mat& image: 需要被检测的图像(灰度图)
  • vector<Rect>& objects: 保存被检测出的人脸位置坐标序列
  • double scaleFactor: 每次图片缩放的比例
  • int minNeighbors: 每一个人脸至少要检测到多少次才算是真的人脸
  • int flags: 决定是缩放分类器来检测,还是缩放图像
  • Size(): 表示人脸的最大最小尺寸

二、代码实现

1、检测图片中的人脸

//头文件
#include<opencv2/objdetect/objdetect.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>

using namespace cv;

//人脸检测的类
CascadeClassifier faceCascade;

int main()
{
	faceCascade.load("../data/haarcascade_frontalface_alt2.xml");   //加载分类器,注意文件路径

	Mat img = imread("../data/PrettyGirl.jpg");
	Mat imgGray;
	vector<Rect> faces;

	if(img.empty())
	{
	  return 1;
	}

	if(img.channels() ==3)
	{
	   cvtColor(img, imgGray, CV_RGB2GRAY);
	}
	else
	{
	   imgGray = img;
	}

	faceCascade.detectMultiScale(imgGray, faces, 1.2, 6, 0, Size(0, 0));   //检测人脸

	if(faces.size()>0)
	{
	   for(int i =0; i<faces.size(); i++)
	   {
	       rectangle(img, Point(faces[i].x, faces[i].y), Point(faces[i].x + faces[i].width, faces[i].y + faces[i].height), 
			               Scalar(0, 255, 0), 1, 8);    //框出人脸位置
	   }
	}

	imshow("FacesOfPrettyGirl", img);

	waitKey(0);
	return 0;
}

结果如下图:

【OpenCV人脸识别入门教程之二】人脸检测

2、检测视频中的人脸

//头文件
#include<opencv2/objdetect/objdetect.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>

using namespace cv;

//人脸检测的类
CascadeClassifier faceCascade;

int main()
{
	faceCascade.load("../data/haarcascade_frontalface_alt2.xml");   //加载分类器,注意文件路径

	VideoCapture cap;  
	cap.open(0);   //打开摄像头
	//cap.open("../data/test.avi");   //打开视频
	Mat img, imgGray;
	vector<Rect> faces;
	int c = 0;

	if(!cap.isOpened())
	{
	  return 1;
	}

	while(c!=27)
	{
		cap>>img;
	   if(img.channels() ==3)
	   {
	      cvtColor(img, imgGray, CV_RGB2GRAY);
	   }
	   else
	   {
	      imgGray = img;
	   }

	   faceCascade.detectMultiScale(imgGray, faces, 1.2, 6, 0, Size(0, 0));   //检测人脸

	   if(faces.size()>0)
	   {
	      for(int i =0; i<faces.size(); i++)
	      {
	          rectangle(img, Point(faces[i].x, faces[i].y), Point(faces[i].x + faces[i].width, faces[i].y + faces[i].height), 
			                  Scalar(0, 255, 0), 1, 8);    //框出人脸位置
	      }
	   }
	
	   imshow("Camera", img);
	   c = waitKey(1);
	}
	return 0;
}

在视频实时检测时,可能会出现卡顿,是因为检测人脸花费了过多的时间,这里代码只实现基本功能,并未优化。

本文完。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/134088.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Java–反射

    Java–反射反射定义用途(了解)反射基本信息反射相关的类Class类(反射机制的起源)反射的使用反射优点和缺点定义Java的反射(reflection)机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性,既然能拿到那么,我们就可以修改部分类型信息;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射(reflection)机制。用途(了解)1、在日常的第三方应用开发过程中,经常会遇到某个类的某个成员变量、方法或是属性是私有的或是只对

    2022年7月7日
    19
  • stm32收发 wiegand 韦根协议开发详解

    stm32收发 wiegand 韦根协议开发详解在刚开始接触到韦根接口时,知道这是一种门禁相关的传输协议。其中有两种比较常用的韦根数据格式,韦根26和韦根34,其中韦根26是开放的,韦根34开不开放我不知道(看样子不开放),但是在网上还是能看到韦根34的代码协议,下面介绍一下韦根26以及韦根34的相关内容。Wiegand26格式:各数据位的含义:第1位: 为输出数据2—13位的偶校验位第2-9位:…

    2025年7月13日
    0
  • Algorithms 普林斯顿算法课程笔记(一)

    Algorithms 普林斯顿算法课程笔记(一)本节将从动态连接性算法(并查集问题的模型)入手,引入算法分析和设计的整体思路和优化方法,为整个课程的引子部分。主要内容包括QuickFind和Quickunion算法,以及这些算法的改进。动态连接性对于连接做如下定义:自反:p连接于自身 对称:若p连接于q,则q连接于p 传递:若p连接q,q连接r那么p连接r我们的算法需要满足上述关于连接的定义。另外,引出了另一个概念…

    2022年9月1日
    3
  • springboot集成日志

    springboot集成日志一、通过代码引入slf4j因为pom文件中已经通过父类引入了log4j查看中有直接进行引入即可。// 在类中引入,MyController是本类名 private static final Logger log = LoggerFactory.getLogger(MyController.class);下面直接使用即可。显示结果:默认情况下是info…

    2022年6月13日
    24
  • ios事件-触摸事件2(手势 和 pointInSide()、hitTest()、touchesBegan()、touchesMoved()、touchesEnded()的关系)

    ios事件-触摸事件2(手势 和 pointInSide()、hitTest()、touchesBegan()、touchesMoved()、touchesEnded()的关系)ios事件-触摸事件2(手势和pointInSide()、hitTest()、touchesBegan()、touchesMoved()、touchesEnded()、touchesCancelled()的关系)先看效果图本文中,凡是看到xxx(),即表示xxx是一个函数或者方法!!!事件分为事件传递和事件响应,其中,事件响应又称事件处理。具体代码FindViewViewContr…

    2022年7月25日
    4
  • 菲尼克斯电源模块的安装

    菲尼克斯电源模块的安装这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML图表FLowchart流程图导出与导入导出导入菲尼克斯电源模块的安装QUINT4-PS/1AC/24DC/101.安全规范和安装注意事项警告:电击危险!仅有具备从

    2022年6月22日
    42

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号