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

C# EMGU人脸识别程序EigenFaceRecognizer.Predict空引用异常求助

排查C# EMGU人脸识别程序的NullReferenceException异常

核心问题定位

触发System.NullReferenceException的直接原因是recognizer对象未完成初始化:

  • recognizer仅在点击btnTrain执行TrainImagesFromDir方法后才会被实例化
  • 如果未执行训练流程,或者训练失败(比如训练目录为空、文件读取错误),recognizer会保持null状态
  • 原代码在保存人脸图像后直接调用recognizer.Predict,此时大概率还未完成训练,导致空引用异常

修复方案

1. 增加Recognizer非空校验

在调用识别方法前先判断对象是否存在,避免异常:

// 替换原识别代码段
if (recognizer != null)
{
    Image<Gray, Byte> grayFacesResult = resultImage.Convert<Gray, Byte>().Resize(200, 200, Inter.Cubic);
    var result = recognizer.Predict(grayFacesResult);
    // 后续绘制逻辑...
}
else
{
    // 提示用户未完成训练
    CvInvoke.PutText(currentFrame, "未完成模型训练", new Point(face.X - 2, face.Y - 2), FontFace.HersheyComplex, 1.0, new Bgr(Color.Red).MCvScalar);
}

2. 分离保存与识别逻辑

保存人脸是为了生成训练数据,不应和识别逻辑绑定。将识别逻辑独立出来,仅当训练完成后执行:

// 修改ProcessFrame中的人脸循环逻辑
foreach (var face in faces) 
{
    // 原有的绘制人脸框、显示检测结果代码...

    if (EnabledSaveImage)
    {
        // 原有的保存10张人脸图像代码...
        // 保存完成后提示用户执行训练
        MessageBox.Show("人脸图像已保存,请点击「训练」按钮完成模型训练");
        EnabledSaveImage = false;
        // 恢复按钮状态代码...
    }

    // 独立执行识别逻辑(仅训练完成后)
    if (isTrained && recognizer != null)
    {
        Image<Gray, Byte> grayFacesResult = resultImage.Convert<Gray, Byte>().Resize(200, 200, Inter.Cubic);
        var result = recognizer.Predict(grayFacesResult);
        
        // 修复标签索引判断:原代码判断result.Label>0会跳过第一个人的识别
        if (result.Label >= 0 && result.Label < PersonsNames.Count)
        {
            CvInvoke.PutText(currentFrame, PersonsNames[result.Label], new Point(face.X - 2, face.Y - 2), FontFace.HersheyComplex, 1.0, new Bgr(Color.Green).MCvScalar);
            CvInvoke.Rectangle(currentFrame, face, new Bgr(Color.Green).MCvScalar, 2);
        }
        else
        {
            CvInvoke.PutText(currentFrame, "Unknown", new Point(face.X - 2, face.Y - 2), FontFace.HersheyComplex, 1.0, new Bgr(Color.Orange).MCvScalar);
            CvInvoke.Rectangle(currentFrame, face, new Bgr(Color.Red).MCvScalar, 2);
        }
    }
}

3. 修复训练逻辑的标签分配问题

原训练代码中每张图像对应一个新标签,会导致同一个人的多张图像被识别为不同身份,需修改为同一人对应同一标签:

private bool TrainImagesFromDir()
{
    int ImagesCount = 0;
    int Threshold = -1;
    TrainedFaces.Clear();
    PersonsLabels.Clear();
    PersonsNames.Clear();
    
    // 新增字典映射姓名与标签
    Dictionary<string, int> nameToLabel = new Dictionary<string, int>();
    int currentLabel = 0;
    
    try
    {
        string path = Directory.GetCurrentDirectory() + @"\TrainedImages";
        string[] files = Directory.GetFiles(path, "*.jpg", SearchOption.AllDirectories);
        foreach (var file in files)
        {
            Image<Gray, Byte> trainedImage = new Image<Gray, byte>(file);
            TrainedFaces.Add(trainedImage);
            
            string name = file.Split('\\').Last().Split('_')[0];
            // 同一姓名对应同一标签
            if (!nameToLabel.ContainsKey(name))
            {
                nameToLabel[name] = currentLabel;
                PersonsNames.Add(name);
                currentLabel++;
            }
            PersonsLabels.Add(nameToLabel[name]);
            
            ImagesCount++;
            Debug.WriteLine(ImagesCount + ". " + name);
        }
        
        if (TrainedFaces.Count > 0)
        {
            recognizer = new EigenFaceRecognizer(TrainedFaces.Count, Threshold);
            recognizer.Train(TrainedFaces.ToArray(), PersonsLabels.ToArray());
            isTrained = true;
        }
        else
        {
            MessageBox.Show("训练目录中没有人脸图像");
            isTrained = false;
        }
        
        Debug.WriteLine(ImagesCount);
        Debug.WriteLine(isTrained);
        return isTrained;
    }
    catch (Exception ex)
    {
        isTrained = false;
        MessageBox.Show("训练失败: " + ex.Message);
        return isTrained;
    }
}

其他潜在优化点

  • Thread.Sleep(1000)会阻塞UI线程导致界面卡顿,建议改用异步延时或单独线程处理图像保存
  • 人脸检测DetectMultiScale可增加最小尺寸参数minSize = new Size(100,100),避免检测过小的无效区域
  • 保存图像时的文件名可增加毫秒级时间戳或随机数,避免文件名重复

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 05:05:01