opencv-人脸识别-2增加人脸数据集

人脸识别-增加自己的脸或者别人脸的数据
这里要增加的一定是脸部的数据,而不是全身的,所以要把脸部的图像从原图中拿出来就可以了,这就是传说中的人脸检测。
代码

static Mat detectAndDraw(Mat& img, CascadeClassifier& cascade,
    double scale, bool tryflip)
{
    double t = 0;
    vector<Rect> faces, faces2;
    const static Scalar colors[] =
    {
        Scalar(255,0,0),
        Scalar(255,128,0),
        Scalar(255,255,0),
        Scalar(0,255,0),
        Scalar(0,128,255),
        Scalar(0,255,255),
        Scalar(0,0,255),
        Scalar(255,0,255)
    };

    Mat imgcopy = img.clone();
    Mat gray, smallImg;

    cvtColor(img, gray, COLOR_BGR2GRAY);

    double fx = 1 / scale;
    resize(gray, smallImg, Size(), fx, fx, INTER_LINEAR_EXACT);
    equalizeHist(smallImg, smallImg);
    t = (double)getTickCount();

    cascade.detectMultiScale(smallImg, faces, 1.1, 3, CV_HAAR_DO_ROUGH_SEARCH, Size(70, 70), Size(100, 100));

    if (tryflip)
    {
        flip(smallImg, smallImg, 1);
        cascade.detectMultiScale(smallImg, faces2,
            1.1, 2, 0
            //|CASCADE_FIND_BIGGEST_OBJECT
            //|CASCADE_DO_ROUGH_SEARCH
            | CASCADE_SCALE_IMAGE,
            Size(30, 30));
        for (vector<Rect>::const_iterator r = faces2.begin(); r != faces2.end(); ++r)
        {
            faces.push_back(Rect(smallImg.cols - r->x - r->width, r->y, r->width, r->height));
        }
    }
    t = (double)getTickCount() - t;
    printf("detection time = %g ms\n", t * 1000 / getTickFrequency());

    Mat faceROI;


    for (size_t i = 0; i < faces.size(); i++)
    {
        Rect r = faces[i];
        Mat smallImgROI;
        //  vector<Rect> nestedObjects;
        Point center;
        Scalar color = colors[i % 8];

        double aspect_ratio = (double)r.width / r.height;
        //  if (0.75 < aspect_ratio && aspect_ratio < 1.3)
        {
            //  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);
            //  circle(img, center, radius, color, 3, 8, 0);
        }
        //      else
        rectangle(img, cvPoint(cvRound(r.x*scale), cvRound(r.y*scale)),
            cvPoint(cvRound((r.x + r.width - 1)*scale), cvRound((r.y + r.height - 1)*scale)),
            color, 3, 8, 0);

        smallImgROI = smallImg(r);

        faceROI = imgcopy(Rect(cvPoint(cvRound(r.x*scale), cvRound(r.y*scale)),
            cvPoint(cvRound((r.x + r.width - 1)*scale), cvRound((r.y + r.height - 1)*scale))));
    }

    cv::imshow("result", img);

    if (!faceROI.empty())
    {
        namedWindow("faceROI", WINDOW_NORMAL);
        imshow("faceROI", faceROI);
        return faceROI;
    }
}

/*有两种输入方式,可以选择文件夹,也可以选择相机*/
//= "faces\\s41";
//= ".jpg";
int detect_save_face(string Normalizat_Dir,int camera_id , string FilePath, string FileType)
{
    bool tryflip = 1;
    CascadeClassifier cascade;
    double scale = 1.3;
    string cascadeName = "haarcascade_frontalface_alt.xml";
    if (scale < 1)
        scale = 1;

    if (!cascade.load(cascadeName))
    {
        cerr << "ERROR: Could not load classifier cascade" << endl;
        help();
        system("pause");
        return -1;
    }
    /*如果没有输入,就启动相机*/
    if (FilePath.empty()||FileType.empty())
    {
        VideoCapture capture;
        Mat frame, image;
        //如果相机打不开
        if (!capture.open(camera_id))
        {
            cout << "Capture from camera #" << camera_id << " didn't work" << endl;
            system("pause");
            return -1;
        }

        if (capture.isOpened())
        {
            char *name = new char[Normalizat_Dir.size() + 1];
            strcpy(name, Normalizat_Dir.data());
            cout << "Video capturing has been started ..." << endl;
            for (;;)
            {
                static int k = 0;
                capture >> frame;
                if (frame.empty())
                    break;

                Mat frame1 = frame.clone();
                Mat faceROI = detectAndDraw(frame1, cascade, scale, tryflip);
            //  waitKey(200);
                char filename[100];
                char c = (char)waitKey(10);
                if (c == 27 || c == 'q' || c == 'Q')
                    break;
                if (c == 32)
                {
                    if (!faceROI.empty())
                    {
                        sprintf(filename, "%s/%d.jpg", name, k++);
                        resize(faceROI, faceROI, Size(92, 112));
                        imwrite(filename, faceROI);
                        imshow("faceROI", faceROI);
                    }
                }
            }
            delete name;
        }
    }

    /*有输入的话,则读取文件夹中的图片,并保存头像图片*/
    else
    {
        vector<string> FilesName;
        /*存放符合格式的图像的名字*/
        string buffer = FilePath + "/*" + FileType;

        _finddata_t c_file;   // 存放文件名的结构体

        intptr_t hFile;
        hFile = _findfirst(buffer.c_str(), &c_file);   //找第一个文件命

        if (hFile == -1L)   // 检查文件夹目录下存在需要查找的文件
            cout << "No" << FileType << " files in current directory!!!" << endl;
        else
        {
            int i = 0;
            string fullFilePath;
            do
            {
                /*清除上一次缓存的名称*/
                fullFilePath.clear();
                /*取出文件照片名*/
                fullFilePath = FilePath + "/" + c_file.name;
                /*保存当前文件的路径和名称*/
                FilesName.push_back(fullFilePath);
            } while (_findnext(hFile, &c_file) == 0);
            _findclose(hFile);
        }

        char *name = new char[Normalizat_Dir.size() + 1];
        strcpy(name, Normalizat_Dir.data());
        for (int i = 0; i < FilesName.size(); i++)
        {
            Mat image = imread(FilesName[i], 1);
            if (!image.empty())
            {
                static int k = 0;
                Mat faceROI = detectAndDraw(image, cascade, scale, tryflip);
                waitKey(200);
                char filename[100];
                if (!faceROI.empty())
                {
                    sprintf(filename, "%s/%d.jpg", name, k++);
                    resize(faceROI, faceROI, Size(92, 112));
                    imwrite(filename, faceROI);
                    imshow("faceROI", faceROI);
                }
            }
        }
        delete name;
    }
    destroyAllWindows();
    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值