文章来自于: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版整理(不仅可以识别人脸,还可以识别眼睛鼻子嘴等)【模式识别中的翘楚】的更多相关文章

  1. 基于开源项目SharpMap的热力图(HeatLayer)实现。

    当前公司需要一个用时较少的热力图呈现方案,在避免较底层的GDI开发和比较了多家GIS产品的实际效果之后,团队决定用sharpMap的API来实现,由于之前框架采用的是另外一个开源项目GMap.net, ...

  2. 活动报名 | 如何基于开源项目 Tapdata PDK,快速完成数据源和目标的开发?

      近日,Tapdata 启动 PDK 插件生态共建计划,宣布开源插件开发框架 Tapdata PDK,将自身的数据接口能力开放出来,帮助开发者根据实际需求,自助接入数据源和目标,快速开启「Data ...

  3. 基于开源项目的在线网络视频直播项目---一个很好的电视直播开源项目Sopcast

    http://blog.csdn.net/roy_xu/article/details/2216559 http://115.com/?ct=rar&pickcode=ew52634xr2cr ...

  4. 基于开源项目的在线网络视频直播项目---pc端的推流

    https://github.com/winlinvip/simple-rtmp-server/issues/66 https://github.com/justinmakaila/iOS-Frame ...

  5. C#开源项目

    原文:  http://alance.iteye.com/blog/693987 一.AOP框架        Encase 是C#编写开发的为.NET平台提供的AOP框架.Encase 独特的提供了 ...

  6. 15个具有高度影响力的Apache开源项目

    自1999年创立以来,Apache软件基金会如今已成了众多重要的开源软件项目之家.其中成功的项目有Geronimo,有Tomcat,有Hadoop,有如今成了大数据王国关键车毂的分布式计算系统. 虽然 ...

  7. c#开源项目[转]

    一.AOP框架 Encase 是C#编写开发的为.NET平台提供的AOP框架.Encase 独特的提供了把方面(aspects)部署到运行时代码,而其它AOP框架依赖配置文件的方式.这种部署方面(as ...

  8. 程序员必备,C#各类项目、开源项目插件资料收藏

    一.AOP框架     Encase 是C#编写开发的为.NET平台提供的AOP框架.Encase独特的提供了把方面(aspects)部署到运行时代码,而其它AOP框架依赖配置文件的方式.这种部署方面 ...

  9. Redis开源项目的终极杀手? ——CRUG解读Redis开源协议变更

    引言: 数据库制造商 Redis Labs 本周将公司开发的Redis 模块从 AGPL 迁移到将 Apache v2.0 与 Commons Clause 相结合的许可证,对许可证涵盖的软件作了限制 ...

随机推荐

  1. HDOJ(HDU) 2103 Family planning(需要注意范围)

    Problem Description As far as we known,there are so many people in this world,expecially in china.Bu ...

  2. 《Linear Algebra and Its Applications》-chaper1-向量方程、矩阵方程和线性方程组

    向量: 向量的基本运算:向量的运算最基本的一件事情,就是基于它n个分量上进行,即对于两个分量的向量a = <a1,a2>,b = <b1,b2>,有a + b = <a1 ...

  3. CSAPP:cachelab(1)

    本项目大体上就是要求用C\C++来模拟cpu对cache的访问,然后统计hits.misses和eviction的次数.其实并没有想象中的那么难,感觉完全可以当成一道acm里面的大模拟题..下面就对这 ...

  4. linux关闭防火墙及selinux

    RHEL6.5 查看linux防护墙状态: service iptables status 关闭linux防火墙: 1)永久关闭,重启后生效 开启: chkconfig iptables on 关闭: ...

  5. hyperv虚拟机网络速度慢问题的解决办法

    服务器安装了windows2012R2进行虚拟化,虚拟机也是用的是windows2012R2的操作系统,这样可以一次激活对应的虚拟机. 在使用虚拟机的过程中发现问题,虚拟机主机的网速正常,无论是ftp ...

  6. java—— 调用系统命令

    调用所在环境的命令 链接:http://blog.csdn.net/yy6060/article/details/6311916 1 import java.io.*; 2 class Exec{ 3 ...

  7. (转)Maven实战(七)settings.xml相关配置

    一.简介 settings.xml对于maven来说相当于全局性的配置,用于所有的项目,当Maven运行过程中的各种配置,例如pom.xml,不想绑定到一个固定的project或者要分配给用户时,我们 ...

  8. Android 适配

    给定字体大小适配时应按照12sp,14sp,18sp,22sp 这几种字体的大小设置,以避免字体大小混乱12sp以上大小,14sp 18sp 22sp 字体首选大小,不要使用奇数.小数,否则会造成精度 ...

  9. 微信公众平台java开发具体解释(project代码+解析)

    说明: 本次的教程主要是对微信公众平台开发人员模式的解说,网络上非常多类似文章,但非常多都让初学微信开发的人一头雾水,所以总结自己的微信开发经验,将微信开发的整个过程系统的列出,并对主要代码进行解说分 ...

  10. CentOS 7 安装教程

    参考资料: http://www.cnblogs.com/bobbylinux/articles/centos7.html