您的位置:首页 > 运维架构

opencv学习(十)(opencv3.0.0+VS2012+win7)打开摄像头并且进行人脸识别的例子

2015-08-23 17:15 736 查看
#include "opencv2/objdetect.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
#include <stdio.h>
using namespace std;
using namespace cv;
void detectAndDraw( Mat& img, CascadeClassifier& cascade,CascadeClassifier& nestedCascade,double scale, bool tryflip );
string cascadeName  = "E:/SRT/opencv/opencv/sources/data/haarcascades/haarcascade_frontalface_alt.xml";
string nestedCascadeName= "E:/SRT/opencv/opencv/sources/data/haarcascades/haarcascade_eye_tree_eyeglasses.xml";
int main( int argc, const char** argv )
{
Mat image;//视频流的图像或者图片
bool tryflip = false;//首先不尝试翻转
CascadeClassifier cascade, nestedCascade;//分类器
double scale = 1;//规模=1
if( !cascade.load( cascadeName ) )
{
cerr << "ERROR: Could not load classifier cascade" << endl;
return -1;
}
if( argc ==1 )
{
VideoCapture cap(0);//在<opencv2/highgui/highgui.hpp>中,win7摄像头只能这样打开
if(!cap.isOpened())
{
return -1;
}
// 循环捕捉,直到用户按键跳出循环体
bool stop = false;
while(!stop)
{
cap>>image;
cvNamedWindow( "result", 1 );
if( !image.empty() )
{
detectAndDraw( image, cascade, nestedCascade, scale, tryflip );
}
if(waitKey(30) >=0)
stop = true;
}
}
else
{
image = imread( argv[1], 1 );
cout << "In image read" << endl;
cvNamedWindow( "result", 1 );
if( !image.empty() )
{
detectAndDraw( image, cascade, nestedCascade, scale, tryflip );
waitKey(0);
}
}
cvDestroyWindow("result");
return 0;
}

void detectAndDraw( Mat& img, CascadeClassifier& cascade,CascadeClassifier& nestedCascade,double scale, bool tryflip )
{
int i = 0;
double t = 0;
vector<Rect> faces, faces2;//翻转前的脸face,翻转后的脸face2
const static Scalar colors[] =  {CV_RGB(0,0,255),CV_RGB(0,128,255),CV_RGB(0,255,255),CV_RGB(0,255,0),
CV_RGB(255,128,0),CV_RGB(255,255,0),CV_RGB(255,0,0),CV_RGB(255,0,255)} ;//用于标识人脸的圈圈的颜色
Mat gray, smallImg( cvRound (img.rows/scale), cvRound(img.cols/scale), CV_8UC1 );//cvRound对一个double型的数进行四舍五入,并返回一个整型数
cvtColor( img, gray, COLOR_BGR2GRAY );//变成灰度
resize( gray, smallImg, smallImg.size(), 0, 0, INTER_LINEAR );//双线性插值(默认方法)
equalizeHist( smallImg, smallImg );//使灰度图象直方图均衡化,增强图像的亮度及对比度

t = (double)cvGetTickCount();//得到现在的时间
cascade.detectMultiScale( smallImg, faces,
1.1, 2, 0
//|CASCADE_FIND_BIGGEST_OBJECT
//|CASCADE_DO_ROUGH_SEARCH
|CASCADE_SCALE_IMAGE
,
Size(30, 30) );
if( tryflip )
{
flip(smallImg, smallImg, 1);
cascade.detectMultiScale( smallImg, faces2,
1.1, 2, 0
//|CASCADE_FIND_BIGGEST_OBJECT
//|CASCADE_DO_ROUGH_SEARCH
|CASCADE_SCALE_IMAGE
,
Size(30, 30) );
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\nthe number of faces = %d\n", t/((double)cvGetTickFrequency()*1000.) ,faces.size());
for( vector<Rect>::const_iterator r = faces.begin(); r != faces.end(); r++, i++ )//画圈圈
{
Mat smallImgROI;
vector<Rect> nestedObjects;
Point center;
Scalar color = colors[i%8];
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, 3, 8, 0 );
}
else
rectangle( img, cvPoint(cvRound(r->x*scale), cvRound(r->y*scale)),
cvPoint(cvRound((r->x + r->width-1)*scale), cvRound((r->y + r->height-1)*scale)),
color, 3, 8, 0);
if( nestedCascade.empty() )
continue;
smallImgROI = smallImg(*r);
nestedCascade.detectMultiScale( smallImgROI, nestedObjects,
1.1, 2, 0
//|CASCADE_FIND_BIGGEST_OBJECT
//|CASCADE_DO_ROUGH_SEARCH
//|CASCADE_DO_CANNY_PRUNING
|CASCADE_SCALE_IMAGE
,
Size(30, 30) );
for( vector<Rect>::const_iterator nr = nestedObjects.begin(); nr != nestedObjects.end(); nr++ )
{
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, 3, 8, 0 );
}
}
cv::imshow( "result", img );
}
脸侧着的时候无法识别,而且不能改变分类器,凑合着能用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: