这是OpenCV的代码,在这基础上加了马赛克。
void CFaceDetectionDlg::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; //先缩小为small_img 后放大,为了便于处理也可以不用
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 ); //经过上面两步,gray指向的图像已经变为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) ); //检测的核心语句,注意cascade参数
t = (double)cvGetTickCount() - t; //计算时间间隔
//cout<<"detection time = %gms\n"<<t/((double)cvGetTickFrequency()*1000.)<<endl;//打印出所用的时间
for( i = 0; i < (faces ? faces->total : 0); i++ ) //总共有faces->total 个脸,把他们一个一个圈出来
{
CvRect* r = (CvRect*)cvGetSeqElem( faces, i ); //每个脸对应的链表节点
CvPoint center;
int radius;
center.x = cvRound((r->x + r->width*0.5)*scale); //圆心横坐标,注意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], -1, 8, 0 ); //画圆圈出目标头像
//马赛克
cvSetImageROI(img,cvRect(center.x-radius,center.y-radius,radius*2,radius*2));
int W=8;
int H=8;
for(int mi=W;mi<img->roi->width;mi+=W)
for(int mj=H;mj<img->roi->height;mj+=H)
{
CvScalar tmp=cvGet2D(img,mj-H/2,mi-W/2);
for(int mx=mi-W;mx<=mi;mx++)
for(int my=mj-H;my<=mj;my++)
cvSet2D(img,my,mx,tmp);
}
cvResetImageROI(img);
}
}
cvReleaseImage( &gray );
cvReleaseImage( &small_img );
}
本人写的通用小项目下载地址:可以提取分类器进行检测,大家必须配置好OpenCV环境和在源码中设置好分类器的路径。
http://download.csdn.net/detail/mkr127/5397219
转载请注明出处!