【opencv】cascades 级联分类器人脸识别-打开摄像头

本文展示了如何使用OpenCV库进行人脸识别和图像缩放。代码中包括了从命令行读取参数,加载预训练的人脸检测分类器,以及实时摄像头人脸检测和显示。同时,还提供了一个批量图像处理的程序,可以调整图像大小并保存,支持按需排序和输出文件路径记录。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <opencv2/opencv.hpp>  
#include <unistd.h>
#include <getopt.h>

using namespace std;
using namespace cv;
 
int main(int argc,char**argv)
{
    char ch;
    string path = "haarcascade_frontalface_alt2.xml";
    while((ch = getopt(argc, argv, "c:")) != EOF){
        switch(ch){
            case 'c':
                path = optarg;
                break;
            default:
                printf("请输入参数。");
                return 1;
        }
    }
	VideoCapture cap(0);    //打开默认摄像头  
	if (!cap.isOpened())
	{
		return -1;
	}
	Mat frame;
	Mat gray;
	//这个分类器是人脸检测所用
	CascadeClassifier cascade;
	
    //训练好的文件名称,放置在可执行文件同目录下  
	cascade.load(path);//感觉用lbpcascade_frontalface效果没有它好,注意哈!要是正脸
    printf("加载成功;请将摄像头对准检测对象!\n");
    while (1)
	{
		cap >> frame;
  
		vector<Rect> faces(0);//建立用于存放人脸的向量容器
		
		cvtColor(frame, gray, COLOR_RGB2GRAY);//测试图像必须为灰度图
		
		equalizeHist(gray, gray); //变换后的图像进行直方图均值化处理  
		//检测人脸
		cascade.detectMultiScale(gray, faces,
			1.1, 4, 0
			//|CV_HAAR_FIND_BIGGEST_OBJECT  
			// | CV_HAAR_DO_ROUGH_SEARCH,
			// | CV_HAAR_DO_CANNY_PRUNING,
			//| CV_HAAR_SCALE_IMAGE,
			,Size(30, 30), Size(500, 500));
		for (int i = 0; i < faces.size(); i++)
		{
			printf("x:%3d,y:%3d,w:%3d,h%3d\n",faces[i].x, faces[i].y,faces[i].width,faces[i].height);
			Scalar color = Scalar(255, 0, 255);//所取的颜色任意值
			rectangle(frame, Point(faces[i].x, faces[i].y), Point(faces[i].x + faces[i].width, faces[i].y + faces[i].height), color, 1, 8);//放入缓存
		}
        if(true){
            imshow("face", frame);
            if(waitKey(200)==27){
                break;
            }
        }
        else
            usleep(200);
	}
 
	return 0;
}
 

#include <stdio.h>
#include <opencv2/opencv.hpp>
#include <string>
#include <getopt.h>
#include <dirent.h>
#include <vector>
#include <sys/stat.h>


using namespace cv;
using namespace std;

void putData(const string &file,const string &data){
    auto fp=fopen(file.c_str(),"a+");
    fwrite(data.c_str(),sizeof(char),data.size(),fp);
    fclose(fp);
}

bool GetFileList(const string &basePath, vector<string> &pathList) {
    DIR *dir;
    struct dirent *ptr;
    if ((dir = opendir(basePath.c_str())) == nullptr) {
        return false;
    }

    while ((ptr = readdir(dir)) != nullptr) {
        if (strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0)    ///current dir OR parrent dir
            continue;
        else if (ptr->d_type == 8) {    ///file
            pathList.push_back(basePath + "/" + ptr->d_name);
        } else if (ptr->d_type == 10) {    ///link file
            // printf("d_name:%s/%s\n", basePath, ptr->d_name);
        } else if (ptr->d_type == 4)    ///dir
        {
            GetFileList(basePath + "/" + ptr->d_name, pathList);
        }
    }
    closedir(dir);
    return true;
}

int main(int argc,char *argv[]){
    string file;
    string path,Path;
    string savePath;
    string saveInfoPath;
    int width=0;
    int height=0;
    char ch;
    bool sortFlag = false;

    while((ch = getopt(argc, argv, "P:p:f:w:h:so:O:")) != EOF)
    {
        switch(ch)
        {
            case 'f':
                file = optarg;
                break;
            case 'P':
                Path = optarg;
                break;
            case 'p':
                path = optarg;
                break;
            case 'o':
                savePath = optarg;
                break;
            case 'O':
                saveInfoPath = optarg;
                break;
            case 'w':
                width = strtol(optarg,nullptr,10);
                break;
            case 'h':
                height = strtol(optarg,nullptr,10);
                break;
            case 's':
                sortFlag = true;
                break;
            default:
                printf("请传入参数:-p 文件夹 -P 另存文件夹 -f 文件 -w 宽度 -h 高度 -s 排序 -o 输出文件 -O 信息文件");
                return 1;
        }
    }
    if(file.empty() && path.empty()){
        return 1;
    }
    if(width <=0 || height <=0){
        return 2;
    }
    if(path.empty()){
        Mat img = imread(file);
        resize(img,img,Size(width,height));
        imwrite(file,img);
        printf("%d\n",1);
    }else{
        vector<string> fileList;
        vector<Mat> imgList;
        GetFileList(path,fileList);
        for(size_t i=0;i< fileList.size();i++ ){
            auto f = fileList[i];
            Mat img = imread(f);
            resize(img,img,Size(width,height));
            if(sortFlag){
                if(Path.empty())
                    remove(f.c_str());
                imgList.push_back(img);
            }else{
                imwrite(f,img);
                if(!savePath.empty())
                    putData(savePath,f + " 1 0 0 "+to_string(width)+" "+to_string(height)+"\r\n");
                if(!saveInfoPath.empty())
                    putData(saveInfoPath,f + "\r\n");
            }
        }
        if(sortFlag){
            for(size_t j=0;j<imgList.size();j++){
                Mat img = imgList[j];
                string ex = ".png";
                char _path[256 * 4];
                memset(_path,0x00,sizeof(_path));
                //string newF = path + "/" + to_string(j) + ex;
                if(Path.empty())
                    sprintf(_path,"%s/%04ld%s",path.c_str(),j,ex.c_str());
                else
                    sprintf(_path,"%s/%04ld%s",Path.c_str(),j,ex.c_str());
                bool flag = imwrite(_path,img);
                if(!savePath.empty())
                    putData(savePath,string(_path) + " 1 0 0 "+to_string(width)+" "+to_string(height)+"\r\n");
                if(!saveInfoPath.empty())
                    putData(saveInfoPath,string(_path) + "\r\n");
            }
        }
        printf("%ld\n",fileList.size());
    }

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值