.NET C# 使用OpenCV实现模型训练、人脸识别
码图~~~
1 引入依赖
OpenCvSHarp4 - 4.10.0.20240616
OpenCvSHarp4.runtime.win - 4.10.0.20240616
2 人脸数据存储结构
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 - 27if (v == 27){break;}}
}