You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现摄像头人脸自动识别并将标签设为对应人脸文件名?

人脸识别系统:自动匹配人脸标签问题求助

我正在开发一套人脸识别系统,已实现将人脸保存为对象并存储到指定文件夹的功能。目前遇到的问题是:开启摄像头后如何自动识别人脸,并将识别标签设置为对应人脸文件的名称?我觉得自己的代码比网上示例更简洁,但调整后反而更困惑,想请教是否需要重写整个代码?

当前代码

private async Task StreamVideo2()
{
    var faceCasade = new CascadeClassifier("./detection/haarcascade_frontalface_default.xml");
    var vc = new VideoCapture(0, Emgu.CV.VideoCapture.API.DShow);

     // Get the list of saved face images
     string folder = Path.Combine(Application.StartupPath, "TrainedFaces");
     string[] savedImages = Directory.GetFiles(folder, "*.bmp");


     while (streamVideo)
    {

        var frame = new Mat();
        var frameGray = new Mat();
        vc.Read(frame);
        CvInvoke.CvtColor(frame, frameGray, Emgu.CV.CvEnum.ColorConversion.Bgr2Gray);

        var faces = faceCasade.DetectMultiScale(frameGray, 1.3, 5);

        if (faces != null && faces.Length > 0)
        {
            CvInvoke.Rectangle(frame, faces[0], new MCvScalar(0, 255, 0), 2); // --> MCvScalar EMGU STRUCTURE [ RETACLE GREEN ON FACE ]

            // Crop
            var faceRect = faces[0];
            var croppedFace = new Mat(frame, faceRect);

            // LABEL
            string labelText = "Detected Face";
            var font = new Emgu.CV.CvEnum.FontFace();
            var fontScale = 0.8;
            var fontThickness = 1;
            var fontColor = new MCvScalar(0, 255, 0); 
            var textOrg = new System.Drawing.Point(faceRect.X, faceRect.Y - 10); 
            CvInvoke.PutText(frame, labelText, textOrg, font, fontScale, fontColor, fontThickness);

            // ResizedCroppedFace
            var resizedCroppedFace = new Mat();
            var resizedSize = new System.Drawing.Size(184, 192); // Size to keep the croppedFace.
            CvInvoke.Resize(croppedFace, resizedCroppedFace, resizedSize);

            // Convert cropped face to black and white (grayscale)
            var grayCroppedFace = new Mat();
            CvInvoke.CvtColor(resizedCroppedFace, grayCroppedFace, Emgu.CV.CvEnum.ColorConversion.Bgr2Gray);

            // Display the grayscale cropped face in pictureBox2
            pictureBox2.Image = grayCroppedFace.ToBitmap();
        }
        else
        {
            pictureBox2.Image = null;
        }

        // TURN CAMERA TO IMG PICTURE BOX
        var img = frame.ToBitmap();
        pictureBox1.Image = img;

        label1.Text = "Mat Size: " + frame.Width.ToString() + " X " + frame.Height.ToString();
        if (CvInvoke.WaitKey(1) == 27)
        {
            break;
        }

        await Task.Delay(16);
    }
} 

private void button1_Click(object sender, System.EventArgs e)
{
    if (pictureBox2.Image != null) 
    {
        string folder = Path.Combine(Application.StartupPath, "TrainedFaces");
        string filename = textBox1.Text.Trim();
        string savePath = Path.Combine(folder, $"{filename}.bmp");

        // Saved As An Object
        using var bitmapImage = new Bitmap(pictureBox2.Image);
        bitmapImage.Save(savePath, System.Drawing.Imaging.ImageFormat.Bmp);
        MessageBox.Show("Succed");
        textBox1.Clear();

        if (!Directory.Exists(folder))
        {
            MessageBox.Show("Not Found");
        }
    } else
    {
        MessageBox.Show("Turn On The Camera");
    }
}

解决方案建议:无需重写,扩展特征匹配逻辑

当前代码仅完成了人脸检测,缺少特征提取与匹配环节,只需在现有代码基础上添加以下步骤:

  1. 预加载并训练人脸特征
    在StreamVideo2方法的开头(循环外),加载已保存的人脸图片,提取特征并训练识别器,同时建立标签与文件名的映射:

    // 初始化特征识别器(推荐LBPH,对姿态/光照变化适应性更强)
    var recognizer = new LBPHFaceRecognizer();
    List<Mat> faceSamples = new List<Mat>();
    List<int> labelIds = new List<int>();
    Dictionary<int, string> idToName = new Dictionary<int, string>();
    
    int currentId = 0;
    foreach (var imgPath in savedImages)
    {
        // 读取灰度图(与后续检测的人脸格式一致)
        var faceMat = CvInvoke.Imread(imgPath, Emgu.CV.CvEnum.ImreadModes.Grayscale);
        faceSamples.Add(faceMat);
        labelIds.Add(currentId);
        // 提取文件名作为标签
        idToName[currentId] = Path.GetFileNameWithoutExtension(imgPath);
        currentId++;
    }
    // 训练识别器
    recognizer.Train(faceSamples.ToArray(), labelIds.ToArray());
    
  2. 实时匹配并替换标签
    在检测到人脸并生成grayCroppedFace后,用识别器预测结果,替换原有的固定标签:

    // 替换原有的labelText赋值逻辑
    string labelText = "Unknown";
    var prediction = recognizer.Predict(grayCroppedFace);
    // 距离阈值根据实际样本调整,越小匹配越严格
    if (prediction.Label != -1 && prediction.Distance < 50)
    {
        labelText = idToName[prediction.Label];
    }
    
  3. 关键优化点

    • 特征训练只执行一次,不要放在循环内,避免重复计算浪费资源。
    • 测试并调整匹配阈值(prediction.Distance),根据你的样本质量找到合适的数值。
    • 确保已保存的人脸图片尺寸与实时检测后裁剪的尺寸一致(当前是184x192),否则匹配会失效。

内容的提问来源于stack exchange,提问作者Alexander

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 13:17:07