用摄像头进行人脸和人眼实时检测的优化 算法

来源:互联网 发布:mac jenkins 启动 编辑:程序博客网 时间:2024/05/18 13:47

         在之前的工作中,我们实现了从摄像头采集图像的功能,那么接下来我们尝试进行人脸和人眼的检测和识别。在图像的预处理和图像参数设置上,花费了不少的时间,现在给出对于优化这个算法的一些看法。

        1、图像预处理

           在图像的与处理上,为了消除光线、背景等的影响,先做图像的灰度化,平滑处理,均衡化,然后进行处理。

               cvCvtColor(img2, img3, CV_BGR2GRAY);//灰度化
cvSmooth(img3, img3, CV_GAUSSIAN, 5, 5, 0, 0);//平滑处理
cvEqualizeHist(img3, img3);//均衡化

      2、检测部分参数设置

            在进行检测的时候,各种参数的设置至关重要。参数设置的不正确非常影响处理速度,也会影响检测的准确性。

             CvSeq *faces = cvHaarDetectObjects(img3, cascade_f, storage1,1.2, 2, CV_HAAR_DO_CANNY_PRUNING, cvSize(40, 40));

             CvSeq *eyes = cvHaarDetectObjects(img3, cascade_e, storage,1.2,3, CV_HAAR_DO_CANNY_PRUNING, cvSize(10, 10));

            在此处,缩放速度设置为1.2,降低检测的进度来提高检测的效率,以便在视频中实现流畅地处理。

            最小方格数量设置为2为常用数据,也可以增大这个数据来提高检测精度,但是可能会导致有部分目标不能被检测到。

       3、彩色显示的坐标设置

            在设置显示效果上,由于设置了RIO区域,检测到的face和eye都是在灰度图像上实现的。所以在显示方框时,会显示在灰度化,并且平滑处理后的灰色图像上实现。为了在彩色图像上实现,只需要在画方框上时画在彩色图像上就行。

             cvRectangle(img2, cvPoint(eye->x + face->x, eye->y + face->y + (face->height / 5.5)), cvPoint(eye->x + face->x + eye->width, eye->y + face->y + (face->height / 5.5) + eye->height), CV_RGB(255, 0, 0), 1, 8, 0);

            在设置坐标时,加上原来设置的RIO的起点坐标,来保证在彩色图像上的坐标一致性。

            全部代码如下:

#include <opencv2/opencv.hpp>
#include <iostream>
#include <stdio.h>
#include "cv.h"
#include "cxcore.h"
#include "highgui.h"
#include <assert.h>
using namespace cv;




int main(int argc, char** argv)
{




//为后期的检测做准备,包括再入分类器,分配内存
CvMemStorage* storage1 = 0;
storage1 = cvCreateMemStorage(0);
CvHaarClassifierCascade *cascade_f = 0;
const char *cascade_name1 = "haarcascade_frontalface_alt2.xml";
cascade_f = (CvHaarClassifierCascade*)cvLoad(cascade_name1, 0, 0, 0);
assert(cascade_f != NULL);




CvMemStorage* storage = 0;
storage = cvCreateMemStorage(0);
CvHaarClassifierCascade* cascade_e = 0;
const char* cascade_name2 = "haarcascade_eye.xml";
cascade_e = (CvHaarClassifierCascade*)cvLoad(cascade_name2, 0, 0, 0);
assert(cascade_e != NULL);










VideoCapture cap;
if (argc > 1)
cap.open(argv[1]);
else
cap.open(0);


if (!cap.isOpened())
{
std::cerr << "Cannot read video. Try moving video file to sample directory." << std::endl;
return -1;
}


Mat frame;
cvNamedWindow("Example1", 0);


for (;;)
{
cap >> frame;


if (frame.empty())
{
break;
}
IplImage img = frame;
IplImage *img2 = &img;


IplImage *img3 = cvCreateImage(cvGetSize(img2), img2->depth, 1);

cvCvtColor(img2, img3, CV_BGR2GRAY);//灰度化
cvSmooth(img3, img3, CV_GAUSSIAN, 5, 5, 0, 0);//平滑处理
cvEqualizeHist(img3, img3);//均衡化




//眼睛检测部分


CvSeq *faces = cvHaarDetectObjects(img3, cascade_f, storage1, 1.2, 2, CV_HAAR_DO_CANNY_PRUNING, cvSize(40, 40));
for (int ii = 0; ii<(faces ? faces->total : 0); ii++)
{
CvRect *face = (CvRect*)cvGetSeqElem(faces, ii);
cvRectangle(img2, cvPoint(face->x, face->y), cvPoint(face->x + face->width, face->y + face->height)
, CV_RGB(255, 0, 0), 1, 8, 0);

cvSetImageROI(img3, cvRect(face->x, face->y + (face->height / 5.5), face->width, face->height / 3.0));






CvSeq *eyes = cvHaarDetectObjects(img3, cascade_e, storage, 1.2,3, CV_HAAR_DO_CANNY_PRUNING, cvSize(10, 10));
int i;


for (i = 0; i < (eyes ? eyes->total : 0); i++)
{


CvRect *eye = (CvRect*)cvGetSeqElem(eyes, i);
cvRectangle(img2, cvPoint(eye->x + face->x, eye->y + face->y + (face->height / 5.5)), cvPoint(eye->x + face->x + eye->width, eye->y + face->y + (face->height / 5.5) + eye->height), CV_RGB(255, 0, 0), 1, 8, 0);
}
cvResetImageROI(img3);
}


cvShowImage("Example1", img2);
int c = waitKey(30);
if (c == 'q' || c == 'Q' || (c & 255) == 27)
break;
}


cvDestroyAllWindows;
return 0;
}

0 0
原创粉丝点击