转:基于开源项目OpenCV的人脸识别Demo版整理(不仅可以识别人脸,还可以识别眼睛鼻子嘴等)【模式识别中的翘楚】
文章来自于:http://blog.renren.com/share/246648717/8171467499
基于开源项目OpenCV的人脸识别Demo版整理(不仅可以识别人脸,还可以识别眼睛鼻子嘴等)【模式识别中的翘楚】作者: 王铎
最近对人脸识别的程序非常感兴趣,但是苦于没有选修多媒体方向,看了几篇关于人脸识别的论文,大概也没看懂多少,什么灰度处理啊,切割识别啊,云里雾里,傻傻看不明白啊。各种苦恼。
于是就在网上找找,看有木有神马开源代码啊,要是有个现成的源码就更好了,百度it ,那些源码都忧伤的躲在CSDN中,老衲还是光头没积分类型的,没有办法,偶尔找几个不用积分的链接吧,妹的,download的好几天,都没下来1K,彻底被打败了。
一狠心一咬牙,自己干了。毛爷爷教育我们说,自己动手,不愁吃喝拉撒睡。于是开始找开源的代码,开始我还天真的寻找Java版的,后来才明白,java的 运算能力根本不被大家认可,像人脸识别这种需要很高运算能力的,需要很高效率的事情,都只有C/C++的。后来就看到了OpenCV这个开源项目,一点一 点开始,终于完成了Demo版本,先晒几张识别的照片,然后再谈谈Demo实现过程。
(本来想用本人靓照,后来想想,怕大家吓怕了不敢继续读下去,还是找明星吧
这是载入图像后再通过图像识别,找到人脸,画出人脸区域的红圈后的效果。
一、OpenCV介绍
OpenCV的全称是Open Source Computer Vision Library,是一个跨平台的计算机视觉库。OpenCV是由英特尔公司发起并参与开发,以BSD许可证授权发行,可以在商业和研究领域中免费使用。OpenCV可用于开发实时的图像处理、计算机视觉以及模式识别程序。
计算机视觉的应用领域越来越广泛,无论从手机应用,行为分析,文字处理还有游戏设计等,在很多地方已经投入了应用生产,而不学一点视觉的东西感觉自己都会落后了,哈哈。目前很多的计算机视觉的软件都有其局限性,成本高,开发周期长,没有固定统一的API设计等等。
OpenCV在Intel公司发起后,不仅在这些问题上给了很多独特的解决方案,同时还可以安装Intel公司的IPP来进行加速处理。作为我们学习,就不必购买IPP,直接使用开源的OpenCV足以解决很多问题。
二、OpenCV安装总结(在Windows环境下,如果需要了解Linux下的安装过程,可以去官方的http://www.opencv.org.cn/forum/寻找解决办法)
1.安装VS2008,相信这个都没问题。VC++2008Express也可以
2.安装OpenCV2.0版本。
这个解释一下啊,现在OpenCV已经出到了2.3版本,但是2.0是目前稳定的最新本,因为OpenCV是开源的项目,在持续的开发中,而2.0网上的介绍大多基于此,新版本的改进还很少详细的介绍。所以2.0已经足够用了。下载地址http://www.opencv.org.cn/index.php/Download
下载后安装,我安装在了D:\Program Files\OpenCV2.0下
3.安装CMake
安装CMakehttp://www.cmake.org/cmake/resources/software.html;
CMake的百科解释:CMake 是个跨平台的自动化建构系统,它用组态档控制建构过程(build process)的方式和 Unix 的 Make 相似,只是 CMake 的组态档取名为 CmakeLists.txt。Cmake 并不直接建构出最终的软件,而是产生标准的建构档(如 Unix 的 Makefile 或 Windows Visual C++ 的 projects/workspaces),然后再依一般的建构方式使用。这使得熟悉某个集成开发环境(IDE)的开发者可以用标准的方式建构他的软件,这种可以使用各平台的原生建构系统的能力是 CMake 和 SCons 等其他类似系统的区别之处。CMake 可以编译源代码、制作程式库、产生适配器(wrapper)、还可以用任意的顺序建构执行档、
我的理解就是CMake是个开源的项目,用于构建源码,但是它构建不生成可用文件,而是按照你喜欢的方式帮你构建源码,构建成特定IDE可用的工程。
一会需要用到它来帮助我们将OpenCV源码编译成VS可用的工程。
4.用CMake导出VC++项目文件
- 运行cmake-gui,设置路径为OpenCV安装路径(本文档假定安装位置为:D:\Program Files\OpenCV2.0),并创建子目录D:\Program Files\OpenCV2.0\vc2008,用于存放编译结果。
- 然后点 configure,在弹出的对话框内选择 Visual Studio 9 2008。
- 如果是VC++2008的Express版本,则不支持OpenMP,所以需要取消ENABLE_OPENMP选项,取消后再次选择“Congfigure”,完成后选择“Generate”。VC++ 2008(不是Express版本)支持OpenMP,如果你使用VC++2008,强烈建议不要取消这个选项。
注意:OpenCV2.1中没有ENABLE_OPENMP选项,在安装VC++2008时可以不管这个选项。
点击看大图 |
点击看大图 |
点击看大图 |
5.编译 OpenCV Debug和Release版本库
完成上一步骤后,将在D:\Program Files\OpenCV2.0\vc2008目录下生成OpenCV.sln的VC Solution File,请用VC++ 2008 Express打开OpenCV.sln,然后执行如下操作:
- 在Debug下,选择Solution Explorer里的 Solution OpenCV,点右键,运行"Rebuild Solution";如编译无错误,再选择INSTALL项目,运行"Build"。
- 在Release下,选择Solution Explorer里的 Solution OpenCV,点右键,运行"Rebuild Solution";如编译无错误,再选择INSTALL项目,运行"Build"。
此时,OpenCV的*d.dll文件(for debug)和*.dll文件(for release)将出现在D:\Program Files\OpenCV2.0\vc2008\bin目录中;OpenCV的*d.lib文件(for debug)和*.lib文件(for release)将出现在D:\Program Files\OpenCV2.0\vc2008\lib目录;头文件*.h出现在D:\Program Files\OpenCV2.0\vc2008\include\opencv中。
可以被VC++ 2008 Express调用的OpenCV动态库生成完毕
点击看大图 |
点击看大图 |
点击看大图 |
点击看大图 |
点击看大图 |
6.配置Windows环境变量Path
将D:\Program Files\OpenCV2.0\vc2008\bin加入Windows系统环境变量Path中。加入后可能需要注销当前Windows用户(或重启)后重新登陆才生效。
点击看大图 |
点击看大图 |
7.为VC++ 2008 Express配置OpenCV环境
打开VC++ 2008 Express,菜单 Tools -> Options -> Projects and Solutions -> VC++ Directories
- Show directories for选择executable files,加入目录 D:\Program Files\OpenCV2.0\vc2008\bin
- Show directories for选择include files,加入目录 D:\Program Files\OpenCV2.0\vc2008\include\opencv
- Show directories for选择library files,加入目录 D:\Program Files\OpenCV2.0\vc2008\lib
关闭VC++ 2008 Express。
点击看大图 |
点击看大图 |
OK,到现在为止呢,我们就配置好了环境可以使用OpenCV来编程,下面将介绍如何使用OpenCV,编写人脸识别的代码。
二、人脸识别程序编写。
1.首先创建一个机遇对话框的MFC工程FaceDetection2。
文件如图:
2.将对话框修改成如图所示
3.按照如下步骤配置用到的lib
- 选择Solution Explorer里的FaceDetection2项目,点击鼠标右键,选择Properties,在[链接器 LINKER]的[输入INPUT]中:
- 为项目的Debug配置增加 [依赖的库 Additional Dependencies]:cxcore200d.lib cv200d.lib highgui200d.lib(注意,文件名cv200d.lib 可能是cv***d.lib等形式,具体应查看D:\Program Files\OpenCV2.0\vc2008\lib。如果使用的是OpenCV2.1,应输入:cxcore210d.lib cv210d.lib highgui210d.lib )
- 为项目的Release配置增加[依赖的库 Additional Dependencies]:cxcore200.lib cv200.lib highgui200.lib (注意:如果使用的是OpenCV2.1,应输入:cxcore210.lib cv210.lib highgui210.lib)
- 在 [配置属性 Configuration Properties]- [General] -[字符集 Character Set] 修改为使用“多字节字符集” (由于2008默认是以Unicode字符集编译的
4.然后编辑FaceDetection2Dlg.cpp文件,源码如下
// FaceDetection2Dlg.cpp : implementation file
//
#include "stdafx.h"
#include "FaceDetection2.h"
#include "FaceDetection2Dlg.h"
#include <string.h>
#include <iostream>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
using namespace std;
const char* cascade_name="haarcascade_frontalface_alt2.xml";//分类器的名称
const char* cascade_name1="haarcascade_eye_tree_eyeglasses.xml";//分类器的名称
const char* cascade_name2="haarcascade_frontalface_alt_tree.xml";//分类器的名称
const char* cascade_name3="haarcascade_mcs_mouth.xml";//分类器的名称
const char* cascade_name4="haarcascade_mcs_nose.xml";//分类器的名称
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
// Implementation
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()
// CFaceDetection2Dlg dialog
CFaceDetection2Dlg::CFaceDetection2Dlg(CWnd* pParent /*=NULL*/)
: CDialog(CFaceDetection2Dlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CFaceDetection2Dlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CFaceDetection2Dlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_BN_CLICKED(ID_FaceDetected, &CFaceDetection2Dlg::OnBnClickedFacedetected)
END_MESSAGE_MAP()
// CFaceDetection2Dlg message handlers
BOOL CFaceDetection2Dlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
return TRUE; // return TRUE unless you set the focus to a control
}
void CFaceDetection2Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CFaceDetection2Dlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this function to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CFaceDetection2Dlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CFaceDetection2Dlg::OnBnClickedFacedetected()
{
// TODO: 在此添加命令处理程序代码
CString fileName;
//打开文件对话窗口
CFileDialog OpenDlg( TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR, L"图像文件格式JPG file format (*.jpg)|*.jpg|(*.bmp) |*.bmp|", NULL);
//从文件对话窗口中打开图像
if(OpenDlg.DoModal()!=IDOK)
return ;
//获得文件名
fileName = OpenDlg.GetPathName();
//必要的类型转换
std::string tempName = (LPCSTR)CStringA(fileName);
const char* tmp = tempName.c_str();
//打开文件,若失败则返回
if((src=cvLoadImage(tmp,CV_LOAD_IMAGE_ANYCOLOR))==0)
return ;
//加载(分类器层叠)训练库
cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name2, 0, 0, 0 );
//加载不成功则显示错误讯息,并退出
if(cascade)
{
storage = cvCreateMemStorage(0);
cvNamedWindow( "人脸检测", CV_WINDOW_AUTOSIZE ); //创建窗口
//如果图片存在则分析并显示结果,否则退出程序
if(src)
detect_and_draw(src);//调用人脸检与标示事件
cvReleaseImage(&src);
cvReleaseMemStorage( &storage );
}else{
AfxMessageBox(L"无法加载分类器,请确认后重试!");
}
cvReleaseHaarClassifierCascade( &cascade );
}
void CFaceDetection2Dlg::detect_and_draw(IplImage *img)
{
static CvScalar color[] = {{0,0,255},{0,128,255},{0,255,255},{0,255,0},{0,128,255},{255,128,0},{255,255,0},{255,0,0},{255,0,255}};//用于设置标示图像中人脸的颜色
double scale = 1.3;
IplImage* gray = cvCreateImage(cvSize(img->width,img->height),8,1);
IplImage* small_img = cvCreateImage( cvSize( cvRound (img->width/scale),cvRound (img->height/scale)),8,1 );
int i;
cvCvtColor( img, gray, CV_BGR2GRAY );
cvResize( gray, small_img, CV_INTER_LINEAR );
cvEqualizeHist( small_img, small_img );
cvClearMemStorage( storage );
if( cascade )
{
//检测人脸
CvSeq* faces = cvHaarDetectObjects( small_img, cascade, storage, 1.1, 2, 0, cvSize(30, 30) );
for( i = 0; i < (faces ? faces->total : 0); i++ )
{
CvRect* r = (CvRect*)cvGetSeqElem( faces, i );
CvPoint center;
int radius;
center.x = cvRound((r->x + r->width*0.5)*scale);
center.y = cvRound((r->y + r->height*0.5)*scale);
radius = cvRound((r->width + r->height)*0.25*scale);
cvCircle( img, center, radius, color[i], 3, 8, 0 );
}
}
cvShowImage( "人脸检测", img );
cvReleaseImage( &gray );
cvReleaseImage( &small_img );
}
其中OnBnClickedFacedetected()为按钮FaceDetect的监听方法
detect_and_draw(IplImage *img)方法用于检测人脸
5.运行观察结果
三、总结
在源码中,
const char* cascade_name="haarcascade_frontalface_alt2.xml";//分类器的名称
const char* cascade_name1="haarcascade_eye_tree_eyeglasses.xml";//分类器的名称
const char* cascade_name2="haarcascade_frontalface_alt_tree.xml";//分类器的名称
const char* cascade_name3="haarcascade_mcs_mouth.xml";//分类器的名称
const char* cascade_name4="haarcascade_mcs_nose.xml";//分类器的名称
这是不同的分类器,你可以在你安装的OpenCV中找到。如D:\Program Files\OpenCV2.0\vs2008\data\haarcascades
不同分类器能够帮助你识别不同的部分,如眼睛,鼻子和嘴,更多的需要自己去探索吧。
求分享求推荐。啊
转:基于开源项目OpenCV的人脸识别Demo版整理(不仅可以识别人脸,还可以识别眼睛鼻子嘴等)【模式识别中的翘楚】的更多相关文章
- 基于开源项目SharpMap的热力图(HeatLayer)实现。
当前公司需要一个用时较少的热力图呈现方案,在避免较底层的GDI开发和比较了多家GIS产品的实际效果之后,团队决定用sharpMap的API来实现,由于之前框架采用的是另外一个开源项目GMap.net, ...
- 活动报名 | 如何基于开源项目 Tapdata PDK,快速完成数据源和目标的开发?
近日,Tapdata 启动 PDK 插件生态共建计划,宣布开源插件开发框架 Tapdata PDK,将自身的数据接口能力开放出来,帮助开发者根据实际需求,自助接入数据源和目标,快速开启「Data ...
- 基于开源项目的在线网络视频直播项目---一个很好的电视直播开源项目Sopcast
http://blog.csdn.net/roy_xu/article/details/2216559 http://115.com/?ct=rar&pickcode=ew52634xr2cr ...
- 基于开源项目的在线网络视频直播项目---pc端的推流
https://github.com/winlinvip/simple-rtmp-server/issues/66 https://github.com/justinmakaila/iOS-Frame ...
- C#开源项目
原文: http://alance.iteye.com/blog/693987 一.AOP框架 Encase 是C#编写开发的为.NET平台提供的AOP框架.Encase 独特的提供了 ...
- 15个具有高度影响力的Apache开源项目
自1999年创立以来,Apache软件基金会如今已成了众多重要的开源软件项目之家.其中成功的项目有Geronimo,有Tomcat,有Hadoop,有如今成了大数据王国关键车毂的分布式计算系统. 虽然 ...
- c#开源项目[转]
一.AOP框架 Encase 是C#编写开发的为.NET平台提供的AOP框架.Encase 独特的提供了把方面(aspects)部署到运行时代码,而其它AOP框架依赖配置文件的方式.这种部署方面(as ...
- 程序员必备,C#各类项目、开源项目插件资料收藏
一.AOP框架 Encase 是C#编写开发的为.NET平台提供的AOP框架.Encase独特的提供了把方面(aspects)部署到运行时代码,而其它AOP框架依赖配置文件的方式.这种部署方面 ...
- Redis开源项目的终极杀手? ——CRUG解读Redis开源协议变更
引言: 数据库制造商 Redis Labs 本周将公司开发的Redis 模块从 AGPL 迁移到将 Apache v2.0 与 Commons Clause 相结合的许可证,对许可证涵盖的软件作了限制 ...
随机推荐
- 查看Linux发行版的名称和版本号
Method #1: /etc/*-release file 在Terminal中执行命令: cat /etc/*-release 我的输出结果: DISTRIB_ID=Ubuntu DISTRIB_ ...
- H - Food - hdu 4292(简单最大流)
题目大意:有N个人,然后有F种食品和D种饮料,每个人都有喜欢的饮料和食品,求出来这些食品最多能满足多少人的需求. 输入描述: 分析:以前是做过类似的题目的,不过输入的信息量比较大,还是使用邻接表的好些 ...
- QFII
QFII(Qualified Foreign Institutional Investors)合格的境外机构投资者的英文简称,中文“酋匪”,QFII机制是指外国专业投资机构到境内投资的资格认定制度. ...
- Demo_敌军坦克生成,坦克移动(可以拓展发射子弹,敌军消失获取分数或者添加动画,声音功能)
using UnityEngine; using System.Collections; public class Tank : MonoBehaviour { //坦克面积结构体对象 public ...
- iOS开发之iPhone通过get和post方式请求asp.net webservice
.创建一个webservice .在webconfig中启用http get 和http post. 复制代码 <</span> webServices > <</ ...
- SKPhysicsJointPin类
继承自 NSObject 符合 NSCoding(SKPhysicsJoint)NSObject(NSObject) 框架 /System/Library/Frameworks/SpriteKit. ...
- java 中读取本地文件中字符
java读取txt文件内容.可以作如下理解: 首先获得一个文件句柄.File file = new File(); file即为文件句柄.两人之间连通电话网络了.接下来可以开始打电话了. 通过这条线路 ...
- IE的CSS相关的BUG(整理一)
本来不想弄这个ie的bug的,真的很想让它快点死掉,可是事与愿违啊,没办法,还是贴出来,以备自用. 这个网页(http://haslayout.net/css/index)上例举了所有的IE和CSS相 ...
- 无限循环的ViewPager
目前情况 在不修改源码的情况下,当ViewPager滑动到最后一个item的时候,他就无法再往右滑动:当ViewPager滑动到第一个item的时候,他也无法再往前滑动.(以上全是废话) 设想 我们可 ...
- Python第一课
一.模块的常用方法 __name__ #主模块name值main __file__ #文件所在的路径+文件名 __doc__ #文件级别的注释 二.函数 参数 参数默认值 可变参数 ...