Esion

zedboard移植opencv+qt的人脸检测

0
阅读(3055)

人脸检测是在ubuntu下调试的。整个工程在附件中。

由于是移植到zedboard上显示,使用opencv读取摄像头并进行人脸检测,然后转换成QImage转换成qt显示。HDMI显示两个视频画面:一个摄像头获取的原始视频和一个人脸检测视频。

人脸检测使用opencv源码包自带的分类器haarcascade_frontalface_alt2.xml,人脸检测的代码如下:

void Widget::detect_and_draw(IplImage* img )
{
    double scale=8; //1.2
    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}}
    };//Just some pretty colors to draw with

    //Image Preparation
    cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 );

    if( !cascade )
    {
        fprintf( stderr, "ERROR: Failed to load classifier cascade\n" );
        return ;
    }
    storage = cvCreateMemStorage(0);

    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);
    cvCvtColor(img,gray, CV_BGR2GRAY);
    cvResize(gray, small_img, CV_INTER_LINEAR);

    cvEqualizeHist(small_img,small_img); //直方图均衡

    //Detect objects if any
    //
    cvClearMemStorage(storage);
    double t = (double)cvGetTickCount();
    CvSeq* objects = 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.) );

    //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(img, cvPoint(r->x*scale,r->y*scale), cvPoint((r->x+r->width)*scale,(r->y+r->height)*scale), colors[i%8]);
    }
    for( int i = 0; i < (objects? objects->total : 0); i++ )
    {
        CvRect* r = (CvRect*)cvGetSeqElem( objects, 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 );
    }

    cvCvtColor(img,img, CV_BGR2RGB);
    im = QImage((uchar *)img->imageData, img->width, img->height, img->widthStep, QImage::Format_RGB888);
    ui->label->setPixmap(QPixmap::fromImage(im,Qt::AutoColor));
    cvReleaseImage(&gray);
    cvReleaseImage(&small_img);
}

其中的scale待检测图像所要缩小的尺寸(将原图像按比例缩小进行检测以提高检测速度),由于该工程是对摄像头输入视频进行实时检测,因此我这里将scale提高到8以提高检测速度,此时人脸检测算法cvHaarDetectObjects所消耗的时间可以减小到20ms以下。

人脸检测视频使用label显示,原始视频显示使用:

painter.drawImage(QRect(0,0, 640, 480), image);

PS:由于本人长得对不起观众,这里就不将人脸检测显示的截图po上来了。

附件:

real_sh_video.rar