.NET C# 使用OpenCV实现人脸识别

发布于:2024-07-04 ⋅ 阅读:(135) ⋅ 点赞:(0)

.NET C# 使用OpenCV实现模型训练、人脸识别

码图~~~
微信图片_20240626175714

微信图片_20240626175734

1 引入依赖

image-20240626174305168

OpenCvSHarp4 - 4.10.0.20240616

OpenCvSHarp4.runtime.win - 4.10.0.20240616

2 人脸数据存储结构

image-20240626174620053

image-20240626174646845

runtime directory | face | {id}_{name} | *.jpg
id - 不可重复
name - 人名
*.jpg - 人脸照片

3 Demo

3.1 人脸识别训练

//人脸识别器
FaceRecognizer _faceRecongnizer = FisherFaceRecognizer.Create();
//人脸id,name字典
Dictionary<int, string> _faceNameDic = new Dictionary<int, string>();
//人脸数据统一大小
OpenCvSharp.Size _imgSize = new OpenCvSharp.Size(1000, 1000);

private void InitializeTrain()
{
    string baseDir = AppDomain.CurrentDomain.BaseDirectory;
    string faceDir = baseDir + "face\\";
    string[] faceImageDirs = Directory.GetDirectories(faceDir, "*_*");
    //读取人脸数据
    List<Mat> faceMats = new List<Mat>();
    List<int> faceIds = new List<int>();
    foreach (var faceImageDir in faceImageDirs)
    {
        string[] faceImages = Directory.GetFiles(faceImageDir, "*.jpg");
        if (faceImages.Length < 1)
        {
            continue;
        }
        DirectoryInfo faceImageDirInfo = new DirectoryInfo(faceImageDir);
        string[] faceNameArr = faceImageDirInfo.Name.Split('_');
        int id = int.Parse(faceNameArr[0]);
        string name = faceNameArr[1];
        _faceNameDic.Add(id, name);
        IEnumerable<Mat> mats = faceImages.Select(face =>
        {
            Mat mat = new Mat(face, ImreadModes.Grayscale);
            Cv2.Resize(mat, mat, _imgSize);
            return mat;
        });
        IEnumerable<int> ids = mats.Select(e => id);
        faceMats.AddRange(mats);
        faceIds.AddRange(ids);
    }
    //训练
    _faceRecongnizer.Train(faceMats, faceIds);
    //保存训练数据
	//_faceRecongnizer.Save("train.xml");
}

3.2 开启摄像头进行人脸识别

//加载人眼、人脸识别训练模型
//这两个是OpenCV官方给出的,在官方库就可以找到
//https://github.com/opencv/opencv/tree/master/data/haarcascades
CascadeClassifier faceFinder = new CascadeClassifier(@"haarcascade_frontalface_default.xml");
CascadeClassifier eyeFinder = new CascadeClassifier(@"haarcascade_eye_tree_eyeglasses.xml");
using (OpenCvSharp.Window window = new OpenCvSharp.Window("video - 按ESC退出"))
//获取camera
using (FrameSource video = Cv2.CreateFrameSource_Camera(0))
using (Mat frame = new Mat())
{
    while (true)
    {
        //获取帧
        video.NextFrame(frame);
        //进行检测识别
        OpenCvSharp.Rect[] faceRects = faceFinder.DetectMultiScale(frame);
        OpenCvSharp.Rect[] eyeRects = eyeFinder.DetectMultiScale(frame);
        //如果没有检测到人脸,就跳过
        if (faceRects.Length < 1)
        {
            continue;
        }
        for (int i = 0; i < faceRects.Length; i++)
        {
            //人脸区域
            OpenCvSharp.Rect rect = faceRects[i];
            using (Mat nFrame = frame.Clone())
            {
                Mat m1 = new Mat(frame, rect);
                Cv2.CvtColor(m1, m1, ColorConversionCodes.BGR2GRAY);
                //设置大小
                Cv2.Resize(m1, nFrame, _imgSize);
                //人脸识别
                _faceRecongnizer.Predict(nFrame, out int id, out double confidence);
                //置信度
                confidence = Math.Round(confidence, 2);
                _faceNameDic.TryGetValue(id, out var name);
                string label = name == null ? "unknow" : $"{name}  {confidence}";
                // 在图像上绘制文字
                Cv2.PutText(frame, label, new OpenCvSharp.Point(rect.Left, rect.Top - 10), HersheyFonts.HersheySimplex, 1.0, new Scalar(0, 0, 255), 2, LineTypes.Link8);
            }
            //绘制人脸框
            Cv2.Rectangle(frame, faceRects[i], new Scalar(0, 0, 255), 1);
        }
        //眼部区域
        if (eyeRects.Length > 1)
        {
            for (int i = 0; i < eyeRects.Length; i++)
            {
                //绘制眼部框
                Cv2.Rectangle(frame, eyeRects[i], new Scalar(255, 0, 0), 1);
            }
        }
        //显示结果
        window.ShowImage(frame);
        int v = Cv2.WaitKey(1);
        //ESC - 27
        if (v == 27)
        {
            break;
        }
    }
}

网站公告

今日签到

点亮在社区的每一天
去签到