From cd61e4a36a316648016675888942beb71369a025 Mon Sep 17 00:00:00 2001 From: tanglong <842690096@qq.com> Date: Sat, 28 Feb 2026 09:17:18 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Wpf_AiSportsMicrospace/Common/Utils.cs | 109 +++++++++++++------------ 1 file changed, 57 insertions(+), 52 deletions(-) diff --git a/Wpf_AiSportsMicrospace/Common/Utils.cs b/Wpf_AiSportsMicrospace/Common/Utils.cs index 04d3d14..cd614d2 100644 --- a/Wpf_AiSportsMicrospace/Common/Utils.cs +++ b/Wpf_AiSportsMicrospace/Common/Utils.cs @@ -215,73 +215,78 @@ namespace Wpf_AiSportsMicrospace.Common LoadGifToCache(relativePath); return _cache.GetValueOrDefault(relativePath); } - public static List FacialRecognition(byte[] buffer, double[] xNorms) { - if (xNorms == null || xNorms.Length == 0) - throw new ArgumentException("xNorms 不能为空"); - - using var image = SharpImage.Image.Load(buffer); - - int imgWidth = image.Width; - int imgHeight = image.Height; - int rectHeight = imgHeight / 2; - - // 1. 排序中心点 - var sortedX = xNorms.OrderBy(x => x).ToList(); - int faceCount = sortedX.Count; - - // 2. 计算分割边界 - var splitXs = new List(); - for (int i = 0; i < sortedX.Count - 1; i++) - splitXs.Add((sortedX[i] + sortedX[i + 1]) / 2.0); - - // 3. 起止边界 - splitXs.Insert(0, 0.0); - splitXs.Add(1.0); - - // 4. 输出目录 - string imgDir = Path.Combine(AppContext.BaseDirectory, "img"); - Directory.CreateDirectory(imgDir); - - var studentInfos = new List(); - - // 5. 循环裁剪 + 同步识别 - for (int i = 0; i < faceCount; i++) + try { - double xStart = splitXs[i]; - double xEnd = splitXs[i + 1]; + if (xNorms == null || xNorms.Length == 0) + return null; // 不再抛异常,直接返回 null - int x1 = (int)(xStart * imgWidth); - int x2 = (int)(xEnd * imgWidth); - int w = Math.Max(1, x2 - x1); + using var image = SharpImage.Image.Load(buffer); - var cropRect = new Rectangle(x1, 0, w, rectHeight); + int imgWidth = image.Width; + int imgHeight = image.Height; + int rectHeight = imgHeight / 2; - using var cropped = image.Clone(ctx => ctx.Crop(cropRect)); + // 1. 排序中心点 + var sortedX = xNorms.OrderBy(x => x).ToList(); + int faceCount = sortedX.Count; - using var ms = new MemoryStream(); - cropped.Save(ms, new JpegEncoder()); - ms.Position = 0; + // 2. 计算分割边界 + var splitXs = new List(); + for (int i = 0; i < sortedX.Count - 1; i++) + splitXs.Add((sortedX[i] + sortedX[i + 1]) / 2.0); - string imgPath = Path.Combine(imgDir, $"crop_{i + 1}_{DateTime.Now:HHmmssfff}.jpg"); - File.WriteAllBytes(imgPath, ms.ToArray()); + // 3. 起止边界 + splitXs.Insert(0, 0.0); + splitXs.Add(1.0); - string base64 = Convert.ToBase64String(ms.ToArray()); + // 4. 输出目录 + string imgDir = Path.Combine(AppContext.BaseDirectory, "img"); + Directory.CreateDirectory(imgDir); - Console.WriteLine($"[{i + 1}] 范围: {xStart:0.00}-{xEnd:0.00}, 宽: {w}"); + var studentInfos = new List(); - // === 同步调用人脸识别接口 === - var result = FaceRecognitionAsync(base64); + // 5. 循环裁剪 + 同步识别 + for (int i = 0; i < faceCount; i++) + { + double xStart = splitXs[i]; + double xEnd = splitXs[i + 1]; - if (result != null) - studentInfos.Add(result); + int x1 = (int)(xStart * imgWidth); + int x2 = (int)(xEnd * imgWidth); + int w = Math.Max(1, x2 - x1); + + var cropRect = new Rectangle(x1, 0, w, rectHeight); + + using var cropped = image.Clone(ctx => ctx.Crop(cropRect)); + + using var ms = new MemoryStream(); + cropped.Save(ms, new JpegEncoder()); + ms.Position = 0; + + string imgPath = Path.Combine(imgDir, $"crop_{i + 1}_{DateTime.Now:HHmmssfff}.jpg"); + File.WriteAllBytes(imgPath, ms.ToArray()); + + string base64 = Convert.ToBase64String(ms.ToArray()); + + Console.WriteLine($"[{i + 1}] 范围: {xStart:0.00}-{xEnd:0.00}, 宽: {w}"); + + var result = FaceRecognitionAsync(base64); + + if (result != null) + studentInfos.Add(result); + } + + return studentInfos; + } + catch (Exception ex) + { + Console.WriteLine($"FacialRecognition 异常: {ex.Message}"); + return null; } - - return studentInfos; } - /// /// 调用人脸识别接口,返回学生信息 ///