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

基于C#与OpenCV的人脸识别登录问题:所有图片均返回100%相似度

人脸识别代码问题排查:所有图片返回100%相似度

核心问题分析

你的代码存在几个关键错误,直接导致所有图片都返回100%相似度:

  • 训练样本严重不足:EigenFaceRecognizer是基于特征脸的算法,仅用单张参考图训练的话,模型没有足够的特征维度区分不同人脸,会默认把任何输入都匹配到唯一的训练类别,距离计算完全失效。
  • 距离归一化逻辑完全错误:Predict方法返回的是PredictResult对象,你直接用对象本身参与计算是错误的,应该取result.Distance;而且硬编码用10000作为最大距离没有任何依据,这种归一化方式直接导致相似度计算失真。
  • 未提取人脸区域直接处理整图:没有先检测图片中的人脸,直接对整张图做特征提取,非人脸区域的像素会严重干扰识别结果,甚至让任何输入都被误判为匹配。
  • 参考图加载方式不合理:每次请求都重新加载本地绝对路径的参考图,不仅效率低,还会在生产环境引发路径访问问题。

修正后的代码示例

[HttpPost]
public IActionResult ReconhecerImagem([FromBody] ImagemDTO imagemDTO)
{
    // 1. Base64转字节数组并加载图片
    string base64String = imagemDTO.ImagemBase64.Replace(" ", "+");
    byte[] imageData = System.Convert.FromBase64String(base64String);
    Mat inputImage = Cv2.ImDecode(imageData, ImreadModes.Color);

    // 2. 加载人脸检测器(需提前准备haar级联分类器文件,比如haarcascade_frontalface_default.xml)
    string faceCascadePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "haarcascade_frontalface_default.xml");
    CascadeClassifier faceDetector = new CascadeClassifier(faceCascadePath);

    // 3. 检测输入图片中的人脸
    Mat grayInput = new Mat();
    Cv2.CvtColor(inputImage, grayInput, ColorConversionCodes.BGR2GRAY);
    Rect[] inputFaces = faceDetector.DetectMultiScale(grayInput, 1.1, 3);
    if (inputFaces.Length == 0)
    {
        return Ok(new { success = false, message = "未检测到人脸" });
    }

    // 4. 加载并检测参考图片中的人脸
    Mat referenceImage = Cv2.ImRead(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Foto.jpg"), ImreadModes.Color);
    Mat grayReference = new Mat();
    Cv2.CvtColor(referenceImage, grayReference, ColorConversionCodes.BGR2GRAY);
    Rect[] referenceFaces = faceDetector.DetectMultiScale(grayReference, 1.1, 3);
    if (referenceFaces.Length == 0)
    {
        return Ok(new { success = false, message = "参考图片未检测到人脸" });
    }

    // 5. 提取人脸区域并统一尺寸
    Size faceSize = new Size(150, 150);
    Mat inputFace = new Mat(grayInput, inputFaces[0]);
    Cv2.Resize(inputFace, inputFace, faceSize);
    Mat referenceFace = new Mat(grayReference, referenceFaces[0]);
    Cv2.Resize(referenceFace, referenceFace, faceSize);

    // 6. 准备训练数据(至少需要同一人的3-5张不同样本,示例中可补充更多)
    // 生产环境需提前训练模型并序列化存储,不要每次请求都训练
    Mat[] trainImages = new[] { referenceFace, /* 添加同一人的其他样本图 */ };
    int[] trainLabels = new[] { 1, /* 同一人标签保持一致 */ };
    var recognizer = EigenFaceRecognizer.Create();
    recognizer.Train(trainImages, trainLabels);

    // 7. 执行人脸预测并计算合理相似度
    PredictResult result = recognizer.Predict(inputFace);
    
    // EigenFace的Distance越小表示越相似,根据实际测试调整阈值(比如匹配时Distance<800)
    bool isMatch = result.Label == 1 && result.Distance < 800;
    // 示例相似度计算,需根据实际测试的距离范围调整比例
    double similarity = isMatch ? 100 - (result.Distance / 800) * 20 : 0;

    return Ok(new { success = isMatch, similarity = Math.Round(similarity, 2) });
}

public class ImagemDTO
{
    public string ImagemBase64 { get; set; }
}

额外注意事项

  • 必须下载OpenCV的haar级联分类器文件(比如haarcascade_frontalface_default.xml),放在项目目录中确保路径正确。
  • 生产环境不要每次请求都训练模型:提前收集足够的用户样本,训练好后用recognizer.Save()序列化保存,请求时用recognizer.Load()加载已训练模型,避免重复训练损耗性能。
  • EigenFace对光照、角度变化敏感,若场景要求高,建议改用LBPHFaceRecognizer(对局部特征更鲁棒)或基于深度学习的预训练模型(OpenCV的DNN模块可加载)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 13:14:53