OpenCV学习笔记之人脸检测的代码分析
- 格式:doc
- 大小:50.00 KB
- 文档页数:9
关于Opencv实现人脸检测的阐述最近用Opencv开发一个人脸检测的小程序,结构并不复杂,但对于Opencv初学者来说还是具有一定的引导意义。
接下来对于程序开发中出现的一些问题进行简单讨论。
一、图像采集。
图像既可以从摄像头设备中读取,也可以从磁盘中加载,两者方法大同小异。
以摄像头为例,Opencv对于摄像头的操作同matlab中一样,是通过一个简单的API 函数实现的,具体如下:CvCapture* m_pCapture;m_pCapture = cvCreateCameraCapture(0);IplImage* m_pFrameImage;m_pFrameImage = cvQueryFrame(m_pCapture);首先是创建一个视频流结构体指针m_pCapture,之后调用cvCreateCameraCapture(0)函数将结构体与相应视频输入设备关联,若只有一个视频输入设备(如笔记本摄像头),建议参数给0,若有多个视频设备则应给对应的ID号。
关联完成后,调用cvQueryFrame(m_pCapture);得到m_pCapture结构体中视频流的下一帧图像,存储在图像指针对应的区域,至此,完成摄像头图像采集。
从磁盘中读取图像过程相对复杂一点,需要用到MFC中关于文件及文件夹读取的知识。
具体讲用两条途径,一是定位指定文件夹,继而读取文件夹下的所有图像文件;二是直接定位文件,继而读取相应文件。
读取文件夹的具体代码如下:BROWSEINFO bi;//用来存储用户选中的目录信息TCHAR name[MAX_PATH];//存储路径name[0]='d';ZeroMemory(&bi,sizeof(BROWSEINFO));//清空目录对应的内存bi.hwndOwner=GetSafeHwnd();//得到窗口句柄bi.pszDisplayName=name;BIF_BROWSEINCLUDEFILES;//这句话是什么意思bi.lpszTitle=_T("Select folder");//对话框标题bi.ulFlags=0x80;//设置对话框形式LPITEMIDLIST idl=SHBrowseForFolder(&bi);//返回所选中文件夹的IDif(idl==NULL)return;SHGetPathFromIDList(idl,str.GetBuffer(MAX_PATH));//将文件信息格式化存储到对应缓冲区中str.ReleaseBuffer();//与GerBuffer配合使用,清空内存m_Path=str;//将路径存储在m_path中if(str.GetAt(str.GetLength()-1)!='\\')m_Path+="\\";UpdateData(FALSE);文件夹读取过程中关键函数为SHBrowseForFolder,这个函数有什么样作用以及具体用法网上都有具体的帖子和博客进行说明,这里不做赘述,最终文件夹路径存储在变量m_Path中。
opencv 人脸识别源代码分享
对人类来说,人脸识别很容易仅仅是才三天的婴儿已经可以区分周围
熟悉的人脸了。
那幺对于计算机来说,到底有多难?其实,迄今为止,我们
对于人类自己为何可以区分不同的人所知甚少。
是人脸内部特征(眼睛、鼻
子、嘴巴)还是外部特征(头型、发际线)对于人类识别更有效?
自动人脸识别就是如何从一幅图像中提取有意义的特征,把它们放入
一种有用的表示方式,然后对他们进行一些分类。
基于几何特征的人脸的人
脸识别可能是最直观的方法来识别人脸。
人脸识别的第一步,就是人脸检测。
把人的脸部从一张照片中用计算
机自动识别出来,作为下一步人脸识别的基础。
在opencv 中,库中自带了一个利用harr 特征的人脸检测训练及检测
函数:cvHaarDetectObjects。
它利用训练好的检测器,在图片中间检测你想要的物体,如人脸。
opencv 自带了很多检测器,在%opencv%data/haarcascades 目录下,你可以随意取用。
或者你也可以自己用图片训练自己的检测器,之
后拿来使用。
OpenCV实现⼈脸检测功能本⽂实例为⼤家分享了OpenCV实现⼈脸检测功能的具体代码,供⼤家参考,具体内容如下1、HAAR级联检测#include <opencv2/opencv.hpp>#include <iostream>using namespace cv;#include <iostream>#include <cstdlib>using namespace std;int main(int artc, char** argv) {face_detect_haar();waitKey(0);return 0;}void face_detect_haar() {CascadeClassifier faceDetector;std::string haar_data_file = "./models/haarcascades/haarcascade_frontalface_alt_tree.xml";faceDetector.load(haar_data_file);vector<Rect> faces;//VideoCapture capture(0);VideoCapture capture("./video/test.mp4");Mat frame, gray;int count=0;while (capture.read(frame)) {int64 start = getTickCount();if (frame.empty()){break;}// ⽔平镜像调整// flip(frame, frame, 1);imshow("input", frame);if (frame.channels() == 4)cvtColor(frame, frame, COLOR_BGRA2BGR);cvtColor(frame, gray, COLOR_BGR2GRAY);equalizeHist(gray, gray);faceDetector.detectMultiScale(gray, faces, 1.2, 1, 0, Size(30, 30), Size(400, 400));for (size_t t = 0; t < faces.size(); t++) {count++;rectangle(frame, faces[t], Scalar(0, 255, 0), 2, 8, 0);}float fps = getTickFrequency() / (getTickCount() - start);ostringstream ss;ss.str("");ss << "FPS: " << fps << " ; inference time: " << time << " ms";putText(frame, ss.str(), Point(20, 20), 0, 0.75, Scalar(0, 0, 255), 2, 8);imshow("haar_face_detection", frame);if (waitKey(1) >= 0) break;}printf("total face: %d\n", count);}2、 DNN⼈脸检测#include <opencv2/dnn.hpp>#include <opencv2/opencv.hpp>using namespace cv;using namespace cv::dnn;#include <iostream>#include <cstdlib>using namespace std;const size_t inWidth = 300;const size_t inHeight = 300;const double inScaleFactor = 1.0;const Scalar meanVal(104.0, 177.0, 123.0);const float confidenceThreshold = 0.7;void face_detect_dnn();void mtcnn_demo();int main(int argc, char** argv){face_detect_dnn();waitKey(0);return 0;}void face_detect_dnn() {//这⾥采⽤tensorflow模型std::string modelBinary = "./models/dnn/face_detector/opencv_face_detector_uint8.pb"; std::string modelDesc = "./models/dnn/face_detector/opencv_face_detector.pbtxt";// 初始化⽹络dnn::Net net = readNetFromTensorflow(modelBinary, modelDesc);net.setPreferableBackend(DNN_BACKEND_OPENCV);net.setPreferableTarget(DNN_TARGET_CPU);if (net.empty()){printf("Load models fail...\n");return;}// 打开摄像头// VideoCapture capture(0);VideoCapture capture("./video/test.mp4");if (!capture.isOpened()) {printf("Don't find video...\n");return;}Mat frame;int count=0;while (capture.read(frame)) {int64 start = getTickCount();if (frame.empty()){break;}// ⽔平镜像调整// flip(frame, frame, 1);imshow("input", frame);if (frame.channels() == 4)cvtColor(frame, frame, COLOR_BGRA2BGR);// 输⼊数据调整Mat inputBlob = blobFromImage(frame, inScaleFactor,Size(inWidth, inHeight), meanVal, false, false);net.setInput(inputBlob, "data");// ⼈脸检测Mat detection = net.forward("detection_out");vector<double> layersTimings;double freq = getTickFrequency() / 1000;double time = net.getPerfProfile(layersTimings) / freq;Mat detectionMat(detection.size[2], detection.size[3], CV_32F, detection.ptr<float>()); ostringstream ss;for (int i = 0; i < detectionMat.rows; i++){// 置信度 0~1之间float confidence = detectionMat.at<float>(i, 2);if (confidence > confidenceThreshold){count++;int xLeftBottom = static_cast<int>(detectionMat.at<float>(i, 3) * frame.cols);int yLeftBottom = static_cast<int>(detectionMat.at<float>(i, 4) * frame.rows);int xRightTop = static_cast<int>(detectionMat.at<float>(i, 5) * frame.cols);int yRightTop = static_cast<int>(detectionMat.at<float>(i, 6) * frame.rows);Rect object((int)xLeftBottom, (int)yLeftBottom,(int)(xRightTop - xLeftBottom),(int)(yRightTop - yLeftBottom));rectangle(frame, object, Scalar(0, 255, 0));ss << confidence;std::string conf(ss.str());std::string label = "Face: " + conf;int baseLine = 0;Size labelSize = getTextSize(label, FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);rectangle(frame, Rect(Point(xLeftBottom, yLeftBottom - labelSize.height),Size(labelSize.width, labelSize.height + baseLine)),Scalar(255, 255, 255), FILLED);putText(frame, label, Point(xLeftBottom, yLeftBottom),FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 0, 0));}}float fps = getTickFrequency() / (getTickCount() - start);ss.str("");ss << "FPS: " << fps << " ; inference time: " << time << " ms";putText(frame, ss.str(), Point(20, 20), 0, 0.75, Scalar(0, 0, 255), 2, 8);imshow("dnn_face_detection", frame);if (waitKey(1) >= 0) break;}printf("total face: %d\n", count);}以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。
In [1]:from imutils import*In [2]:image = imread('face.png')show(image)1. image:输入图像2. scaleFactor=1.1:这个是每次缩小图像的比例,默认是1.13. minNeighbors=3:匹配成功所需要的周围矩形框的数目,每一个特征匹配到的区域都是一个矩形框,只有多个矩形框同时存在的时候,才认为是匹配成功,比如人脸,这个默认值是3。
4. minSize:匹配人脸的最小范围5. flags=0:可以取如下这些值:CASCADE_DO_CANNY_PRUNING=1, 利用canny边缘检测来排除一些边缘很少或者很多的图像区域CASCADE_SCALE_IMAGE=2, 正常比例检测CASCADE_FIND_BIGGEST_OBJECT=4, 只检测最大的物体CASCADE_DO_ROUGH_SEARCH=8 初略的检测In [3]:# 级联分类器detector = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")rects = detector.detectMultiScale(image, scaleFactor=1.1, minNeighbors=2, minSize=(10, 10), flags=cv for (x,y,w,h) in rects:# 画矩形框cv2.rectangle(image, (x,y), (x+w,y+h), (0,255,0), 2)show(image)In [4]:def facedetect(image):image = imread(image)# 级联分类器detector = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")rects = detector.detectMultiScale(image, scaleFactor=1.1, minNeighbors=2, minSize=(10, 10), flag for (x,y,w,h) in rects:# 画矩形框cv2.rectangle(image, (x,y), (x+w,y+h), (0,255,0), 2)show(image)In [5]:facedetect('Solvay.jpg')In [ ]:。
OpenCV学习笔记人脸检测的代码分析一、预备知识:1、动态内存存储及操作函数CvMemStoragetypedef struct CvMemStorage{struct CvMemBlock* bottom;/* first allocated block */struct CvMemBlock* top; /* the current memory block - top of the stack */struct CvMemStorage* parent; /* borrows new blocks from */int block_size; /* block size */int free_space; /* free space in the top block (in bytes) */} CvMemStorage;内存存储器是一个可用来存储诸如序列,轮廓,图形,子划分等动态增长数据结构的底层结构。
它是由一系列以同等大小的内存块构成,呈列表型---bottom 域指的是列首,top 域指的是当前指向的块但未必是列尾.在bottom和top之间所有的块(包括bottom, 不包括top)被完全占据了空间;在top和列尾之间所有的块(包括块尾,不包括top)则是空的;而top 块本身则被占据了部分空间-- free_space 指的是top块剩余的空字节数。
新分配的内存缓冲区(或显示的通过cvMemStorageAlloc 函数分配,或隐示的通过cvSeqPush, cvGraphAddEdge等高级函数分配)总是起始于当前块(即top块)的剩余那部分,如果剩余那部分能满足要求(够分配的大小)。
分配后,free_space 就减少了新分配的那部分内存大小,外加一些用来保存适当列型的附加大小。
当top块的剩余空间无法满足被分配的块(缓冲区)大小时,top块的下一个存储块被置为当前块(新的top块)-- free_space 被置为先前分配的整个块的大小。
#include "cv.h"#include "highgui.h"#include <stdio.h>#ifdef _EiC#define WIN32#endifstatic CvMemStorage* storage = 0;static CvHaarClassifierCascade* cascade = 0;void detect_and_draw( IplImage* image );const char* cascade_name ="haarcascade_frontalface_alt.xml";//人脸检测分类器int main( int argc, char** argv ){CvCapture* capture = 0;IplImage *frame, *frame_copy = 0;int optlen = strlen("--cascade=");const char* input_name;if( argc > 1 && strncmp( argv[1], "--cascade=", optlen ) == 0 ){cascade_name = argv[1] + optlen;input_name = argc > 2 ? argv[2] : 0;}else{cascade_name = "E:\毕业设计\智能机器人动态人脸识别系统\陈建州程序.xml";//分类器路径input_name = argc > 1 ? argv[1] : 0;}cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 );if( !cascade )//如果没有找到分类器,输出以下{fprintf( stderr, "ERROR: Could not load classifier cascade\n" );fprintf( stderr,"Usage: facedetect --cascade=\"<cascade_path>\" [filename|camera_index]\n" );return -1;}storage = cvCreateMemStorage(0);capture = cvCaptureFromCAM( !input_name ? 0 : input_name[0] - '0' );//读取摄像头if(!capture)//如果没有摄像头读取视频文件capture = cvCaptureFromA VI("检测.avi");cvNamedWindow( "result", 1);//创建窗口if( capture ){for(;;){if( !cvGrabFrame( capture ))//从摄像头中抓取帧break;frame = cvRetrieveFrame( capture );//读取上边抓取的帧if( !frame )break;if( !frame_copy )frame_copy = cvCreateImage( cvSize(frame->width,frame->height),IPL_DEPTH_8U, frame->nChannels );if( frame->origin == IPL_ORIGIN_TL )cvCopy( frame, frame_copy, 0 );elsecvFlip( frame, frame_copy, 0 );detect_and_draw( frame_copy );if( cvWaitKey( 10 ) >= 0 )break;}cvReleaseImage( &frame_copy );cvReleaseCapture( &capture );}else//没检测到视频文件或者摄像头{const char* filename = (char*)"检测.jpg";//读图片IplImage* image = cvLoadImage( filename, 1 );if( image ){detect_and_draw( image );cvWaitKey(0);cvReleaseImage( &image );}else{FILE* f = fopen( filename, "rt" );if( f ){char buf[1000+1];while( fgets( buf, 1000, f ) ){int len = (int)strlen(buf);while( len > 0 && isspace(buf[len-1]) )len--;buf[len] = '\0';image = cvLoadImage( buf, 1 );if( image ){detect_and_draw( image );cvWaitKey(0);cvReleaseImage( &image );}}fclose(f);}}}cvDestroyWindow("result");return 0;}void detect_and_draw( IplImage* img ){static CvScalar colors[] ={{{0,0,255}},{{0,128,255}},{{0,255,255}},{{0,255,0}},{{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 ){double t = (double)cvGetTickCount();CvSeq* faces = cvHaarDetectObjects( small_img, cascade, storage,1.1, 2, 0/*CV_HAAR_DO_CANNY_PRUNING*/,cvSize(30, 30) );//检测人脸返回矩形人脸t = (double)cvGetTickCount() - t;printf( "detection time = %gms\n", t/((double)cvGetTickFrequency()*1000.) );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, colors[i%8], 3, 8, 0 );}}cvShowImage( "result", img );cvReleaseImage( &gray );cvReleaseImage( &small_img );}OpenCV的人脸检测主要是调用训练好的cascade(Haar分类器)来进行模式匹配。
opencv python 人脸detectmultiscale 参数在Python中使用OpenCV库进行人脸检测时,`detectMultiScale`函数是一个常用的方法。
这个函数可以从图像中检测出多个人脸,并返回每个脸部的位置和大小。
函数的基本用法如下:```pythonimport cv2# 加载Haar分类器face_cascade = cv2.CascadeClassifier('/path/to/haarcascade_frontalface_default.xml')# 读取图像img = cv2.imread('path/to/image.jpg')# 将图像转换为灰度图gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 调用detectMultiScale函数检测人脸faces = face_cascade.detectMultiScale(gray,scaleFactor=1.1,minNeighbors=5,minSize=(30, 30),flags=cv2.CASCADE_SCALE_IMAGE)# 打印检测到的人脸数量print("Detected {0} faces!".format(len(faces)))# 循环遍历检测到的人脸for (x, y, w, h) in faces:# 绘制人脸矩形cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2)# 显示图像cv2.imshow('img', img)cv2.waitKey()```函数`detectMultiScale`的参数意义如下:- `gray`:必须是灰度图像。
- `scaleFactor`:图像缩放比例,用来调整检测人脸的大小,默认为1.1。
基于OpenCV的人脸识别技术研究与实现(C语言)一、引言人脸识别技术是近年来备受关注的领域之一,随着计算机视觉和人工智能的发展,人脸识别技术在各个领域得到了广泛的应用。
本文将重点介绍基于OpenCV库的人脸识别技术研究与实现,使用C语言进行编程实现。
二、OpenCV简介OpenCV是一个开源的计算机视觉库,提供了丰富的图像处理和计算机视觉算法。
它支持多种编程语言,包括C++、Python等。
在本文中,我们将使用C语言结合OpenCV库来实现人脸识别技术。
三、人脸检测人脸检测是人脸识别技术的第一步,通过检测输入图像中的人脸位置来进行后续的识别工作。
OpenCV提供了Haar级联分类器来进行人脸检测,我们可以利用该分类器来实现简单而有效的人脸检测功能。
四、人脸特征提取在进行人脸识别之前,需要对检测到的人脸进行特征提取。
常用的方法包括主成分分析(PCA)和线性判别分析(LDA)等。
通过提取人脸的特征向量,可以将其表示为一个高维向量,便于后续的比对和识别。
五、人脸识别算法在得到人脸特征向量后,我们可以使用不同的算法来进行人脸识别。
常见的算法包括最近邻算法(KNN)、支持向量机(SVM)和深度学习方法等。
这些算法可以根据实际需求选择合适的模型进行训练和测试。
六、实验设计与实现在本节中,我们将介绍如何使用OpenCV库和C语言来实现基于人脸识别技术的实验。
首先,我们需要准备训练数据集和测试数据集,并对数据集进行预处理和特征提取。
然后,我们可以选择合适的算法模型进行训练,并对测试数据集进行验证和评估。
七、实验结果与分析通过实验我们可以得到不同算法在人脸识别任务上的表现结果,并对比它们的准确率、召回率等指标。
通过分析实验结果,可以帮助我们选择最适合当前任务需求的人脸识别算法,并对其性能进行优化和改进。
八、应用与展望人脸识别技术在安防监控、人机交互、身份认证等领域有着广泛的应用前景。
未来随着技术的不断发展,人脸识别技术将会变得更加智能化和便捷化,为社会生活带来更多便利。
1. 打开Microsoft Visual Studio 2008,新建一个Win32控制台项目;控制台项目; 2. 配置好项目的包含文件和库文件;配置好项目的包含文件和库文件;3. 将…………\OpenCV\data\haarcascades\OpenCV\data\haarcascades 中的haarcascade_frontalface_alt.xml 拷贝到所建项目的文件夹中;文件夹中;4. 然后添加代码:然后添加代码:#include "stdafx.h"#include "cv.h"#include "highgui.h"#include <stdio.h>int _tmain _tmain((int argc argc, , _TCHAR _TCHAR* * argv argv[]) []){CvCapture CvCapture* * capture capture=0; =0;/*初始化一个视频捕获操作。
告诉底层的捕获api 我想从Capture1.avi 中捕获图片,底层底层api 将检测并选择相应的解码器并做好准备工作*/capture capture = = c vCaptureFromFile cvCaptureFromFile cvCaptureFromFile( ( "F:\\1.avi"); ////设置要读的视频(avi 格式)static CvMemStorage CvMemStorage* * storage storage = 0; = 0;static CvHaarClassifierCascade CvHaarClassifierCascade* * cascade cascade = 0; = 0;cascade cascade = ( = (CvHaarClassifierCascade CvHaarClassifierCascade*)*)*)cvLoad cvLoad cvLoad(("haarcascade_frontalface_alt.xml",0,0,0);if ( !c ascade cascade cascade || ! || !capture capture ) )return -1;storage storage = = c vCreateMemStorage cvCreateMemStorage cvCreateMemStorage(0); (0);/*创建一个窗口,用“Video ”作为窗口的标识符*/cvNamedWindow cvNamedWindow( ( "Video",1);/*如果初始化失败,那么capture 为空指针,程序停止,否则进入捕获循环*/if ( capture capture ) ){for (;;){IplImage IplImage* * frame frame = = c vQueryFrame cvQueryFrame cvQueryFrame( ( capture capture ); );IplImage IplImage* * img img = = N ULL NULL NULL; ;CvSeq CvSeq* * faces faces; ;if ( !f rame frame frame ) )break ; img img = = c vCloneImage cvCloneImage cvCloneImage((frame frame); );img img->->->origin origin origin = 0; = 0; if ( frame frame->->->origin origin origin ) ) cvFlip cvFlip((img img,,img img); );cvClearMemStorage cvClearMemStorage( ( storage storage ); );//目标检测faces faces = = c vHaarDetectObjects cvHaarDetectObjects cvHaarDetectObjects( ( img img, , cascade cascade, , storage storage,1.1, 2, ,1.1, 2, CV_HAAR_DO_CANNY_PRUNING CV_HAAR_DO_CANNY_PRUNING, , cvSize cvSize(20, 20) ); (20, 20) ); for ( int i = 0; i < (faces faces ? ? f aces faces faces->->->total total total : 0); : 0); i ++ ) { CvRect CvRect* * r = (CvRect CvRect*)*)*)cvGetSeqElem cvGetSeqElem cvGetSeqElem( ( faces faces, , i ); cvRectangle cvRectangle( ( img img, , cvPoint cvPoint((r ->->x x ,r ->->y y ), cvPoint cvPoint((r ->->x x +r ->->width width width,,r ->->y y +r ->->height height height), ), CV_RGB CV_RGB(255,0,0), 1); (255,0,0), 1); } cvShowImage cvShowImage( ( "Video", img img ); ); //设置每帧图像的间隔 Sleep Sleep(50); (50); /*如果你敲了键盘,就退出程序,否则继续捕获下一帧*/ if ( cvWaitKey cvWaitKey(10)>0 ) (10)>0 ) break ; } /*退出之前结束底层api 的捕获操作,比如会使得别的程序无法访问已经被它们打开的文件*/ cvReleaseCapture cvReleaseCapture( &( &c apture capture capture); ); } /*销毁窗口*/ cvDestroyWindow cvDestroyWindow(("Video"); return 0; }。
1.利用OpenCV进行人脸检测
人脸检测程序主要完成3部分功能,即加载分类器、加载待检测图象以及检测并标示;本程序使用OpenCV中提供的“haarcascade_frontalface_alt.xml”文件存储的目标检测分类,用cvLoad函数载入后,进行强制类型转换;OpenCV中提供的用于检测图像中目标的函数是cvHaarDetectObjects,该函数使用指针对某目标物体如人脸训练的级联分类器在图象中找到包含目标物体的矩形区域,并将这些区域作为一序列的矩形框返回;分类器在使用后需要被显式释放,所用的函数为cvReleaseHaarCla ssifierCascade;这些函数原型请参看有关OpenCV手册;
2.程序实现
1新建一个VisualC++MFC项目,取名为“FaceDetection”,选择应用程序类型为“单文档”;将菜单中多余的项去掉,并添加一项“人脸检测”,其ID为“ID_FaceDe tected”,并生成该菜单项的消息映射函数;
2在“FaceDetectionView.h”头文件中添加以下灰底色部分程序代码:
3在“FaceDetectionView.cpp”文件中添加以下灰底色部分程序代码:
需要注意的是,本程序运行时应将分类器文件置于程序目录下,如果运行的是生成的EXE文件,则应将分类器文件与该EXE文件放在同一个目录下;
三、程序运行结果
运行该程序,选择人脸检测菜单项,弹出文件打开对话框,选择要检测的图像文件,程序就会将检测到的人脸用圆圈标示出来,如图3所示;本程序能顺利检测出大部分人脸,但由于光照、遮挡和倾斜等原因,部分人脸不能正确检测,另外,也有一些非人脸部分由于具有人脸的某些特征,也被当成了人脸,这些都是本程序需要改进的部分;。
/* cascade or tree of stage classifiers */int flags; /* signature */int count; /* number of stages */CvSize orig_window_size; /* original object size (the cascade is trained for) *//* these two parameters are set by cvSetImagesForHaarClassifierCascade */CvSize real_window_size; /* current object size */double scale; /* current scale */CvHaarStageClassifier* stage_classifier; /* array of stage classifiers */ CvHidHaarClassifierCascade* hid_cascade; /* hidden optimized representation of the cascade, created by cvSetImagesForHaarClassifierCascade */所有的结构都代表一个级联boosted Haar分类器。
级联有下面的等级结构:Cascade:Stage1:Classifier11:Feature11Classifier12:Feature12...Stage2:Classifier21:Feature21......全部等级可以手农构修,也可以应用函数cvLoadHaarClassifierCascade从已有的磁盘文件或嵌进式基中导进。
特征检测用到的函数:cvLoadHaarClassifierCascade从文件中装载练习佳的级联分类器或者从OpenCV中嵌入的分类器数据库中导入CvHaarClassifierCascade* cvLoadHaarClassifierCascade(const char* directory,CvSize orig_window_size );directory :练习的级联分类器的门路orig_window_size:级联分类器训练中采取的检测目标的尺寸。
由于这个信息没有在级联分类器中存储,所有要共同指出。
函数cvLoadHaarClassifierCascade 用于从文件中装载训练赖的利用海尔特点的级联分类器,或者从OpenCV中嵌入的分类器数据库中导入。
分类器的训练可以利用函数haartraining(具体观察opencv/apps/haartraining)函数已经过期了。
当初的目标检测分类器通常存储在XML 或YAML 文件中,而不是通过路径导入。
从文件中导入分类器,可以使用函数cvLoad 。
cvReleaseHaarClassifierCascade释放haar classifier cascade。
void cvReleaseHaarClassifierCascade( CvHaarClassifierCascade** cascade );cascade :单指针类型指针指向要释放的cascade. 指针由函数申明。
函数cvReleaseHaarClassifierCascade 开释cascade的动态内存,其中cascade的动态内存或者是手工创立,或者通过函数cvLoadHaarClassifierCascade 或cvLoad分配。
cvHaarDetectObjects检测图像中的目标typedef struct CvAvgComp{CvRect rect; /* bounding rectangle for the object (average rectangle of a group) */int neighbors; /* number of neighbor rectangles in the group */}CvAvgComp;CvSeq* cvHaarDetectObjects( const CvArr* image,CvHaarClassifierCascade* cascade,CvMemStorage* storage,double scale_factor=1.1,int min_neighbors=3, int flags=0,CvSize min_size=cvSize(0,【强】看看牛人是怎样用4句话来概括四大名著的!!!,0) );image 被检图像cascade harr 分类器级联的内部标识情势storage 用来存储检测到的一序列候选目的矩形框的内存区域。
scale_factor 在前后两次接踵的扫描中,搜索窗口的比例系数。
例如1.1指将搜索窗口顺次扩展10%。
min_neighbors 构成检测目标的相邻矩形的最小个数(缺费-1)。
如果组成检测目标的小矩形的个数和小于min_neighbors-1 都会被消除。
如果min_neighbors 为0, 则函数不干免何操作就返回所有的被检候选矩形框,这种设定值普通用在用户自定义对检测成果的组折程序上。
flags 操作方法。
当前独一能够定义的操作方法是CV_HAAR_DO_CANNY_PRUNING,未满18别入,入了也看不懂。
假如被设定,函数应用Canny边沿检测器来消除一些边沿很少或者良多的图像区域,由于这样的区域个别不露被检目的。
己脸检测中通过设定阈值应用了这种方式,并因而进步了检测快度。
min_size 检测窗口的最小尺寸。
缺省的情形下被设为分类器训练时采取的样利尺寸(我脸检测中缺省大小是~20×20)。
函数cvHaarDetectObjects 使用针对某目标物体练习的级联分类器在图像中找到包括目标物体的矩形区域,并且将这些区域作为一序列的矩形框返回。
函数以不同比例大小的扫描窗口对图像进行几回搜寻(观察cvSetImagesForHaarClassifierCascade)。
每次都要对图像中的这些重叠区域利用cvRunHaarClassifierCascade进行检测。
有时候也会利用某些继续(heuristics)技巧以减少剖析的候选区域,例如利用Canny 裁减(prunning)方式。
函数在处置和发集到候选的方框(全体通过级联分类器各层的区域)之后,接着对这些区域进行组合并且返回一系列各个脚够大的组合中的均匀矩形。
调节程序中的缺省参数(scale_factor=1.1, min_neighbors=3, flags=0)用于对目标进行更准确同时也是耗时较长的进一步检测。
为了能对视频图像进行更钝的名时检测,参数设置通常是:scale_factor=1.2, min_neighbors=2, flags=CV_HAAR_DO_CANNY_PRUNING, min_size=<minimum possible face size> (例如, 对视频会议的图像区域).cvSetImagesForHaarClassifierCascade为暗藏的cascade(hidden cascade)指定图像void cvSetImagesForHaarClassifierCascade( CvHaarClassifierCascade* cascade,const CvArr* sum, const CvArr* sqsum,const CvArr* tilted_sum, double scale );cascade 暗藏Harr 分类器级联(Hidden Haar classifier cascade), 由函数cvCreateHidHaarClassifierCascade天生sum 32-比特,单通谈图像的积分图像(Integral (sum) 单通说image of 32-比特integer format). 这幅图像以及随后的二幅用于对疾速特点的评估和明度/对照度的回一化。
它们皆可以利用函数cvIntegral从8-比特或浮点数单通路的输进图像中得到。
sqsum 单通讲64比特图像的平方和图像tilted_sum 单通叙32比特整数格局的图像的倾斜和(Tilted sum)scale cascade的窗口比例. 如果scale=1, 就只用原始窗口尺寸检测(只检测同样尺寸大小的目标物体) - 原始窗口尺寸在函数cvLoadHaarClassifierCascade中定义(在"<default_face_cascade>"中缺省为24x24), 如果scale=2, 使用的窗口是上面的两倍(在face cascade中缺省值是48x48 )。
这样只管可以将检测速度进步四倍,但同时尺寸小于48x48的人脸将不能被检测到。
函数cvSetImagesForHaarClassifierCascade 为hidden classifier cascade 指定图像and/or 窗口比例系数。
如果图像指针为空,会持续使用本来的图像(i.e. NULLs 象征这"不转变图像")。
比例系数不"protection" 值,然而本来的值可以通过函数cvGetHaarClassifierCascadeScale 重新得到并使用。
这个函数用于对特定图像中检测特定目标尺寸的cascade分类器的设定。
函数通过cvHaarDetectObjects进行内部调用,但当须要在更低一层的函数cvRunHaarClassifierCascade中使用的时候,用户也可以自行调用。
cvRunHaarClassifierCascade在给定地位的图像中运言cascade of boosted classifierint cvRunHaarClassifierCascade( CvHaarClassifierCascade* cascade,CvPoint pt, int start_stage=0 );cascade Haar 级联分类器pt 待检测区域的左上角卧标。
待检测区域大小为本始窗口尺寸趁以当前设定的比例系数。
当前窗口尺寸可以通过cvGetHaarClassifierCascadeWindowSize从新得到。
start_stage 级联层的初始下标值(从0开端计数)。
函数假设后面所有每层的分类器都已通过。
这个特征通过函数cvHaarDetectObjects内部调用,用于更美的处理器高速缓冲存储器。