实现人脸检测。opencv提供了Haar分类器,其在data文件下还提供了训练的数据,所以实现这个不是很难。
我继承OpenCVaction,实现了人脸检测的算法。
#ifndef OPENCVFACEDETECTACTION_H
#define OPENCVFACEDETECTACTION_H
#include "opencvaction.h"
class OpenCVfaceDetectAction : public OpenCVaction
{
Q_OBJECT
public:
OpenCVfaceDetectAction(QObject *parent = 0);
~OpenCVfaceDetectAction();
void action(IplImage *imgin, IplImage *&imgout);
signals:
void a();
private:
CvHaarClassifierCascade* m_cascade;
CvMemStorage* m_storage;
double m_scale;
};
#endif // OPENCVFACEDETECTACTION_H
#include "opencvfacedetectaction.h"
#include <QDebug>
const char* cascade_name = "data/haarcascade_frontalface_alt.xml";
OpenCVfaceDetectAction::OpenCVfaceDetectAction(QObject *parent): OpenCVaction(parent),
m_cascade(NULL),
m_storage(NULL),
m_scale(1.3)
{
m_cascade = (CvHaarClassifierCascade*)cvLoad(cascade_name, 0, 0, 0);
if (!m_cascade) {
qDebug() << "load Cascade fail!";
}
m_storage = cvCreateMemStorage(0);
}
OpenCVfaceDetectAction::~OpenCVfaceDetectAction()
{
if (m_cascade) {
cvReleaseHaarClassifierCascade(&m_cascade);
}
cvReleaseMemStorage(&m_storage);
}
void OpenCVfaceDetectAction::action(IplImage *imgin, IplImage *&imgout)
{
imgout = cvCloneImage(imgin);
if (!m_cascade) {
qDebug() << "Cascade is invaild!";
return;
}
static CvScalar color = CV_RGB(255, 255, 255);
//Image Preparation
//
IplImage* gray = cvCreateImage(cvGetSize(imgin), 8, 1);
IplImage* small_img = cvCreateImage(cvSize(cvRound(imgin->width / m_scale),
cvRound(imgin->height / m_scale)), 8, 1);
cvCvtColor(imgin, gray, CV_BGR2GRAY);
cvResize(gray, small_img, CV_INTER_LINEAR);
cvEqualizeHist(small_img, small_img); //直方图均衡
//Detect objects if any
//
cvClearMemStorage(m_storage);
double t = (double)cvGetTickCount();
CvSeq *objects = cvHaarDetectObjects(small_img,
m_cascade,
m_storage,
1.1,
2,
0,
cvSize(50,50));
t = (double)cvGetTickCount() - t;
qDebug() << "detection time =" << t / ((double)cvGetTickFrequency()*1000.) << "ms";
//Loop through found objects and draw boxes around them
for(int i=0; i < (objects ? objects->total : 0); ++i)
{
CvRect* r = (CvRect*)cvGetSeqElem(objects, i);
cvRectangle(imgout, cvPoint(r->x * m_scale, r->y * m_scale),
cvPoint((r->x + r->width) * m_scale, (r->y + r->height) * m_scale), color, 2, CV_AA);
}
cvReleaseImage(&gray);
cvReleaseImage(&small_img);
emit a();
}
在OpenCVshowFrame中,添加下面
OpenCVfaceDetectAction *f = new OpenCVfaceDetectAction();
m_actions.push_back(f);
就ok了。
运行效果如下: