• asp.net core 实现 face recognition 使用 tensorflowjs(源代码)


     功能描述

    1. 上传照片文件名及是系统要识别标签或是照片的名称(人物标识)
    2. 提取照片脸部特征值(调用 facemesh模型)
    3. 保存特征值添加样本(调用 knnClassifier)
    4. 测试上传的图片是否识别正确

    项目依赖的库

    源代码(neozhu/smartadmin.core.urf: Domain Driven Design (DDD) ultra-lightweight rapid development architecture(support .net 5.0) (github.com)

    tensorflowjs,在该项目中我使用了ml5js这个封装过的机器学习JavaScript类库, 使用起来更简单

    Demo

    http://106.52.105.140:6200/photos/index

    demo/123456

    代码实现

    上传照片功能

     asp.net core 参考CleanArchitecture 结构实现后台代码, 

     参考代码如下(具体请看源代码):

    namespace SmartAdmin.Application.Photos.Commands
    {
      public partial class AddPhotoCommand : IRequest<Result<int>>
      {
        public Stream Stream { get; set; }
        public string FileName { get; set; }
        public decimal Size { get; set; }
        public string Path { get; set; }
    
      }
      internal class AddPhotoCommandHandler : IRequestHandler<AddPhotoCommand, Result<int>>
      {
        private readonly IUnitOfWork unitOfWork;
        private readonly IPhotoService photoService;
    
        public AddPhotoCommandHandler(IUnitOfWork unitOfWork,
          IPhotoService photoService)
        {
          this.unitOfWork = unitOfWork;
          this.photoService = photoService;
        }
        public async Task<Result<int>> Handle(AddPhotoCommand request, CancellationToken cancellationToken)
        {
          var info = new DirectoryInfo(request.Path);
          if (!info.Exists)
          {
            info.Create();
          }
          using (FileStream outputFileStream = new FileStream(Path.Combine(request.Path,request.FileName), FileMode.Create))
          {
            request.Stream.CopyTo(outputFileStream);
            outputFileStream.Close();
          }
          var photo = new Photo()
          {
            Name = Path.GetFileNameWithoutExtension(request.FileName),
            Size = request.Size,
            Path = $"/photos/{request.FileName}",
          };
          this.photoService.Insert(photo);
          await this.unitOfWork.SaveChangesAsync();
          return await Result<int>.SuccessAsync(0, "保存成功");
        }
    
      }
    }
    

    facemesh模型提取照片中脸部特特信息

    扫描图片获取图片中脸部的特征信息以一个多维数组的形式保存到数据库中,这些特征值将用与下一步的KNN分类识别使用

     完成每一张照片中脸部信息的数字转化

    参考代码如下:

     function predict() {
          const img = document.getElementById('photo-canvas');
          facemesh.predict(img).then(faces => {
            console.log(faces)
            if (faces) {
              const canvas = document.getElementById("photo-canvas");
              const photoId=canvas.getAttribute("photo-id");
              const photoName=canvas.getAttribute("photo-name");
              console.log(canvas)
              var draw = canvas.getContext("2d");
              var mesh = faces[0].scaledMesh;
              console.log(mesh);
              /* highlight facial landmark points on canvas board */
              draw.fillStyle = "#00FF00";
              for (i = 0; i < mesh.length; i++) {
                var [x, y, z] = mesh[i];
                draw.fillRect(Math.round(x), Math.round(y), 2, 2);
              }
              updateLandmarks(photoId,JSON.stringify(mesh));
              knnClassifier.addExample(mesh, photoName);
              canvas.setAttribute("photo-mesh", JSON.stringify(mesh));
              $('#testbutton').attr('disabled', false);
            }
          });
        }
    
       function updateLandmarks(id,landmarks){
         $.post('/Photos/Update',{Id:id,Landmarks:landmarks}).done(res=>{
          console.log(res);
          reload();
         }).fail(res=>{
          $.messager.alert('更新失败', res, 'error');
         })
        } 

     添加分类识别样本数据

    facemesh模型只负责把照片中面部特征转换成一个数组,如果需要对每一张照片的数据再进行分类就需要用到KNN模型,添加的样本数据越多,识别的就越正确。

    参考代码:

    let knnClassifier =ml5.KNNClassifier();
        function training(){
           $.messager.progress({msg:'training....'});
           $.get('/Photos/GetAll').done(res=>{
            for(let i=0;i<50;i++){
            res.map(item=>{
            if(item.Landmarks){
            knnClassifier.addExample(JSON.parse(item.Landmarks), item.Name);
            }
            });
            }
            $.messager.progress('close')
               if(knnClassifier.getNumLabels()>0){
               knnClassifier.classify(JSON.parse(res[2].Landmarks),(err,result)=>{
                 console.log(result);
             })
           $('#testbutton').attr('disabled', false);
           }
           })
        }
    

    测试照片识别结果

    上传一张照片匹配维护的照片库中照片名称是否正确

     参考代码:

    function testPredict(){
          const img = document.getElementById('testphoto_img');
          facemesh.predict(img).then(faces => {
            console.log(faces)
            if (faces) {
              knnClassifier.classify(faces[0].scaledMesh,(err,result)=>{
              console.log(result);
              $.messager.alert('Result:',result.label);
              $('#testresult').text(result.label);
             })
            }
          });
        }

    到这里就全部完成了,对tensorflow感兴趣的朋友可以留言,下面有时间会继续更新,实现利用摄像头来识别人脸。

    对asp.net core CleanArchitecture 感兴趣的朋友可以从github下载,也可以留言交流,这个项目我也会继续更新,如果喜欢,请给个星星。

  • 相关阅读:
    Invalid CSRF Token 'null' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'.
    Qt 下快速读写Excel指南(尘中远)
    QT 那些事
    安卓环境下,通过QT调用jar包
    android使用C/C++调用SO库
    雷军曾定下目标,2017年将聚焦5大核心战略,分别是:黑科技、新零售、国际化、人工智能和互联网金融五大部分
    Maven和Gradle
    链接生成接口
    孤儿进程和僵尸进程
    Case when 的使用方法
  • 原文地址:https://www.cnblogs.com/neozhu/p/14925905.html
Copyright © 2020-2023  润新知