基于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 ...
随机推荐
- 在scratch中怎样编写抓蝴蝶游戏
打开scratch2.0软件,进入工作界面,将语言切换为简体中文:将默认的演员猫删除掉:在新建背景中选择“从背景库中选择背景”: 选择户外,来点一个背景图flower bed,然源后点下面的确定: 背 ...
- 家庭版记账本app进度之关于android界面布局的相关学习
1.线性布局(linearlayout)是一种让视图水平或垂直线性排列的布局线性布局使用<LinearLayout>标签进行配置对应代码中的类是android.widget.LinearL ...
- Scrapy-02-item管道、shell、选择器
Scrapy-02 item管道: scrapy提供了item对象来对爬取的数据进行保存,它的使用方法和字典类似,不过,相比字典,item多了额外的保护机制,可以避免拼写错误和定义字段错误. 创建的i ...
- Quil-delta-enhanced 简介
Quill 是一款时下非常热门的富文本编辑器,它拥有非常强大的扩展能力,可以让开发者根据自己的需要编写插件,使编辑器支持的内容类型更加丰富.它之所以能够拥有这么强大的扩展能力,一方面是因为它的架构和 ...
- 28 api的使用2
本文将讲解如下api的使用: Object.System.Date.DateFormat.Calendar.Integer-- int的包装类等 1. 类 Object 是类层次结构的根类.每个类都使 ...
- nghttp2 交叉编译
touch run.sh chmod 755 run.sh mkdir build cd build ../run.sh run.sh #!/bin/bash #cd build ../configu ...
- 使用Network Emulator Toolkit工具模拟网络丢包测试(上)
弱网络测试包括延时和丢包二种场景下应用的功能是否正常: 网络延时测试使用Fiddler工具控制上下行数据传输延时时间来模拟网络延时场景: 网络丢包测试使用Network Emulator Toolki ...
- Git应用详解第十讲:Git子库:submodule与subtree.md
前言 前情提要:Git应用详解第九讲:Git cherry-pick与Git rebase 一个中大型项目往往会依赖几个模块,git提供了子库的概念.可以将这些子模块存放在不同的仓库中,通过submo ...
- Docker-Bridge Network 03 自定义网络
本节介绍自定义bridge network的自定义网络. 1.前言2.创建自定义网络2.1 创建网络2.2 指定网段创建网络3.创建容器3.1 指定网络创建容器3.2 指定IP创建容器4.通信4.1 ...
- codeforces 122C perfect team
You may have already known that a standard ICPC team consists of exactly three members. The perfect ...