您的位置:首页 > 其它

基于人脸检测的肤色采集以及两种常见肤色模型建模

2015-05-21 15:35 399 查看
[code]#include "relativeFunction.h"

int main()
{
    //svmTest();
    //neuralTest();
    char imageFileDir[100];
    CascadeClassifier cc;
    cc.load("haarcascade_frontalface_alt2.xml");

    VideoCapture cap(0);
    Mat frame;
    int countOfCheckFace = 0;
    vector<Mat> skinRegion;
    /***************************利用人脸检测收集可能的肤色像素********************************/
    while(1)
    {
        cap >> frame;
        blur(frame,frame,Size(5,5));
        resize(frame,frame,Size(640,480));
        Mat gray;
        cvtColor(frame,gray,CV_BGR2GRAY);

        vector<Rect> objects;
        cc.detectMultiScale(gray, objects, 1.1, 3, 0);
        Mat newImage;
        if(!objects.empty() && objects[0].width > 100 && objects[0].height > 100)
        {
            //Mat white(gray.size(),CV_8UC3,Scalar::all(255));
            Mat white = Mat::zeros(frame.size(),CV_8UC3);
            if(objects.size() == 1)
            {
                rectangle(white,objects[0],Scalar(0,0,255));

                if(countOfCheckFace >= 20)
                {

                        break;
                }
                else
                    countOfCheckFace++;
                ;
            }
            else
                continue;

            int width = objects[0].width/8;
            int height = objects[0].height/8;
            Rect rr = Rect(objects[0].x+width,objects[0].y+2*height,6*width, 4*height);
            rectangle(white,rr,Scalar(255,0,255));
            Mat newImage = frame(objects[0]);

            Mat ycc;
            cvtColor(newImage,ycc,CV_BGR2YCrCb);

            Mat a[3];
            split(ycc,a);
            skinRegion.push_back(ycc);
            Mat mask;
            threshold(a[1],mask,131,255,THRESH_BINARY);
            imshow("dst",mask);
            Mat mmask;
            mask.convertTo(mmask,CV_8UC1,255,0);
            Mat roi = Mat::zeros(newImage.size(),CV_8UC3);
            newImage.copyTo(roi,mmask);
            sprintf(imageFileDir,"skin\\image%d.jpg",time(0));
            imwrite(imageFileDir, roi);
            imshow("roi",roi);
            char context[100];
            sprintf(context,"%s","this is fist");
            putText(white,context,Point(50,50),FONT_HERSHEY_COMPLEX,1.0,Scalar(0,0,0));
            imshow("white", white);
        }
        waitKey(22);
    }

    resize(frame,frame,Size(320,240));
    float mu = 0;
    float sigma = 0;
    vector<float> cr;
    vector<float> cb;
    int n = skinRegion.size();
    Mat tuoyuan = Mat(255,255,CV_8UC3,Scalar::all(255));
    vector<Point> fitEllipsePointSet;
    for(int i = 0; i < n; i++)
    {
        int imageRow = skinRegion[i].rows;
        int imageCol = skinRegion[i].cols;
        //cout << imageRow << "\t" << imageCol << endl;
        for(int ii = 0; ii < imageRow; ii = ii + 10)
        {
            for(int jj = 0; jj < imageCol; jj = jj + 10)
            {
                Vec3b ycrcb = skinRegion[i].at<Vec3b>(ii,jj);
                //cout << ii << "\t" << jj << endl;
                if(ycrcb[1] > 125)
                {
                    cr.push_back(ycrcb[1]);
                    cb.push_back(ycrcb[2]);
                    fitEllipsePointSet.push_back(Point(ycrcb[1],ycrcb[2]));
                    circle(tuoyuan,Point(ycrcb[1],ycrcb[2]),1,Scalar(255,0,0));
                }
            }
        }
    } 
    /**************************椭圆肤色模型*********************************/
    RotatedRect ellipse1 = fitEllipse(fitEllipsePointSet);
    ellipse(tuoyuan,ellipse1.center,ellipse1.size - Size2f(0,0),ellipse1.angle,0,360,Scalar(0,0,255),-1);
    Mat tyModel(frame.size(),CV_8UC1,Scalar::all(0));
    ellipse(tyModel,ellipse1.center,ellipse1.size - Size2f(0,0),ellipse1.angle,0,360,Scalar(255,255,255),-1);
    for(int i = 0; i < 255; i = i + 20)
    {
        line(tuoyuan,Point(0,i+20),Point(255,i+20),Scalar(0,0,0));
        line(tuoyuan,Point(i+20,0),Point(i+20,255),Scalar(0,0,0));
    }
    time_t t = time(NULL);
    struct tm* tm = localtime(&t);
    char fileDate[100];
    sprintf(fileDate,"%d:%d:%d:%d:%d",1900+tm->tm_year,1+tm->tm_mon,tm->tm_mday,tm->tm_hour,tm->tm_min);
    putText(tuoyuan,fileDate,Point(5,50),FONT_HERSHEY_COMPLEX,1.0,Scalar(0,0,255));
    sprintf(imageFileDir,"fusejulei\\image%d.jpg",time(0));
    imwrite(imageFileDir,tuoyuan);
    imshow("tuoyuan", tuoyuan);
    imshow("tyModel", tyModel);
    while(1)
    {
        cap >> frame;

        Mat ycc;
        cvtColor(frame,ycc,CV_BGR2YCrCb);

        Mat hh(frame.size(),CV_8UC1);
        for(int i = 0; i < 480; i++)
        {
            for(int j = 0; j < 640; j++)
            {
                Vec3b pixel = ycc.at<Vec3b>(i,j);
                if(tyModel.at<uchar>(pixel[1],pixel[2]) > 0)
                {
                    hh.at<uchar>(i,j) = 0;
                }
                else
                {
                    hh.at<uchar>(i,j) = 255;
                }
            }
        }

        Mat kernel;
        kernel = getStructuringElement(MORPH_RECT,Size(5,5));
        erode(hh,hh,kernel);
        dilate(hh,hh,kernel);
        dilate(hh,hh,kernel);
        erode(hh,hh,kernel);
        Mat contour_image = Mat(frame.size(),CV_8UC3,Scalar::all(255));
        vector<vector<Point>> contour;
        vector<Vec4i> heri;
        findContours(hh,contour,heri,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE);
        drawContours(contour_image,contour,-1,Scalar(255,0,255));
        imshow("contour", contour_image);
        imshow("hh",hh);
        waitKey(22);
    }
    /***************************************下面是高斯肤色模型*******************************************/
    Scalar avr;
    Scalar stddev;
    meanStdDev(cr,avr,stddev);
    mu = avr[0];
    sigma = stddev[0];
    cout << avr << "\t" << stddev << endl;
    cout << skinRegion.size();
    //system("pause");

    while(1)
    {
        cap >> frame;

        Mat ycrcb;
        cvtColor(frame,ycrcb,CV_BGR2YCrCb);

        Mat aa[3];
        split(ycrcb,aa);

        Mat res(aa[1].size(),CV_32FC1);
        cout << frame.size() << endl;
        //system("pause");
        for(int i = 0; i < res.rows; i++)
        {
            for(int j = 0; j < res.cols; j++)
            {
                res.at<float>(i,j) = exp(-(aa[1].at<char>(i,j)-mu)*(aa[1].at<char>(i,j)-mu)/(2*sigma*sigma));
                //cout << "mu = " << mu << "\t" << "sigma = " << sigma << endl;
                //cout << i << "\t" << j << endl;
            }
        }

        Mat dstt = Mat::zeros(res.size(),CV_32FC1);
        double max1 = 0;
        double min1 = 0;
        Mat hh = res.clone();
        minMaxIdx(hh, &min1, &max1,0,0,Mat());
        cout << min1 << "\t" << max1 << endl;

        for(int i = 0; i < 480; i++)
        {
            for(int j = 0; j < 640; j++)
            {
                /*dstt.at<float>(j,i) = 255*(res.at<float>(j,i) - min1) /(max1 - min1);*/
                //cout << i << "\t" << j << endl;
                if(res.at<float>(i,j) > 0.35)
                    dstt.at<float>(i,j) = 255;
                else
                    dstt.at<float>(i,j) = 0;
            }
        }
        imshow("dstt",dstt);

        Mat thresh;
        threshold(aa[1],thresh,135,255.0,THRESH_BINARY);
        imshow("thresh",thresh);
        waitKey(22);
    }
    system("pause");
    return  0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: