CSharp: create cartoon image

ML.NET 可供你重新使用作为 .NET 开发人员已经拥有的所有知识、技能、代码和库,以便你可以轻松地将机器学习集成到 Web、移动、桌面、游戏和物联网应用中。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics.Eventing.Reader;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;
using Microsoft.ML.OnnxRuntime;
using Microsoft.ML.OnnxRuntime.Tensors;
using OpenCvSharp;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;




namespace WinFormsPhotoCartoonApp
{

    /// <summary>
    /// https://github.com/LiteraturePro/Photo2cartoon
    /// OpenCvSharp4.runtime.win
    /// OpenCvSharp4.Extensions
    /// OpenCvSharp4
    ///  Microsoft.ML.OnnxRuntime
    ///  CSharp create cartoon image 生成卡通像
    /// </summary>
    public partial class CartoonForm : Form
    {

        string fileFilter = "图片|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";
        string image_path = "";
        string startupPath;
        DateTime dt1 = DateTime.Now;
        DateTime dt2 = DateTime.Now;
        string model_path;
        Mat image;
        Mat result_image;
        int modelSize = 256;

        SessionOptions options;
        InferenceSession onnx_session;
        Tensor<float> input_tensor;
        List<NamedOnnxValue> input_ontainer;
        IDisposableReadOnlyCollection<DisposableNamedOnnxValue> result_infer;
        DisposableNamedOnnxValue[] results_onnxvalue;

        Tensor<float> result_tensors;
        float[] result_array;
        /// <summary>
        /// 
        /// </summary>
        public CartoonForm()
        {
            InitializeComponent();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Load(object sender, EventArgs e)
        {
            try
            {
                startupPath = System.Windows.Forms.Application.StartupPath;
                model_path = startupPath + "\\photo2cartoon_weights.onnx"; //https://github.com/LiteraturePro/Photo2cartoon

                // 创建输出会话,用于输出模型读取信息
                options = new SessionOptions();
                options.LogSeverityLevel = OrtLoggingLevel.ORT_LOGGING_LEVEL_INFO;
                // 设置为CPU上运行
                options.AppendExecutionProvider_CPU(0);

                // 创建推理模型类,读取本地模型文件
                onnx_session = new InferenceSession(model_path, options);

                // 输入Tensor
                input_tensor = new DenseTensor<float>(new[] { 1, 3, 256, 256 });

                // 创建输入容器
                input_ontainer = new List<NamedOnnxValue>();


                image_path = startupPath + "\\1.jpg";
                pictureBox1.Image = new Bitmap(image_path);
                image = new Mat(image_path);
            }
            catch (ArgumentException ex)
            {
                ex.Message.ToString();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnCreate_Click(object sender, EventArgs e)
        {
            try
            {
                if (image_path == "")
                {
                    return;
                }

                textBox1.Text = "";
                pictureBox2.Image = null;

                int oldwidth = image.Cols;
                int oldheight = image.Rows;

                //缩放图片大小
                int maxEdge = Math.Max(image.Rows, image.Cols);
                float ratio = 1.0f * modelSize / maxEdge;
                int newHeight = (int)(image.Rows * ratio);
                int newWidth = (int)(image.Cols * ratio);
                Mat resize_image = image.Resize(new OpenCvSharp.Size(newWidth, newHeight));
                int width = resize_image.Cols;
                int height = resize_image.Rows;

                if (width != modelSize || height != modelSize)
                {
                    resize_image = resize_image.CopyMakeBorder(0, modelSize - newHeight, 0, modelSize - newWidth, BorderTypes.Constant, new Scalar(255, 255, 255));
                }

                Cv2.CvtColor(resize_image, resize_image, ColorConversionCodes.BGR2RGB);

                // 输入Tensor
                for (int y = 0; y < resize_image.Height; y++)
                {
                    for (int x = 0; x < resize_image.Width; x++)
                    {
                        input_tensor[0, 0, y, x] = (resize_image.At<Vec3b>(y, x)[0] / 255f - 0.5f) / 0.5f;
                        input_tensor[0, 1, y, x] = (resize_image.At<Vec3b>(y, x)[1] / 255f - 0.5f) / 0.5f;
                        input_tensor[0, 2, y, x] = (resize_image.At<Vec3b>(y, x)[2] / 255f - 0.5f) / 0.5f;
                    }
                }

                //将 input_tensor 放入一个输入参数的容器,并指定名称
                input_ontainer.Add(NamedOnnxValue.CreateFromTensor("input", input_tensor));

                dt1 = DateTime.Now;
                //运行 Inference 并获取结果
                result_infer = onnx_session.Run(input_ontainer);
                dt2 = DateTime.Now;

                //将输出结果转为DisposableNamedOnnxValue数组
                results_onnxvalue = result_infer.ToArray();

                //读取第一个节点输出并转为Tensor数据
                result_tensors = results_onnxvalue[0].AsTensor<float>();

                result_array = result_tensors.ToArray();

                float[] temp_r = new float[256 * 256];
                float[] temp_g = new float[256 * 256];
                float[] temp_b = new float[256 * 256];

                Array.Copy(result_array, temp_r, 256 * 256);
                Array.Copy(result_array, 256 * 256, temp_g, 0, 256 * 256);
                Array.Copy(result_array, 256 * 256 * 2, temp_b, 0, 256 * 256);

                Mat rmat = new Mat(256, 256, MatType.CV_32F, temp_r);
                Mat gmat = new Mat(256, 256, MatType.CV_32F, temp_g);
                Mat bmat = new Mat(256, 256, MatType.CV_32F, temp_b);

                rmat = (rmat + 1f) * 127.5f;
                gmat = (gmat + 1f) * 127.5f;
                bmat = (bmat + 1f) * 127.5f;

                result_image = new Mat();
                Cv2.Merge(new Mat[] { bmat, gmat, rmat }, result_image);

                if (!result_image.Empty())
                {
                    //还原图像大小
                    if (width != modelSize || height != modelSize)
                    {
                        Rect rect = new Rect(0, 0, width, height);
                        result_image = result_image.Clone(rect);
                    }
                    result_image = result_image.Resize(new OpenCvSharp.Size(oldwidth, oldheight));

                    pictureBox2.Image = new Bitmap(result_image.ToMemoryStream());
                    textBox1.Text = "推理耗时:" + (dt2 - dt1).TotalMilliseconds + "ms";
                }
                else
                {
                    textBox1.Text = "无信息";
                }
            }
            catch(Exception ex)
            {
                ex.Message.ToString();
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnCheck_Click(object sender, EventArgs e)
        {


            try
            {
                OpenFileDialog ofd = new OpenFileDialog();
                ofd.Filter = fileFilter;
                if (ofd.ShowDialog() != DialogResult.OK) return;
                pictureBox1.Image = null;
                image_path = ofd.FileName;
                pictureBox1.Image = new Bitmap(image_path);
                textBox1.Text = "";
                image = new Mat(image_path);
                pictureBox2.Image = null;

            }
            catch (Exception ex)
            {
                ex.Message.ToString();
            }
           
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CreateCarttoonForm_Load(object sender, EventArgs e)
        {
            try
            {
                startupPath = System.Windows.Forms.Application.StartupPath;
                model_path = startupPath + "\\photo2cartoon_weights.onnx"; //https://github.com/LiteraturePro/Photo2cartoon

                // 创建输出会话,用于输出模型读取信息
                options = new SessionOptions();
                options.LogSeverityLevel = OrtLoggingLevel.ORT_LOGGING_LEVEL_INFO;
                // 设置为CPU上运行
                options.AppendExecutionProvider_CPU(0);

                // 创建推理模型类,读取本地模型文件
                onnx_session = new InferenceSession(model_path, options);

                // 输入Tensor
                input_tensor = new DenseTensor<float>(new[] { 1, 3, 256, 256 });

                // 创建输入容器
                input_ontainer = new List<NamedOnnxValue>();


                image_path = startupPath + "\\1.jpg";
                pictureBox1.Image = new Bitmap(image_path);
                image = new Mat(image_path);
            }
            catch (ArgumentException ex)
            {
                ex.Message.ToString();
            }
        }
    }
}

  

参考:https://dotnet.microsoft.com/zh-cn/apps/ai/ml-dotnet

de31bfa4ac2f4cfa19b0f29f6227a7b1

 

posted @ 2025-08-28 23:02  ®Geovin Du Dream Park™  阅读(8)  评论(0)    收藏  举报