基于opencv的人脸识别程序
1. 解析opencv自带人脸识别源码(……/opencv-3.1.0/samples/cpp/facedetect.cpp)
@ 操作系统:Ubuntu 15.04
OpenCV版本:3.1.0
#include "opencv2/objdetect.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream> using namespace std;
using namespace cv; static void help()
{
cout << "\nThis program demonstrates the cascade recognizer. Now you can use Haar or LBP features.\n"
"This classifier can recognize many kinds of rigid objects, once the appropriate classifier is trained.\n"
"It's most known use is for faces.\n"
"Usage:\n"
"./facedetect [--cascade=<cascade_path> this is the primary trained classifier such as frontal face]\n"
" [--nested-cascade[=nested_cascade_path this an optional secondary classifier such as eyes]]\n"
" [--scale=<image scale greater or equal to 1, try 1.3 for example>]\n"
" [--try-flip]\n"
" [filename|camera_index]\n\n"
"see facedetect.cmd for one call:\n"
"./facedetect --cascade=\"../../data/haarcascades/haarcascade_frontalface_alt.xml\" --nested-cascade=\"../../data/haarcascades/haarcascade_eye_tree_eyeglasses.xml\" --scale=1.3\n\n"
"During execution:\n\tHit any key to quit.\n"
"\tUsing OpenCV version " << CV_VERSION << "\n" << endl;
} void detectAndDraw( Mat& img, CascadeClassifier& cascade,
CascadeClassifier& nestedCascade,
double scale, bool tryflip ); string cascadeName;
string nestedCascadeName; int main( int argc, const char** argv )
{
VideoCapture capture;
Mat frame, image;
string inputName;
bool tryflip; // CascadeClassifier是Opencv中做人脸检测的时候的一个级联分类器,现在有两种选择:一是使用老版本的CvHaarClassifierCascade函数,一是使用新版本的CascadeClassifier类。老版本的分类器只支持类Haar特征,而新版本的分类器既可以使用Haar,也可以使用LBP特征。
CascadeClassifier cascade, nestedCascade;
double scale; cv::CommandLineParser parser(argc, argv,
"{help h||}"
"{cascade|../../data/haarcascades/haarcascade_frontalface_alt.xml|}"
"{nested-cascade|../../data/haarcascades/haarcascade_eye_tree_eyeglasses.xml|}"
"{scale|1|}{try-flip||}{@filename||}"
);
if (parser.has("help"))
{
help();
return ;
} // 问题1:不用定义返回类型?
cascadeName = parser.get<string>("cascade");
nestedCascadeName = parser.get<string>("nested-cascade");
scale = parser.get<double>("scale");
if (scale < )
scale = ;
tryflip = parser.has("try-flip");
inputName = parser.get<string>("@filename");
std::cout << inputName << std::endl; // test
if (!parser.check())
{
parser.printErrors();
return ;
} // 加载模型
if ( !nestedCascade.load( nestedCascadeName ) )
cerr << "WARNING: Could not load classifier cascade for nested objects" << endl;
if( !cascade.load( cascadeName ) )
{
cerr << "ERROR: Could not load classifier cascade" << endl;
help();
return -;
}
// 读取摄像头
// isdigit检测字符是否为阿拉伯数字
if( inputName.empty() || (isdigit(inputName[]) && inputName.size() == ) )
{
int c = inputName.empty() ? : inputName[] - '';
// 此处若系统在虚拟机上,需在虚拟机中设置接管摄像头:虚拟机(M)-> 可移动设备 -> 摄像头名称 -> 连接(断开与主机连接)
if(!capture.open(c))
cout << "Capture from camera #" << c << " didn't work" << endl;
else {
capture.set(CV_CAP_PROP_FRAME_WIDTH, );
capture.set(CV_CAP_PROP_FRAME_HEIGHT, );
}
}
else if( inputName.size() )
{
image = imread( inputName, );
if( image.empty() )
{
if(!capture.open( inputName ))
cout << "Could not read " << inputName << endl;
}
}
else
{
image = imread( "../data/lena.jpg", );
if(image.empty()) cout << "Couldn't read ../data/lena.jpg" << endl;
} if( capture.isOpened() )
{
cout << "Video capturing has been started ..." << endl; for(;;)
{
std::cout << "capturing..." << std::endl; // test
capture >> frame;
if( frame.empty() )
break; Mat frame1 = frame.clone();
std::cout << "Start to detect..." << std::endl; // test
detectAndDraw( frame1, cascade, nestedCascade, scale, tryflip ); int c = waitKey();
if( c == || c == 'q' || c == 'Q' )
break;
}
}
else
{
cout << "Detecting face(s) in " << inputName << endl;
if( !image.empty() )
{
detectAndDraw( image, cascade, nestedCascade, scale, tryflip );
waitKey();
}
else if( !inputName.empty() )
{
/* assume it is a text file containing the
list of the image filenames to be processed - one per line */
FILE* f = fopen( inputName.c_str(), "rt" );
if( f )
{
char buf[+];
while( fgets( buf, , f ) )
{
int len = (int)strlen(buf), c;
while( len > && isspace(buf[len-]) )
len--;
buf[len] = '\0';
cout << "file " << buf << endl;
image = imread( buf, );
if( !image.empty() )
{
detectAndDraw( image, cascade, nestedCascade, scale, tryflip );
c = waitKey();
if( c == || c == 'q' || c == 'Q' )
break;
}
else
{
cerr << "Aw snap, couldn't read image " << buf << endl;
}
}
fclose(f);
}
}
} return ;
} void detectAndDraw( Mat& img, CascadeClassifier& cascade,
CascadeClassifier& nestedCascade,
double scale, bool tryflip )
{
double t = ;
vector<Rect> faces, faces2;
const static Scalar colors[] =
{
Scalar(,,),
Scalar(,,),
Scalar(,,),
Scalar(,,),
Scalar(,,),
Scalar(,,),
Scalar(,,),
Scalar(,,)
};
Mat gray, smallImg; cvtColor( img, gray, COLOR_BGR2GRAY );
double fx = / scale;
resize( gray, smallImg, Size(), fx, fx, INTER_LINEAR );
equalizeHist( smallImg, smallImg ); t = (double)cvGetTickCount();
cascade.detectMultiScale( smallImg, faces,
1.1, ,
//|CASCADE_FIND_BIGGEST_OBJECT
//|CASCADE_DO_ROUGH_SEARCH
|CASCADE_SCALE_IMAGE,
Size(, ) );
if( tryflip )
{
flip(smallImg, smallImg, );
cascade.detectMultiScale( smallImg, faces2,
1.1, ,
//|CASCADE_FIND_BIGGEST_OBJECT
//|CASCADE_DO_ROUGH_SEARCH
|CASCADE_SCALE_IMAGE,
Size(, ) );
for( vector<Rect>::const_iterator r = faces2.begin(); r != faces2.end(); r++ )
{
faces.push_back(Rect(smallImg.cols - r->x - r->width, r->y, r->width, r->height));
}
}
t = (double)cvGetTickCount() - t;
printf( "detection time = %g ms\n", t/((double)cvGetTickFrequency()*.) );
for ( size_t i = ; i < faces.size(); i++ )
{
Rect r = faces[i];
Mat smallImgROI;
vector<Rect> nestedObjects;
Point center;
Scalar color = colors[i%];
int radius; double aspect_ratio = (double)r.width/r.height;
if( 0.75 < aspect_ratio && aspect_ratio < 1.3 )
{
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);
circle( img, center, radius, color, , , );
}
else
rectangle( img, cvPoint(cvRound(r.x*scale), cvRound(r.y*scale)),
cvPoint(cvRound((r.x + r.width-)*scale), cvRound((r.y + r.height-)*scale)),
color, , , );
if( nestedCascade.empty() )
continue;
smallImgROI = smallImg( r );
nestedCascade.detectMultiScale( smallImgROI, nestedObjects,
1.1, ,
//|CASCADE_FIND_BIGGEST_OBJECT
//|CASCADE_DO_ROUGH_SEARCH
//|CASCADE_DO_CANNY_PRUNING
|CASCADE_SCALE_IMAGE,
Size(, ) );
for ( size_t j = ; j < nestedObjects.size(); j++ )
{
Rect nr = nestedObjects[j];
center.x = cvRound((r.x + nr.x + nr.width*0.5)*scale);
center.y = cvRound((r.y + nr.y + nr.height*0.5)*scale);
radius = cvRound((nr.width + nr.height)*0.25*scale);
circle( img, center, radius, color, , , );
}
}
imshow( "result", img );
}
问题未解决:
运行到capture>>frame;时出现select timeout的错误;
@ 操作系统:windows 10
OpenCV版本:3.1.0
代码与Linux版本基本相同,未出现错误;
基于opencv的人脸识别程序的更多相关文章
- 基于 OpenCV 的人脸识别
基于 OpenCV 的人脸识别 一点背景知识 OpenCV 是一个开源的计算机视觉和机器学习库.它包含成千上万优化过的算法,为各种计算机视觉应用提供了一个通用工具包.根据这个项目的关于页面,OpenC ...
- 基于Dlib、OpenCV开发人脸识别程序的开发建议
前言 在去年十月的时候参加了一个小比赛,做了一个人脸识别程序并很意外地获得省里面的一等奖,视频演示链接在这里,有同学想要做这方面的毕业设计or课程设计,发一篇博客来分享一下当时的开发过程. 视频演示链 ...
- java基于OpenCV的人脸识别
基于Java简单的人脸和人眼识别程序 使用这个程序之前必须先安装配置OpenCV详细教程见:https://www.cnblogs.com/prodigal-son/p/12768948.html 注 ...
- 【计算机视觉】基于OpenCV的人脸识别
一点背景知识 OpenCV 是一个开源的计算机视觉和机器学习库.它包含成千上万优化过的算法,为各种计算机视觉应用提供了一个通用工具包.根据这个项目的关于页面,OpenCV 已被广泛运用在各种项目上,从 ...
- 基于OpenCV的人脸识别[iOS开发笔记(2)]
开始了OpenCV的试水工作了... 1.Get ready 在OpenCV中我们会使用函数cv::CascadeClassifier 来进行人脸检测.但是在使用本函数之前我们需要添加一个XML文件对 ...
- python基于OpenCV的人脸识别系统
想获得所有的代码,请下载(来自我的CSDN): https://download.csdn.net/download/qq_40875849/11292912 主函数: from recognitio ...
- java+opencv实现人脸识别程序记录
结果 基本实现了识别的功能.基本的界面如下 界面长得比较丑,主要是JavaSwing写界面比较麻烦,写个菜单栏都要那么多代码.目前不打算改了. 实现的思路是:使用opencv中自带的OpenCVFra ...
- 转:基于开源项目OpenCV的人脸识别Demo版整理(不仅可以识别人脸,还可以识别眼睛鼻子嘴等)【模式识别中的翘楚】
文章来自于:http://blog.renren.com/share/246648717/8171467499 基于开源项目OpenCV的人脸识别Demo版整理(不仅可以识别人脸,还可以识别眼睛鼻子嘴 ...
- 关于运行“基于极限学习机ELM的人脸识别程序”代码犯下的一些错误
代码来源 基于极限学习机ELM的人脸识别程序 感谢文章主的分享 我的环境是 win10 anaconda Command line client (version 1.6.5)(conda 4.3.3 ...
随机推荐
- Golang笔记集
学习Golang了, 下面分享我的, 还有我收集的Golang的学习资料 我的基础笔记地址: https://github.com/zhuchangwu/go-study-notes 其他参考: Go ...
- Scratch 怎么打开SB文件怎么打开
扩展名是.sb( )的文件均可以用匹配版本的scratch或比匹配版本高的scratch打开,列表如下:类型 可打开.sb ···1.4(1.3).sb2 ···2.0.sb3··· 3.0或3.0b ...
- 30.1 HashSet存储自定义对象 未去重解决
问题: package day30_HashSet; import java.util.HashSet; /* * 通过hashset存储自定义对象,没有进行去重. * * */ public cla ...
- C# 基础知识系列- 9 字符串的更多用法(一)
0. 前言 在前面的文章里简单介绍了一下字符串的相关内容,并没有涉及到更多的相关内容,这一篇将尝试讲解一下在实际开发工作中会遇到的字符串的很多操作. 1. 创建一个字符串 这部分介绍一下如何创建一个字 ...
- xargs与exec区别
平时使用find命令查找出文件的时候有时候后面有时候用-exec有时候用管道加xargs,这2个到底有什么不同?下面就这2个的不同做简单介绍. 零.实验环境 [root@osker /]# find ...
- hexo部署在码云中 无样式问题
在本地localhost:4000 运行如下 上传码云之后打开Gitee Pages服务 如下 同时控制台打印 解决方法 找到根目录下的_config.yml中的url 和 root # url: h ...
- OS X10.10.3正式版和Xcode 6.3正式版下载
4.09日,OS X10.10.3 正式版 IOS8.3 正式版和 Xcode 6.3 正式版在今天发布,这是 2015 年里面,IOS 系统和 Mac OS 系统,以及 IOS 和 Mac OS 专 ...
- 【Jenkins】插件更改国内源
最近调试脚本,本机安装了Jenkins,但是安装插件时一直失败.更改升级站点也不生效,究其原因是因为default.json中插件下载地址还https://updates.jenkins.io,升级站 ...
- Pie 杭电1969 二分
My birthday is coming up and traditionally I'm serving pie. Not just one pie, no, I have a number N ...
- div3--C. Pipes
题目链接:https://codeforces.com/contest/1234/problem/C 题目大意:根据规则,判断是否可以从左上走到右下,1,2,3,4,5,6分别对应题干给的图片,所以1 ...