C# PaddleInference.PP-HumanSeg 人像分割 替换背景色

效果

项目

VS2022+.net4.8+OpenCvSharp4+Sdcb.PaddleInference

包含4个分割模型

modnet-hrnet_w18

modnet-mobilenetv2

ppmatting-hrnet_w18-human_512

ppmattingv2-stdc1-human_512

代码

复制代码
using OpenCvSharp;
using Sdcb.PaddleInference;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using YamlDotNet.RepresentationModel;
 
namespace PaddleInference.PP_HumanSeg_人像分割_替换背景色
{
    public class PaddleSeger : IDisposable
    {
        private readonly PaddlePredictor _p;
        public PaddleSeger(PaddleConfig config, string deployYamlPath)
            : this(config.CreatePredictor(), deployYamlPath)
        {
        }
        public PaddleSeger(PaddlePredictor predictor, string deployYamlPath)
        {
            _p = predictor;
            var yaml = new YamlStream();
            using (FileStream ymlFile = File.OpenRead(deployYamlPath))
                yaml.Load(new StreamReader(ymlFile));
            YamlDocument doc = yaml.Documents[0];
        }
        public PaddleSeger(string modelDir) : this(PaddleConfig.FromModelFiles(
            Path.Combine(modelDir, "model.pdmodel"),
            Path.Combine(modelDir, "model.pdiparams")).Apply(PaddleDevice.Mkldnn()),
            Path.Combine(modelDir, "deploy.yaml"))
        {
        }
        public Mat Run(Mat src)
        {
            Mat dest;
            using (PaddleTensor input = _p.GetInputTensor(_p.InputNames[0]))
            {
                Mat bgr = src.CvtColor(ColorConversionCodes.BGR2RGB);
                Mat normalized = Normalize(bgr);
                float[] data = ExtractMat(normalized);
                normalized.Dispose();
                bgr.Dispose();
                input.Shape = new int[] { 1, 3, src.Rows, src.Cols };
                input.SetData(data);
            }
            if (!_p.Run())
            {
                throw new Exception("PaddlePredictor(Seger) run failed.");
            }
            using (PaddleTensor output = _p.GetOutputTensor(_p.OutputNames[0]))
            {
                float[] rawData = output.GetData<float>();
                byte[] data = Array.ConvertAll(rawData, d => (byte)(d * 255));
                GCHandle gc = GCHandle.Alloc(data, GCHandleType.Pinned);
                dest = new Mat(output.Shape[2], output.Shape[3], MatType.CV_8UC1, gc.AddrOfPinnedObject());
                gc.Free();
            }
            return dest;
        }
        private static Mat Normalize(Mat src)
        {
            Mat normalized = new Mat();
            src.ConvertTo(normalized, MatType.CV_32FC3, 1.0 / 255);
            Mat[] bgr = normalized.Split();
            float[] scales = new[] { 2.0f, 2.0f, 2.0f };
            float[] means = new[] { 0.5f, 0.5f, 0.5f };
            for (int i = 0; i < bgr.Length; ++i)
            {
                bgr[i].ConvertTo(bgr[i], MatType.CV_32FC1, 1.0 * scales[i], (0.0 - means[i]) * scales[i]);
            }
            normalized.Dispose();
            Mat dest = new Mat();
            Cv2.Merge(bgr, dest);
            foreach (Mat channel in bgr)
            {
                channel.Dispose();
            }
            return dest;
        }
        internal static float[] ExtractMat(Mat src)
        {
            int rows = src.Rows;
            int cols = src.Cols;
            float[] result = new float[rows * cols * 3];
            GCHandle resultHandle = default;
            try
            {
                resultHandle = GCHandle.Alloc(result, GCHandleType.Pinned);
                IntPtr resultPtr = resultHandle.AddrOfPinnedObject();
                for (int i = 0; i < src.Channels(); ++i)
                {
                    Mat dest = new Mat(rows, cols, MatType.CV_32FC1, resultPtr + i * rows * cols * sizeof(float));
                    Cv2.ExtractChannel(src, dest, i);
                    dest.Dispose();
                }
            }
            finally
            {
                resultHandle.Free();
            }
            return result;
        }
        public void Dispose()
        {
            _p.Dispose();
        }
    }
}

下载

源码下载

相关推荐
亚马逊云开发者17 分钟前
Amazon Q Developer 结合 MCP 实现智能化云成本分析
人工智能
知了一笑22 分钟前
从经典产品看大模型方向
人工智能·aigc·产品
MuYiLuck1 小时前
【Spring Ai框架】
java·人工智能·spring
hllqkbb1 小时前
图像分类-动手学计算机视觉10
计算机视觉·分类·数据挖掘
音视频牛哥1 小时前
Android平台RTSP播放器选型指南:从开源方案到跨平台低延迟专业SDK
android·人工智能·音视频·大牛直播sdk·android rtsp播放器·安卓rtsp播放器·安卓播放rtsp流
Monkey PilotX2 小时前
把 7B 模型塞进车规级芯片:LoRA 在自动驾驶中的极限调参指南
人工智能·机器学习·自动驾驶
不大姐姐AI智能体2 小时前
最新Coze(扣子)智能体工作流:用Coze实现「图片生成-视频制作」全自动化,3分钟批量产出爆款内容
运维·人工智能·经验分享·自动化·aigc·视频
NewCarRen2 小时前
模型驱动的自动驾驶AI系统全生命周期安全保障
人工智能·安全·自动驾驶·汽车
音视频牛哥2 小时前
从感知到执行:人形机器人低延迟视频传输与多模态同步方案解析
网络·人工智能·深度学习·大牛直播sdk·机器人视觉·人形机器人·智能机器人