2025-06-06 16:00:39 +08:00

223 lines
7.8 KiB
C#

using AlibabaCloud.SDK.Facebody20191230.Models;
using AlibabaCloud.TeaUtil.Models;
using AutoMapper;
using Confluent.Kafka;
using DlibDotNet;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.ML;
using Microsoft.ML.Data;
using Microsoft.ML.Transforms.Onnx;
using Tea;
using VOL.Business.IServices.School;
using VOL.Core.CacheManager;
using VOL.Core.Configuration;
using VOL.Core.Extensions.AutofacManager;
using VOL.Model;
using VOL.System.IRepositories;
namespace VOL.Business.Services.School
{
public class FaceDetectService : IFaceDetectService, IDependency
{
#region
private readonly IMapper _mapper;
private readonly ICacheService _cacheService;
private readonly IS_StudentRepository _studentRepository;
private readonly IWebHostEnvironment _environment;
[ActivatorUtilitiesConstructor]
public FaceDetectService(IMapper mapper,
ICacheService cacheService,
IS_StudentRepository studentRepository, IWebHostEnvironment environment)
{
_mapper = mapper;
_cacheService = cacheService;
_studentRepository = studentRepository;
_environment = environment;
}
public async Task<StudentPageListModel> Face(string base64)
{
if (string.IsNullOrWhiteSpace(base64))
throw new FileNotFoundException("base64为空");
var res = new StudentPageListModel();
var students = await _studentRepository.FindAsIQueryable(x => x.ClassId == 1).Select(x => new StudentPageListModel()
{
GradeId = 1,
GradeName = "一年级",
ClassName = "一班",
ClassId = x.ClassId,
Age = x.Age,
HeartRateId = x.HeartRateId,
HeartRateFrontNo = x.HeartRateFrontNo,
Photo = x.Photo,
RopeSkipQRCode = x.RopeSkipQRCode,
SchoolRollNo = x.SchoolRollNo,
Sex = x.Sex,
StudentName = x.StudentName,
StudentStatus = x.StudentStatus,
StudentNo = x.StudentNo
}).ToListAsync();
foreach (var student in students)
{
string imagePath = Path.Combine(_environment.WebRootPath, student.Photo);
string imageDataB = ConvertImageToBase64(imagePath);
if (string.IsNullOrWhiteSpace(imageDataB))
continue;
var result = await FaceDetect(base64, imageDataB);
if (result)
{
res = student;
break;
}
}
return res;
}
#endregion
public async Task<StudentPageListModel> GetStudentDetails(IFormFile file, int classId)
{
var res = new StudentPageListModel();
string imageDataA = await ConvertFileToBase64Async(file);
var students = await _studentRepository.FindAsIQueryable(x => x.ClassId == classId).Select(x => new StudentPageListModel()
{
ClassId = x.ClassId,
Age = x.Age,
HeartRateId = x.HeartRateId,
HeartRateFrontNo = x.HeartRateFrontNo,
Photo = x.Photo,
RopeSkipQRCode = x.RopeSkipQRCode,
SchoolRollNo = x.SchoolRollNo,
Sex = x.Sex,
StudentName = x.StudentName,
StudentStatus = x.StudentStatus,
StudentNo = x.StudentNo
}).ToListAsync();
var tasks = new List<Task>();
using (var semaphore = new SemaphoreSlim(5)) // 限制并发数为5
{
foreach (var student in students)
{
await semaphore.WaitAsync();
if (res.StudentNo != null)
{
semaphore.Release();
break;
}
tasks.Add(Task.Run(async () =>
{
try
{
string imagePath = Path.Combine(_environment.WebRootPath, student.Photo);
string imageDataB = _cacheService.Get(imagePath); // 从缓存中获取图片数据
if (imageDataB == null) // 如果缓存中没有图片数据,则从文件中读取
{
imageDataB = ConvertImageToBase64(imagePath);
_cacheService.Add(imagePath, imageDataB); // 将图片数据写入缓存
}
if (imageDataB != null)
{
var result = await FaceDetect(imageDataA, imageDataB);
if (result)
{
lock (res)
{
if (res.StudentNo == null) // 双重检查
{
res = student;
}
}
}
}
}
finally
{
semaphore.Release();
}
}));
}
await Task.WhenAny(tasks);
}
return res;
}
private async Task<string> ConvertFileToBase64Async(IFormFile file)
{
if (file == null || file.Length == 0)
{
throw new ArgumentNullException("上传文件为空");
}
using (var memoryStream = new MemoryStream())
{
await file.CopyToAsync(memoryStream);
byte[] fileBytes = memoryStream.ToArray();
string base64String = Convert.ToBase64String(fileBytes);
return base64String;
}
}
private string ConvertImageToBase64(string imagePath)
{
if (File.Exists(imagePath))
{
byte[] imageBytes = File.ReadAllBytes(imagePath);
return Convert.ToBase64String(imageBytes);
}
else
{
return null; // 文件未找到,返回 null
}
}
private async Task<bool> FaceDetect(string imageDataA, string imageDataB)
{
AlibabaCloud.OpenApiClient.Models.Config config = new AlibabaCloud.OpenApiClient.Models.Config
{
AccessKeyId = AppSetting.ALiYunFaceDetect.AccessKeyId,
AccessKeySecret = AppSetting.ALiYunFaceDetect.SecretAccessKey,
Endpoint = AppSetting.ALiYunFaceDetect.Endpoint
};
var client = new AlibabaCloud.SDK.Facebody20191230.Client(config);
CompareFaceRequest compareFaceRequest = new CompareFaceRequest()
{
QualityScoreThreshold = (float)98.5,
ImageDataA = imageDataA,
ImageDataB = imageDataB
};
RuntimeOptions runtime = new RuntimeOptions();
try
{
CompareFaceResponse resp = await client.CompareFaceWithOptionsAsync(compareFaceRequest, runtime);
return resp.Body.Data.Confidence > 61;
}
catch (TeaException error)
{
throw new FileNotFoundException("识别图片出错", error);
}
}
}
}