如何用python 做网站可以做平面设计兼职的网站
如何用python 做网站,可以做平面设计兼职的网站,ps培训班一般学费多少钱,网架结构厂家电话.NET Core集成MogFace-large#xff1a;C#开发跨平台人脸检测应用
最近在做一个社区门禁系统的原型#xff0c;需要快速实现一个能准确识别人脸的模块。团队主要技术栈是C#和.NET#xff0c;一开始大家还担心是不是得用Python才能搞定AI模型。结果一研究#xff0c;发现用….NET Core集成MogFace-largeC#开发跨平台人脸检测应用最近在做一个社区门禁系统的原型需要快速实现一个能准确识别人脸的模块。团队主要技术栈是C#和.NET一开始大家还担心是不是得用Python才能搞定AI模型。结果一研究发现用.NET Core配合ONNX Runtime调用像MogFace-large这样的人脸检测模型不仅完全可行而且体验相当顺畅。这篇文章我就想跟你分享一下怎么在熟悉的.NET环境里把前沿的AI能力集成进来。我们会从创建一个Web API服务开始再到开发一个WPF桌面应用手把手带你走一遍流程。你会发现用C#写AI应用和你平时写业务代码的感觉差不多门槛并没有想象中那么高。1. 为什么要在.NET里做人脸检测你可能已经用过一些云端的人脸识别服务它们确实方便但涉及到数据隐私、网络延迟或者离线使用的场景时本地部署模型就成了刚需。MogFace-large是一个在学术界和工业界都备受认可的人脸检测模型它的特点就是检测精度高尤其是在复杂场景、小人脸、遮挡人脸的情况下表现很出色。那么为什么选择.NET Core来做这件事呢首先.NET Core是跨平台的你写的代码可以在Windows、Linux、macOS上运行这为部署提供了极大的灵活性。其次对于广大C#开发者来说能在自己熟悉的技术栈里引入AI能力意味着更快的开发速度、更低的维护成本以及更好的团队协作。最后通过ONNX Runtime这个高性能推理引擎.NET应用可以高效地运行各种预训练的模型打通了与Python AI生态的壁垒。简单来说这套方案的核心价值就是让你用最熟悉的C#语言和.NET工具链快速构建出高性能、可跨平台部署的智能应用。2. 环境准备与项目搭建在开始写代码之前我们需要把“厨房”收拾好。整个过程不复杂跟着步骤走就行。2.1 准备模型文件首先你需要获取MogFace-large的模型文件。通常模型会以.onnx格式提供这是ONNX开放神经网络交换格式可以被多种推理引擎识别。你可以从模型的官方仓库或相关开源社区找到它。假设你下载到的文件名为mogface_large.onnx把它放到你项目中的一个目录下比如Assets/Models。2.2 创建ASP.NET Core Web API项目我们首先创建一个提供人脸检测服务的Web API。打开命令行或Visual Studio创建一个新的Web API项目dotnet new webapi -n MogFaceDetectionApi cd MogFaceDetectionApi然后我们需要安装两个核心的NuGet包dotnet add package Microsoft.ML.OnnxRuntime dotnet add package SixLabors.ImageSharpMicrosoft.ML.OnnxRuntime是微软官方维护的ONNX Runtime .NET绑定它负责加载模型并执行推理。SixLabors.ImageSharp是一个强大且跨平台的图像处理库我们将用它来读取和处理图片。2.3 创建WPF桌面应用项目接下来我们再创建一个WPF项目作为客户端。在解决方案根目录下执行dotnet new wpf -n MogFaceDetectionWpf同样进入WPF项目目录安装必要的包。除了ONNX Runtime和ImageSharpWPF项目通常还需要引入Microsoft.Extensions.Http来调用我们刚创建的Web API。cd MogFaceDetectionWpf dotnet add package Microsoft.ML.OnnxRuntime dotnet add package SixLabors.ImageSharp dotnet add package Microsoft.Extensions.Http现在你的解决方案里应该有两个项目一个Web API一个WPF客户端。基础架子就搭好了。3. 构建人脸检测Web API服务Web API将作为我们的人脸检测引擎它接收图片返回检测到的人脸位置信息。我们采用依赖注入的方式来管理模型这样更清晰、也便于测试。3.1 创建模型推理服务在MogFaceDetectionApi项目中创建一个Services文件夹并添加一个接口和它的实现类。首先定义接口IFaceDetectionService.csusing System.Collections.Generic; using System.Threading.Tasks; namespace MogFaceDetectionApi.Services { public interface IFaceDetectionService { TaskListFaceDetectionResult DetectFacesAsync(byte[] imageData); } public class FaceDetectionResult { public float X { get; set; } // 人脸框左上角X坐标归一化 public float Y { get; set; } // 人脸框左上角Y坐标归一化 public float Width { get; set; } // 人脸框宽度归一化 public float Height { get; set; } // 人脸框高度归一化 public float Confidence { get; set; } // 检测置信度 } }然后实现这个接口MogFaceDetectionService.cs。这是核心部分包含了模型加载、图片预处理、推理和后处理。using Microsoft.ML.OnnxRuntime; using Microsoft.ML.OnnxRuntime.Tensors; using SixLabors.ImageSharp; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace MogFaceDetectionApi.Services { public class MogFaceDetectionService : IFaceDetectionService, IDisposable { private readonly InferenceSession _session; private const int ModelInputSize 640; // MogFace-large的典型输入尺寸请根据你的模型调整 private const float ConfidenceThreshold 0.5f; // 置信度阈值 public MogFaceDetectionService() { // 加载模型。在生产环境中路径应该通过配置如appsettings.json来管理。 var modelPath Assets/Models/mogface_large.onnx; var options new SessionOptions(); // 可以根据需要设置执行提供器例如 CUDA 或 TensorRT 以加速GPU推理 // options.AppendExecutionProvider_CUDA(0); _session new InferenceSession(modelPath, options); } public async TaskListFaceDetectionResult DetectFacesAsync(byte[] imageData) { // 1. 使用ImageSharp加载和预处理图片 using var image Image.LoadRgb24(imageData); // 调整大小并保持宽高比填充到模型输入尺寸 image.Mutate(x x.Resize(new ResizeOptions { Size new Size(ModelInputSize, ModelInputSize), Mode ResizeMode.Pad // 填充模式避免变形 })); // 2. 将图像数据转换为模型需要的张量格式 (1, 3, H, W) 且数值归一化到[0,1] var input new DenseTensorfloat(new[] { 1, 3, image.Height, image.Width }); for (int y 0; y image.Height; y) { var rowSpan image.GetPixelRowSpan(y); for (int x 0; x image.Width; x) { input[0, 0, y, x] rowSpan[x].R / 255.0f; // R通道 input[0, 1, y, x] rowSpan[x].G / 255.0f; // G通道 input[0, 2, y, x] rowSpan[x].B / 255.0f; // B通道 } } // 3. 准备输入运行模型推理 var inputs new ListNamedOnnxValue { NamedOnnxValue.CreateFromTensor(input, input) // “input”是模型输入节点名称需根据模型确定 }; using var results _session.Run(inputs); // 4. 解析输出结果 // MogFace输出格式可能包含框坐标、置信度等这里需要根据模型实际输出结构进行解析。 // 以下是一个示例性解析流程你需要根据实际的MogFace-large模型输出进行调整。 var boxesTensor results.FirstOrDefault(r r.Name boxes)?.AsTensorfloat(); var scoresTensor results.FirstOrDefault(r r.Name scores)?.AsTensorfloat(); var detections new ListFaceDetectionResult(); if (boxesTensor ! null scoresTensor ! null) { for (int i 0; i scoresTensor.Length; i) { if (scoresTensor[i] ConfidenceThreshold) { // 假设boxesTensor的shape为[1, N, 4]其中N是检测框数量 // 坐标格式可能是 [x1, y1, x2, y2] (左上角右下角) var baseIndex i * 4; var x1 boxesTensor[0, i, 0]; var y1 boxesTensor[0, i, 1]; var x2 boxesTensor[0, i, 2]; var y2 boxesTensor[0, i, 3]; detections.Add(new FaceDetectionResult { X x1, Y y1, Width x2 - x1, Height y2 - y1, Confidence scoresTensor[i] }); } } } // 注意返回的坐标是相对于预处理后图像640x640的归一化坐标。 // 在实际应用中你可能需要将这些坐标映射回原始图像的尺寸。 return detections; } public void Dispose() { _session?.Dispose(); } } }重要提示上面代码中模型的输入节点名称input、输出节点名称boxes,scores以及输出张量的具体形状必须根据你实际使用的mogface_large.onnx模型文件来确定。你需要使用Netron等工具打开模型文件查看其输入输出定义并相应调整代码。3.2 注册服务并创建控制器在Program.cs中将我们刚写的服务注册到依赖注入容器中using MogFaceDetectionApi.Services; var builder WebApplication.CreateBuilder(args); // 添加服务 builder.Services.AddControllers(); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); // 注册我们的人脸检测服务为单例因为InferenceSession创建成本较高。 builder.Services.AddSingletonIFaceDetectionService, MogFaceDetectionService(); var app builder.Build(); // 配置HTTP请求管道 if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run();接下来创建一个控制器FaceDetectionController.csusing Microsoft.AspNetCore.Mvc; using MogFaceDetectionApi.Services; using System.Threading.Tasks; namespace MogFaceDetectionApi.Controllers { [ApiController] [Route(api/[controller])] public class FaceDetectionController : ControllerBase { private readonly IFaceDetectionService _faceDetectionService; public FaceDetectionController(IFaceDetectionService faceDetectionService) { _faceDetectionService faceDetectionService; } [HttpPost(detect)] public async TaskIActionResult DetectFaces(IFormFile file) { if (file null || file.Length 0) { return BadRequest(No file uploaded.); } using var memoryStream new MemoryStream(); await file.CopyToAsync(memoryStream); var imageData memoryStream.ToArray(); var results await _faceDetectionService.DetectFacesAsync(imageData); return Ok(results); // 返回人脸框列表 } } }现在启动你的Web API项目你应该会有一个运行在https://localhost:5001或类似地址的服务并且有一个POST /api/facedetection/detect的端点可以调用。4. 开发WPF桌面客户端Web API服务跑起来后我们再来做一个简单的WPF客户端它可以选择本地图片调用API并把检测到的人脸框画出来。4.1 设计主界面修改MainWindow.xaml设计一个简单的界面Window x:ClassMogFaceDetectionWpf.MainWindow xmlnshttp://schemas.microsoft.com/winfx/2006/xaml/presentation xmlns:xhttp://schemas.microsoft.com/winfx/2006/xaml TitleMogFace Detection Client Height600 Width800 Grid Grid.RowDefinitions RowDefinition HeightAuto/ RowDefinition Height*/ /Grid.RowDefinitions StackPanel Grid.Row0 OrientationHorizontal Margin10 Button x:NameBtnSelectImage Content选择图片 ClickBtnSelectImage_Click Margin5/ Button x:NameBtnDetect Content检测人脸 ClickBtnDetect_Click Margin5 IsEnabledFalse/ TextBlock x:NameTbStatus Margin10,0 VerticalAlignmentCenter/ /StackPanel ScrollViewer Grid.Row1 HorizontalScrollBarVisibilityAuto VerticalScrollBarVisibilityAuto Image x:NameImgDisplay StretchNone Source{Binding DisplayImage}/ /ScrollViewer /Grid /Window4.2 实现后台逻辑修改MainWindow.xaml.cs文件。我们需要注入一个HTTP客户端并实现图片选择、调用API和绘制结果的功能。using Microsoft.Extensions.DependencyInjection; using System; using System.IO; using System.Net.Http; using System.Net.Http.Headers; using System.Net.Http.Json; using System.Windows; using System.Windows.Media; using System.Windows.Media.Imaging; namespace MogFaceDetectionWpf { public partial class MainWindow : Window { private readonly HttpClient _httpClient; private string _selectedImagePath; private BitmapImage _originalBitmap; // 定义一个人脸结果类对应API返回的数据结构 public class FaceDetectionResult { public float X { get; set; } public float Y { get; set; } public float Width { get; set; } public float Height { get; set; } public float Confidence { get; set; } } public MainWindow() { InitializeComponent(); // 创建并配置HttpClient _httpClient new HttpClient { BaseAddress new Uri(https://localhost:5001/) // 指向你的API地址 }; _httpClient.DefaultRequestHeaders.Accept.Clear(); _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(application/json)); } private void BtnSelectImage_Click(object sender, RoutedEventArgs e) { var openFileDialog new Microsoft.Win32.OpenFileDialog { Filter Image files (*.jpg; *.jpeg; *.png; *.bmp)|*.jpg; *.jpeg; *.png; *.bmp, Multiselect false }; if (openFileDialog.ShowDialog() true) { _selectedImagePath openFileDialog.FileName; _originalBitmap new BitmapImage(new Uri(_selectedImagePath)); ImgDisplay.Source _originalBitmap; BtnDetect.IsEnabled true; TbStatus.Text $已选择: {Path.GetFileName(_selectedImagePath)}; } } private async void BtnDetect_Click(object sender, RoutedEventArgs e) { if (string.IsNullOrEmpty(_selectedImagePath) || _originalBitmap null) return; BtnDetect.IsEnabled false; TbStatus.Text 检测中...; try { // 1. 读取图片文件并准备上传 using var fileStream File.OpenRead(_selectedImagePath); using var content new MultipartFormDataContent(); using var fileContent new StreamContent(fileStream); fileContent.Headers.ContentType new MediaTypeHeaderValue(image/jpeg); // 根据实际类型调整 content.Add(fileContent, file, Path.GetFileName(_selectedImagePath)); // 2. 调用Web API var response await _httpClient.PostAsync(api/facedetection/detect, content); response.EnsureSuccessStatusCode(); var faceResults await response.Content.ReadFromJsonAsyncFaceDetectionResult[](); // 3. 在图片上绘制人脸框 DrawFaceRectangles(faceResults); TbStatus.Text $检测完成发现 {faceResults?.Length ?? 0} 张人脸。; } catch (HttpRequestException ex) { MessageBox.Show($调用API失败: {ex.Message}, 错误, MessageBoxButton.OK, MessageBoxImage.Error); TbStatus.Text 检测失败; } catch (Exception ex) { MessageBox.Show($发生错误: {ex.Message}, 错误, MessageBoxButton.OK, MessageBoxImage.Error); TbStatus.Text 检测失败; } finally { BtnDetect.IsEnabled true; } } private void DrawFaceRectangles(FaceDetectionResult[] faces) { if (faces null || faces.Length 0 || _originalBitmap null) return; // 创建一个DrawingVisual来绘制矩形 var drawingVisual new DrawingVisual(); using (var drawingContext drawingVisual.RenderOpen()) { // 先绘制原始图片 drawingContext.DrawImage(_originalBitmap, new Rect(0, 0, _originalBitmap.PixelWidth, _originalBitmap.PixelHeight)); var pen new Pen(Brushes.Red, 2.0); var typeface new Typeface(Arial); var fontSize 12.0; foreach (var face in faces) { // 注意API返回的坐标是归一化坐标需要转换到原始图片像素坐标。 // 这里假设API返回的是相对于预处理后图像的坐标且我们直接映射。 // 更严谨的做法是让API返回原始图像坐标或在客户端根据预处理方式反向计算。 double x face.X * _originalBitmap.PixelWidth; double y face.Y * _originalBitmap.PixelHeight; double width face.Width * _originalBitmap.PixelWidth; double height face.Height * _originalBitmap.PixelHeight; var rect new Rect(x, y, width, height); drawingContext.DrawRectangle(null, pen, rect); // 绘制置信度文本 var text new FormattedText($Face: {face.Confidence:F2}, System.Globalization.CultureInfo.CurrentCulture, FlowDirection.LeftToRight, typeface, fontSize, Brushes.Lime, VisualTreeHelper.GetDpi(this).PixelsPerDip); drawingContext.DrawText(text, new Point(x, y - fontSize - 2)); } } // 将DrawingVisual渲染为BitmapSource并显示 var renderTarget new RenderTargetBitmap( (int)_originalBitmap.PixelWidth, (int)_originalBitmap.PixelHeight, _originalBitmap.DpiX, _originalBitmap.DpiY, PixelFormats.Pbgra32); renderTarget.Render(drawingVisual); ImgDisplay.Source renderTarget; } } }现在分别运行你的Web API项目和WPF项目。在WPF客户端里选择一张带人脸的图片点击“检测人脸”稍等片刻你应该就能看到图片上被标出了红色的矩形框并且显示了置信度。5. 总结与拓展思考走完这一趟你会发现在.NET生态里集成一个像MogFace-large这样的AI模型核心流程其实很清晰准备模型、用ONNX Runtime加载、处理输入数据、执行推理、解析输出。无论是封装成Web API供多方调用还是直接内嵌到WPF、WinForms甚至Blazor的客户端应用里模式都大同小异。实际用下来这种方式的优势很明显。开发效率高因为全程使用C#调试、部署都和普通的.NET应用无异。性能也不错ONNX Runtime做了大量优化并且支持CPU、GPU等多种硬件后端。最重要的是它给了.NET开发者一条拥抱AI的捷径让你不必为了一个智能功能而切换整个技术栈。当然在实际项目中你可能会遇到更多需要考虑的点。比如模型文件可能很大如何优雅地打包和分发对于实时视频流的人脸检测如何优化性能如何将检测到的人脸坐标与原始高分辨率图片准确对应这些问题都有成熟的解决方案比如使用模型压缩技术、利用GPU加速、设计更精细的坐标映射逻辑等。如果你正在为你的.NET应用寻找智能化的可能性不妨从这样一个具体的人脸检测功能开始尝试。它或许就是你打开AI赋能业务那扇门的钥匙。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。