上优快云很久了,一直也没写过博客,今天开始尝试写。今天先介绍并分享一下我几个月前做过的一个小DEMO,这个例子实现的功能是检测人脸并识别,如果是本人,就打开用户设置的软件,可以是多个软件同时打开,当用户离开电脑后几分钟后,会自动关闭设定了要关闭的软件,保证了用户的个人隐私。
可能大家没太听懂,我举个例子。如果我离开电脑去办点事,电脑检测不到我的存在后会关闭掉我设置好的几个软件,比如说会关到QQ、文档、快播等软件;当我回来后程序会识别我的人脸,确认是我后(准确率在90%以上),会自动打开之前关闭的软件。这个程序是基于苹果的某个较新的专利写的,写的比较简单,主要利用了OpenCV人脸检测识别模块实现,功能比较简单,使用VS2010,opencv2.4.3。下面是实现思路。
人脸识别使用的是createFisherFaceRecognizer();这个是opencv2.x以后新出的类,它的准确率目前看来效果不错,首先得保存照片,最好是10张以上,保存到指定路径,同时在at.txt文档中记下来,并分配一个唯一的ID号,这里的ID号可以按顺序来,这样后面读取的时候就可以得到照片和它的ID号。
有照片后就可以进行训练了,也就是传说中的
try{
facereg.model->train(images, labels);}
catch (cv::Exception& e) {
AfxMessageBox(e.msg.c_str());}
AfxMessageBox("训练成功,以后若仍是您使用便不用重复训练!");
facereg.model->
save("model.xml");
save一下,这样只要没有增加新人,这个model就可以长期使用,因为train速度很慢,所有很有必要进行一下save一劳永逸。
**********************************************************************************************************************************
****************************************************************************************************
顺便提一下,在保存照片时候对路径和各种字符串的折腾还是挺有意思的,比如说:你想说“你的学号为ID,请牢记!”,而这个ID为你计算得到的整数变量。你可以这样来完成这样的功能:
string out="你的学号为";
string out1="请牢记";
int id=10;//假设为10
char char_id[6];
itoa(id,char_id);//数字转化为字符串
out=out+char_id+out1;//string 是不是很简单?
AfxMessageBox(out.c_str());
*************************************************************
****************************************************************
在人脸识别阶段,需要load一下刚才保存的model.xml,这个过程也是挺慢的,可以也没有办法啊。然后就可以进行predict(inputarray);返回predictlable,这个值是保存照片赋值的唯一值,若它和你输入的ID一样说明认证成功,然后才能权限进行一步的工作。为保证准确率,累计三次ID相等才算认证成功。
到了程序自动开关区,首先可以添加要自动打开的程序,需要得到程序的全路径并保存到文档中,同时路径也加到需要关闭程序文档中,这是因为默认认为自动打开的也需要自动关闭,当然可以后面的操作中选择需要自动关闭的程序。选择程序路径代码如下:
ofstream fout2,fout3;
char sint[6];
char szSelected[MAX_PATH];//用来存放文件夹路径
BROWSEINFO bi;
LPITEMIDLIST pidl;
bi.hwndOwner = this->m_hWnd;
bi.pidlRoot = NULL;
bi.pszDisplayName = szSelected;
bi.lpszTitle = "选择输出文件路径";
bi.ulFlags = BIF_BROWSEINCLUDEFILES; //
浏览器将显示目录,同时也显示文件。
BIF_RETURNONLYFSDIRS:仅仅返回文件系统的目录。
bi.lpfn = NULL;
bi.lParam = NULL;
bi.iImage = NULL;
isselect=0;
if((pidl = SHBrowseForFolder(&bi)) != NULL)
{
if(SUCCEEDED(SHGetPathFromIDList(pidl, szSelected)))//得到文件夹的全路径,不要的话,只得本文件夹名
{
m_path = szSelected;
isselect=1;
}
itoa(predictedLabel,sint,10);
string temp=sint;
string temppath="..\\path"+temp+".txt";
string temppath2="..\\path"+temp+"c.txt";
fout2.open(temppath,ios::app);
fout3.open(temppath2,ios::app);
fout2<<m_path<<endl;
fout3<<m_path<<endl;
显示已添加程序用的是一个Edit control,当然可以根据需要加上滚动条啥的,代码如下:
ifstream in;
ofstream out;
char sint[6];
itoa(predictedLabel,sint,10);
string temp=sint;
string temppath="..\\path"+temp+".txt";
in.open(temppath,ios::in);
string s,snext;
while(in>>snext)
{
s=s+snext+"\r\n"; //显示的时候换行
}
ShowpathDlg show;
show.m_pathshow=s.c_str();
UpdateData(FALSE);
show.DoModal();
UpdateData(TRUE);
out.open(temppath,ios::out);
out<<show.m_pathshow<<endl;
in.close();
out.close();
下面是启动自动开关,这里面的算法比较复杂,下面缕一下:
1,首先判断是否进行了身份验证,若没进行则中止,进行探测人脸,若检测到人脸转向2,否则转向5。
2,进行大循环,判断程序是不是第一次打开或者已有程序关闭过,若成立转向3。
3,若是已有程序关闭而不是第一次打开则需要再次进行身份认证,从打开程序文档中依次读取程序路径,判断该程序是否需要自动关闭,方法是该路径字符串和保存自动关闭程序的文档中的所有路径进行比较,若存在说明需要自动关闭。
4,打开刚才路径文档中取出的程序,保存该程序的句柄,并记录该程序是否需要自动关闭。若打开程序文档中仍有程序路径,返到步骤3.
5,进行自动关闭程序操作,判断是否已经打开过程序,若打开过,延迟指定的时间后关闭在步骤3中标记的需要自动关闭的程序。
算法具体细节说明:
1,为了保证不需要自动关闭的程序只被打开一次,设置一个数组,保存那些被关闭的程序的序号,再次检测到人脸的时候只打开这些程序就可以了。
2,在程序运行过程中,只有在程序执行关闭操作后才能进行打开操作,否则循环过程中会重复执行打开操作,办法是设定一个标志isopen,执行打开操作后设置为1,执行关闭操作后设置为0.打开前会判断isopen是否为0。
3,延时指定时间方法,在程序没检测到人脸后就执行,start=cv::getTickCount();,
只执行一次,并now=cv::getTickCount();,这个需要每次循环都执行,double second=((now-start)/cv::getTickFrequency());
if(second>=delay)
{*********
源码下载链接:http://download.youkuaiyun.com/detail/wunghao8/7253359