基于C# winform实现PP-HumanSeg人像分割替换背景色更换背景色
图像分割与人像抠图工具
这是是一个基于 .NET Framework 的桌面演示应用程序,主要用于图像分割与人像抠图任务,集成 PaddlePaddle 模型进行推理处理。
效果展示如下:
界面代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using OpenCvSharp;namespace FIRC
{public partial class Form1 : Form{Color backColor = Color.Red;Mat src = new Mat();Mat resultMat = new Mat();//一共提供4种模型,切换只需要修改对应文件夹PaddleSegManager detector = new PaddleSegManager(Application.StartupPath+ "\\weights\\modnet-mobilenetv2");public Form1(){InitializeComponent();}private void button1_Click(object sender, EventArgs e){OpenFileDialog openFileDialog = new OpenFileDialog();openFileDialog.Filter = "图文件(*.*)|*.jpg;*.png;*.jpeg;*.bmp";openFileDialog.RestoreDirectory = true;openFileDialog.Multiselect = false;if (openFileDialog.ShowDialog() == DialogResult.OK){src = Cv2.ImRead(openFileDialog.FileName);pictureBox1.Image = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(src);}}private void button2_Click(object sender, EventArgs e){if(pictureBox1.Image==null){return;}Stopwatch sw = new Stopwatch();sw.Start();resultMat = detector.Run(src);sw.Stop();this.Text = "耗时" + sw.Elapsed.TotalSeconds + "秒";pictureBox2.Image= OpenCvSharp.Extensions.BitmapConverter.ToBitmap(resultMat); //Mat转Bitmap}private void Form1_Load(object sender, EventArgs e){}private void btn_video_Click(object sender, EventArgs e){var capture = new VideoCapture(0);if (!capture.IsOpened()){Console.WriteLine("video not open!");return;}Mat frame = new Mat();var sw = new Stopwatch();int fps = 0;while (true){capture.Read(frame);if (frame.Empty()){Console.WriteLine("data is empty!");break;}sw.Start();resultMat = detector.Run(frame);sw.Stop();fps = Convert.ToInt32(1 / sw.Elapsed.TotalSeconds);sw.Reset();Cv2.PutText(resultMat, "FPS=" + fps, new OpenCvSharp.Point(30, 30), HersheyFonts.HersheyComplex, 1.0, new Scalar(255, 0, 0), 3);//显示结果Cv2.ImShow("Result", resultMat);int key = Cv2.WaitKey(10);if (key == 27)break;}capture.Release();}private void btn_choose_color_Click(object sender, EventArgs e){if(colorDialog1.ShowDialog()==DialogResult.OK){backColor = colorDialog1.Color;}}private void btn_replace_backgroundcolor_Click(object sender, EventArgs e){if (pictureBox1.Image == null){return;}// 获取分割结果图像(灰度图)Mat mask = resultMat;// 确保mask是单通道图像if (mask.Channels() != 1){Cv2.CvtColor(mask, mask, ColorConversionCodes.BGR2GRAY);}// 将mask归一化到0-1范围Mat normalizedMask = new Mat();mask.ConvertTo(normalizedMask, MatType.CV_32FC1, 1.0 / 255);// 原始图像Mat original = src.Clone();// 调整mask尺寸与原图一致if (normalizedMask.Size() != original.Size()){Cv2.Resize(normalizedMask, normalizedMask, original.Size());}// 创建背景图像(使用选定的颜色)Mat background = new Mat(original.Size(), MatType.CV_8UC3, new Scalar(backColor.B, backColor.G, backColor.R));// 将mask扩展为3通道Mat[] maskChannels = new Mat[3] { normalizedMask, normalizedMask, normalizedMask };Mat mask3Channel = new Mat();Cv2.Merge(maskChannels, mask3Channel);// 计算最终图像:original * mask + background * (1 - mask)Mat result = new Mat();Cv2.AddWeighted(original, 1.0, background, 0.0, 0.0, result); // 先复制original到result// 应用maskMat foreground = new Mat();Cv2.Multiply(original, mask3Channel, foreground, 1.0, MatType.CV_8UC3);Mat backgroundMask = new Mat();Mat invertedMask = new Mat();Cv2.Subtract(new Scalar(1.0, 1.0, 1.0), mask3Channel, invertedMask);Cv2.Multiply(background, invertedMask, backgroundMask, 1.0, MatType.CV_8UC3);Mat finalResult = new Mat();Cv2.Add(foreground, backgroundMask, finalResult);// 显示结果pictureBox2.Image = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(finalResult);// 释放资源normalizedMask.Dispose();original.Dispose();background.Dispose();mask3Channel.Dispose();result.Dispose();foreground.Dispose();backgroundMask.Dispose();invertedMask.Dispose();finalResult.Dispose();foreach (var channel in maskChannels){channel.Dispose();}}}
}
项目概述
核心功能
- 图像人像分割(支持多款 MODNet 和 PP-Matting 系列模型)
- 基于 Paddle Inference 的本地模型推理
- 模型配置管理(通过 YAML 文件加载部署参数)
- Windows 桌面图形界面操作(WinForms)
目标用户
需要本地化、轻量级图像分割工具的开发者或终端用户。
技术架构
WinForms 客户端 → PaddleSegManager(业务逻辑层) → Sdcb.PaddleInference(Paddle 封装层) → Paddle 模型(YAML + 权重)
组件交互
- [Form1](file:///c:/Users/Administrator/Downloads/FIRC/Form1.cs#L12-L113) 负责 UI 事件响应和图像显示
- [PaddleSegManager](file:///c:/Users/Administrator/Downloads/FIRC/PaddleSegManager.cs#L10-L125) 封装模型初始化、推理执行和结果后处理
- 通过 Sdcb.PaddleInference 调用原生 Paddle 库进行推理
- 使用 YamlDotNet 解析 deploy.yaml 配置文件
技术栈
- 前端: Windows Forms (.NET Framework 4.7.2)
- 后端逻辑: C#
- 模型推理: Sdcb.PaddleInference 3.0.1(PaddlePaddle .NET 封装)
- 图像处理: OpenCvSharp
- 配置解析: YamlDotNet 16.3.0
- 依赖管理: NuGet 包管理
功能特性
-
图像分割功能
- 支持多种预训练模型(MODNet 和 PP-Matting 系列)
- 实时摄像头人像分割
- 图像背景色替换
-
支持的模型
- modnet-hrnet_w18
- modnet-mobilenetv2
- ppmatting-hrnet_w18-human_512
- ppmattingv2-stdc1-human_512
-
界面操作
- 图片选择与显示
- 分割结果展示
- 背景颜色自定义
- 实时摄像头分割演示
使用说明
基本操作流程
- 点击"选择图片"按钮选择待处理的图像文件
- 点击"开始检测"按钮进行图像分割
- 点击"选择背景色"按钮选择想要的背景颜色
- 点击"替换背景色"按钮将分割图像的背景替换为选定颜色
实时摄像头分割
点击"摄像头实时分割"按钮可以启动摄像头并实时进行人像分割。
项目结构
FIRC/
├── bin/x64/Debug/
│ ├── weights/ # 模型权重文件
│ │ ├── modnet-hrnet_w18/
│ │ ├── modnet-mobilenetv2/
│ │ ├── ppmatting-hrnet_w18-human_512/
│ │ └── ppmattingv2-stdc1-human_512/
│ └── *.dll # 依赖库文件
├── packages/ # NuGet 包
├── Form1.cs # 主窗体逻辑
├── Form1.Designer.cs # 窗体设计器
├── PaddleSegManager.cs # 模型推理管理器
└── Program.cs # 程序入口
开发环境
必需工具
- Visual Studio 2019 或更高版本
- .NET Framework 4.7.2 SDK
搭建开发环境
- 打开项目目录中的解决方案文件
- 安装所需 NuGet 包(可通过
nuget restore
或 VS 自动恢复) - 确保 bin/x64/Debug/weights/ 下存在对应模型文件夹及 deploy.yaml
- 编译并运行
构建与部署
- 构建命令:
msbuild FIRC.sln /p:Configuration=Debug /p:Platform="x64"
- 本地开发: 启动 Form1 即可测试图像分割功能
- 部署方式: 发布为 x64 Debug/Release 单机版应用,需包含 weights 文件夹
技术规范
模型输入尺寸预处理
使用PaddleSeg MODNet模型时,输入图像的尺寸必须调整为指定数值(如32)的倍数,以确保张量连接操作时各输入维度一致,避免InvalidArgumentError错误。
图像分割后处理
使用PaddleSeg MODNet等分割模型后,若需进行背景替换或图像合成:
- 将模型输出的单通道灰度分割图归一化到0-1范围作为透明蒙版
- 扩展单通道蒙版为三通道以匹配彩色图像维度
- 前景 = 原图 × 蒙版
- 背景 = 目标背景色 × (1 - 蒙版)
- 最终图像 = 前景 + 背景
- 保留蒙版的连续值特性以实现边缘平滑过渡
已知问题
- 未提供日志记录机制
- 缺少异常处理细节(如模型加载失败)
- 依赖大量本地二进制文件(Paddle 运行时未列出,可能隐式依赖系统环境)
- packages 目录存在于项目中,建议使用 PackageReference 方式替代 packages.config
源码地址:https://download.csdn.net/download/FL1623863129/88611588