效果
项目
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();}}
}
下载
源码下载