前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >OpenCV学习入门(一):人脸检测

OpenCV学习入门(一):人脸检测

作者头像
用户1150922
发布2018-01-08 16:17:09
1.3K0
发布2018-01-08 16:17:09
举报
文章被收录于专栏:计算机视觉life计算机视觉life

关于OpenCV网上的学习资料非常多,尤其是很多比较专业的技术博客,对学习计算机视觉的筒子们真的是个非常好的帮助~踩在这些巨人们的肩膀上,我打算一步一个脚印从零开始学习,在博客里记录下遇到的问题及解决方法,也是对自己的一种监督和激励

(一)首先是安装软件,OpenCV下载地址点击打开链接,我使用的是2.4.10版本 + visualstudio 2010 + win7 32位系统。

(二)环境配置。OpenCV环境配置相较于一般的软件复杂一点,官网上有较详细的英文教程点击这里,但是对于习惯于中文的孩纸们可以参考这里。对于其他的版本,网上还有很多其他的可以参考。

那么问题来了,为什么要配置环境变量呢?肯定是为了后续使用方便啦!官方解释是这样滴:

看到英语就头大的同学可以看下我的翻(chě)译(dàn):

我们以动态链接库(DLL)的形式使用OpenCV库,这些库里包含了OpenCV所有的算法和信息。在运行程序时操作系统(operatingsystem)就会根据需要上载,但是操作系统需要知道去哪里找它们。所以我们把OpenCV库路径添加到系统路径(systemPATH)内包含的文件夹里,操作系统可以从这些文件夹里找到这些所需的DLLs,否则就需要我们人工的把用到的DLLs正确的拷贝到应用可执行文件里让系统去查找,这样当你有多个project时会疯掉的。

(三)好了,一切准备就绪了,先不管那些具体函数,类型什么的,先跑个程序,看看结果,知道OpenCV到底咋回事吧!我们根据OpenCV安装目录下opencv\build\doc里opencv_tutorials的指导来学习一下吧。我选择了objdetectmodule. Object Detection-->Cascade Classifier作为第一个实验,这个是从摄像头实时检测当前的人脸和人眼并显示的程序,先不管他的原理,只是觉得好玩,先调动起兴趣最重要!tutorial给出了代码下载链接点击打开链接 可以直接下载,然后复制到新建的工程里。注意复制分类器文件haarcascade_frontalface_alt.xmlhaarcascade_eye_tree_eyeglasses.xml (在“opencv\sources\data\haarcascades”目录下)到你的当前工程目录下(我放在了"opencv\faceDetection\"工程目录下,faceDetection是我建的工程文件名)。

(四)出现的问题及解决方法

1.        问题1:将.xml文件

代码语言:javascript
复制
String face_cascade_name = "haarcascade_frontalface_alt.xml"

改为绝对路径

代码语言:javascript
复制
String face_cascade_name = "F:\opencv\faceDetection\haarcascade_frontalface_alt.xml";

然后“生成-->生成解决方案”后报错:“不可识别的字符转义序列”

解决方法:出错的原因是OpenCV中文件路径要用双斜杠“\\”。“\”在 C/C++/C# 中是转义前导字符,这个符号“\”会把跟在它后面的字符结合起来转义为其他字符,例如“\n”代表换行。所以如果路径中出现转义前导字符“\”就会引起问题,所以路径中的“\”必须用“\\”代替。

细心的同学会追问:为什么

代码语言:javascript
复制
#include "opencv2/objdetect/objdetect.hpp"

没有报错呢?这是因为斜杠“/”表示从根目录开始。事实上,“\\”也可以用反斜杠“/”代替。以下两种表达方式都是对的:

代码语言:javascript
复制
String eyes_cascade_name = "F:/opencv/faceDetection/haarcascade_eye_tree_eyeglasses.xml";
代码语言:javascript
复制
String face_cascade_name = "F:\\opencv\\faceDetection\\haarcascade_frontalface_alt.xml";

关于左斜杠,右斜杠,绝对路径,相对路径的详细解释见这里

2.        问题2:程序保证正确的前提下,OpenCV获取笔记本电脑摄像头实时捕获视频时,捕获的窗口是一片灰色。

解决方法:win7系统下需要将代码capture.open( -1)中的“-1”改为“0”即可。

3.        using namespace cv的作用?

解释:一般放在使用#include语句包含相应头文件后.如果没有这个语句,那么在这个命名空间的相关资源就需要带上cv前缀,如cv::Mat,表示的是使用命名空间cv中的Mat;而有了using namespace cv这个语句后,就可以直接写Mat

4.        关于颜色空间RGB顺序排列问题

代码语言:javascript
复制
circle( frame, mouth_center, radius, Scalar( 0, 255, 0 ), 4, 8, 0 );//-- 蓝色圆框出眼睛

解释:上述(255,0,0)并非对应RGB(否则显示为红色),而是对应BGR(显示蓝色),因为在内存中RGB各分量的排列顺序为BGR 。

(五)代码

在给定代码基础上,可以自己改一改,玩一玩,我试着加入了鼻子的检测,挺好玩的,具体code:

代码语言:javascript
复制
// face.cpp : Defines the entry point for the console application.
// faceDetection.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/video/video.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"

#include <iostream>
#include <stdio.h>

using namespace std;
using namespace cv;

/** Function Headers */
void detectAndDisplay(Mat frame);

/** Global variables */
// String face_cascade_name = "haarcascade_frontalface_alt.xml";
// String eyes_cascade_name = "haarcascade_eye_tree_eyeglasses.xml";
String face_cascade_name = "F:/opencv/faceDetection/haarcascade_frontalface_alt.xml";
String eyes_cascade_name = "F:/opencv/faceDetection/haarcascade_eye_tree_eyeglasses.xml";
String nose_cascade_name = "F:/opencv/faceDetection/haarcascade_mcs_nose.xml";
CascadeClassifier face_cascade;
CascadeClassifier eyes_cascade;
CascadeClassifier nose_cascade;
String window_name = "Capture - Face detection";

/** @function main */
int main(void)
{
	VideoCapture capture;
	Mat frame;

	//-- 1. Load the cascades
	if (!face_cascade.load(face_cascade_name)){ printf("--(!)Error loading face cascade\n"); return -1; };
	if (!eyes_cascade.load(eyes_cascade_name)){ printf("--(!)Error loading eyes cascade\n"); return -1; };
	if( !nose_cascade.load( nose_cascade_name ) ){ printf("--(!)Error loading nose cascade\n"); return -1; };

	//-- 2. Read the video stream
	capture.open(0);	//-- 如果改为-1会出错!
	if (!capture.isOpened()) { printf("--(!)Error opening video capture\n"); return -1; }

	while (capture.read(frame))
	{
		if (frame.empty())
		{
			printf(" --(!) No captured frame -- Break!");
			break;
		}

		//-- 3. Apply the classifier to the frame
		detectAndDisplay(frame);

		int c = waitKey(10);
		if ((char)c == 27) { break; } // escape
	}
	return 0;
}

/** @function detectAndDisplay */
void detectAndDisplay(Mat frame)
{
	std::vector<Rect> faces;
	Mat frame_gray;

	cvtColor(frame, frame_gray, COLOR_BGR2GRAY);//-- 注意颜色排列顺序是BGR不是RGB
	equalizeHist(frame_gray, frame_gray);

	//-- Detect faces
	face_cascade.detectMultiScale(frame_gray, faces, 1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(30, 30));

	for (size_t i = 0; i < faces.size(); i++)
	{
		Point center(faces[i].x + faces[i].width / 2, faces[i].y + faces[i].height / 2);
		ellipse(frame, center, Size(faces[i].width / 2, faces[i].height / 2), 0, 0, 360, Scalar(255, 0, 255), 4, 8, 0);//-- 用品红色椭圆框出脸

		Mat faceROI = frame_gray(faces[i]);
		std::vector<Rect> eyes;

		//-- In each face, detect eyes
		eyes_cascade.detectMultiScale(faceROI, eyes, 1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(30, 30));

		for (size_t j = 0; j < eyes.size(); j++)
		{
			Point eye_center(faces[i].x + eyes[j].x + eyes[j].width / 2, faces[i].y + eyes[j].y + eyes[j].height / 2);
			int radius = cvRound((eyes[j].width + eyes[j].height)*0.25);
			circle(frame, eye_center, radius, Scalar(255, 0, 0), 4, 8, 0);//-- 蓝色圆框出眼睛
		}

		//-- In each face, detect nose
		std::vector<Rect> nose;
		nose_cascade.detectMultiScale( faceROI, nose, 1.1, 2, 0 |CASCADE_SCALE_IMAGE, Size(30, 30) );

		for ( size_t j = 0; j < nose.size(); j++ )
		{
			Point nose_center( faces[i].x + nose[j].x + nose[j].width/2, faces[i].y + nose[j].y + nose[j].height/2 );
			int radius = cvRound( (nose[j].width + nose[j].height)*0.25 );
			circle( frame, nose_center, radius, Scalar( 0, 255, 0 ), 4, 8, 0 );//-- 蓝色圆框出眼睛
		}
	}
	//-- Show what you got
	imshow(window_name, frame);
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2015-05-10 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档