C# U2Net 抠图

news2024/10/6 2:25:38

效果(u2net.onnx)

效果(u2net_human_seg.onnx)

项目

代码

using Microsoft.ML.OnnxRuntime;
using Microsoft.ML.OnnxRuntime.Tensors;
using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;


namespace U2Net
{
    public partial class frmMain : Form
    {
        public frmMain()
        {
            InitializeComponent();
        }

        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 = 512;

        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;

        private void button1_Click(object sender, EventArgs e)
        {
            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;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            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);

            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.485f) / 0.229f;
                    input_tensor[0, 1, y, x] = (resize_image.At<Vec3b>(y, x)[1] / 255f - 0.456f) / 0.224f;
                    input_tensor[0, 2, y, x] = (resize_image.At<Vec3b>(y, x)[2] / 255f - 0.406f) / 0.225f;
                }
            }

            //将 input_tensor 放入一个输入参数的容器,并指定名称
            input_ontainer.Add(NamedOnnxValue.CreateFromTensor("input_image", 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();

            //黑白色反转
            //for (int i = 0; i < result_array.Length; i++)
            //{
            //    result_array[i] = 1 - result_array[i];
            //}

            float maxVal = result_array.Max();
            float minVal = result_array.Min();

            for (int i = 0; i < result_array.Length; i++)
            {
                result_array[i] = (result_array[i] - minVal) / (maxVal - minVal) * 255;
            }

            result_image = new Mat(modelSize, modelSize, MatType.CV_32F, result_array);

            Cv2.CvtColor(result_image, result_image, ColorConversionCodes.RGB2BGR);

            //还原图像大小
            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";

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            startupPath = Application.StartupPath;

            //model_path = startupPath + "\\model\\u2net.onnx";
            //model_path = startupPath + "\\model\\u2netp.onnx";
            model_path = startupPath + "\\model\\u2net_human_seg.onnx";

            modelSize = 320;

            //创建输出会话,用于输出模型读取信息
            options = new SessionOptions();
            options.LogSeverityLevel = OrtLoggingLevel.ORT_LOGGING_LEVEL_INFO;

            //设置为CPU上运行
            options.AppendExecutionProvider_CPU(0);

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

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

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

        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (pictureBox2.Image == null)
            {
                return;
            }
            Bitmap output = new Bitmap(pictureBox2.Image);
            var sdf = new SaveFileDialog();
            sdf.Title = "保存";
            sdf.Filter = "Images (*.bmp)|*.bmp|Images (*.emf)|*.emf|Images (*.exif)|*.exif|Images (*.gif)|*.gif|Images (*.ico)|*.ico|Images (*.jpg)|*.jpg|Images (*.png)|*.png|Images (*.tiff)|*.tiff|Images (*.wmf)|*.wmf";
            if (sdf.ShowDialog() == DialogResult.OK)
            {
                switch (sdf.FilterIndex)
                {
                    case 1:
                        {
                            output.Save(sdf.FileName, ImageFormat.Bmp);
                            break;
                        }
                    case 2:
                        {
                            output.Save(sdf.FileName, ImageFormat.Emf);
                            break;
                        }
                    case 3:
                        {
                            output.Save(sdf.FileName, ImageFormat.Exif);
                            break;
                        }
                    case 4:
                        {
                            output.Save(sdf.FileName, ImageFormat.Gif);
                            break;
                        }
                    case 5:
                        {
                            output.Save(sdf.FileName, ImageFormat.Icon);
                            break;
                        }
                    case 6:
                        {
                            output.Save(sdf.FileName, ImageFormat.Jpeg);
                            break;
                        }
                    case 7:
                        {
                            output.Save(sdf.FileName, ImageFormat.Png);
                            break;
                        }
                    case 8:
                        {
                            output.Save(sdf.FileName, ImageFormat.Tiff);
                            break;
                        }
                    case 9:
                        {
                            output.Save(sdf.FileName, ImageFormat.Wmf);
                            break;
                        }
                }
                MessageBox.Show("保存成功,位置:" + sdf.FileName);

            }
        }
    }
}


参考

GitHub - xuebinqin/U-2-Net: The code for our newly accepted paper in Pattern Recognition 2020: "U^2-Net: Going Deeper with Nested U-Structure for Salient Object Detection."

下载

源码下载

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1127179.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C# 开发的程序怎么默认以管理员身份运行

C# 在读写注册表或其他的敏感操作时&#xff0c;如果程序未获得管理员权限&#xff0c;操作会报错&#xff0c;可以在exe文件的属性页面里勾选【以管理员身份运行此程序】 那么怎么默认以管理员身份运行呢 方法一 在项目上右键&#xff0c;点击【属性】&#xff0c;点击【安…

ROS系列(三):rosbag 中提取图像数据与帧率对齐

首先说明一下&#xff0c;rosbag的解压方式取决于之前的压缩方式&#xff0c;数据的格式和工具使用的方法有很大关系。当前数据类型是 sensor_msgs/CompressedImage 。 处理数据的topic为 /cam_front_center/csi_cam/image_raw/compressed 当前提取是前置摄像头图像数据。 可…

【23真题】碰瓷重邮成电,题目Mini版本!

今天分享的是23年广西师范大学846的信号与系统部分试题及解析。 本套试难度分析&#xff1a;23年平均分只有90-100分&#xff0c;最高分129分&#xff01;但是我觉得不难。22年广西师范846我也发布过&#xff0c;如有需要戳这里自取&#xff01;该院校考察的是模拟电路和信号系…

工具及方法 - 查电子器件和查说明书

查询电子器件 手里一个产品&#xff0c;上面使用的蓝牙模组是BL871E2&#xff0c;然后想查一下相关信息&#xff0c;发现了下面的查询网站&#xff1a; 查询某颗物料的网站&#xff1a; device.report Search for Electronic Components Price & Stock | DigiPart 查询UG…

【实战】Kubernetes安装持久化工具NFS-StorageClass

文章目录 前言技术积累存储类&#xff08;storage class&#xff09;什么是NFS什么是PV\PVC为什么要用NFS-StorageClass 安装NFS-StorageClass保证N8S集群正常投用安装NFS工具与客户端NFS安装常见错误安装NFS-StorageClass存储器 前言 前面的博文我们介绍了如何用kuberadmin的…

RosettaNet PIPs 简介

RosettaNet背景知识 RosettaNet由主要计算机&#xff0c;消费电子产品&#xff0c;半导体制造商&#xff0c;电信和物流公司组成的联盟组成&#xff0c;共同创建和实施行业范围的开放式电子商务流程标准。这些标准形成了一种通用的电子商务语言&#xff0c;在全球范围内协调供…

【SpringCloud微服务项目实战-mall4cloud项目(5)】——mall4cloud-leaf

mall4cloud-leaf 基于美团leaf的生成id服务 分布式id介绍具体代码及使用项目中的生成id模式具体代码分布式id生成使用 分布式id介绍 分布式ID&#xff08;Distributed ID&#xff09;是在分布式计算环境中生成的唯一标识符或标识号。在分布式系统中&#xff0c;通常需要唯一标…

Vcenter实战利用方式总结

目录 0x01 指纹特征 0x02 查看Vcenter版本 0x03 CVE-2021-21972 0x04 CVE-2021-22005 0x05 CVE-2021-44228 0x06 获取vcenter-web控制台权限 重置密码 cookie登录 不重置获取密码&#xff08;ESXI&#xff09; 1、获取解密key 2、获取数据库账号密码 3、使用脚本解…

PHP 函数、PHP 简单后门

函数 基本结构 语法结构 function 函数名(形式参数1,形式参数2...){//函数体return 返回值 }定义并执行一个简单函数 // funtion.phpfunction test(){echo "This is function ".__FUNCTION__; }test();函数传参 // function.phpfunction add($x, $y){$sum $x …

JAVA-编程基础-11-03-java IO 字节流

Lison <dreamlison163.com>, v1.0.0, 2023.05.07 JAVA-编程基础-11-03-java IO 字节流 文章目录 JAVA-编程基础-11-03-java IO 字节流字节输出流&#xff08;OutputStream&#xff09;FileOutputStream类**FileOutputStrea 的构造方法**使用文件名创建FileOutputStream…

【RocketMQ系列十三】RocketMQ的集群核心概念之消费重试死信队列幂等消息的出现以及处理

您好&#xff0c;我是码农飞哥&#xff08;wei158556&#xff09;&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f4aa;&#x1f3fb; 1. Python基础专栏&#xff0c;基础知识一网打尽&#xff0c;9.9元买不了吃亏&#xff0c;买不了上当。 Python从入门到精…

基于拦截器Interceptor实现简易权限控制及行为记录功能

一、业务需求 使用拦截器(Interceptor)&#xff0c;实现Controller中方法的权限控制&#xff0c;并记录访问行为。要求仅在Controller方法上加注解&#xff0c;就可以实现权限控制。具体为&#xff1a; 1、拦截未登录用户的访问&#xff1b; 2、拦截不具有权限用户的访问&#…

ASPICE标准快速掌握「3.1. 实践示例」

实践示例 本章内容是最重要的,建议慢下来跟着博主的思路一步一步前进 1. 示例背景说明 假设我们现在是一个Tier1的车窗控制软件开发商,我们给OEM提供软件解决方案 1.1. 本过程目标 根据客户、上级部门、安全团队与质量团队等提出的要求,本项目要求SYS.1过程达到ASPICE过…

【源码】C/C++学生信息管理系统 1024程序员节日快乐

文章目录 题目介绍源码效果展示报告内容 更多源码&#xff1a; 点我跳转目录 题目介绍 1024程序员节日快乐! 使用语言&#xff1a; 此源码包含两个版本: 版本1&#xff1a;C语言 版本2&#xff1a; C 代码量&#xff1a; 650 题目&#xff1a; 学生信息管理系统&#xff0c; …

JAVA-编程基础-11-04-java IO 字符流

Lison <dreamlison163.com>, v1.0.0, 2023.05.07 JAVA-编程基础-11-04-java IO 字符流 文章目录 JAVA-编程基础-11-04-java IO 字符流字符流Reader 和 Writer字符输入流&#xff08;Reader&#xff09;**FileReader构造方法****FileReader读取字符数据** 字符输出流&am…

解决样本不均衡问题

一、样本不均衡问题 样本&#xff08;类别&#xff09;不平衡指的是分类任务中不同类别的训练样例数目差别很大的情况&#xff0c;一般地&#xff0c;样本类别比例&#xff08;多数类VS少数类&#xff09;明显大于1&#xff1a;1&#xff08;例如4&#xff1a;1&#xff09;就…

软考信息安全工程师备考

软考信息安全工程师备考 报名 公告地址 通知是否有考试和考试安排的公告 https://www.ruankao.org.cn/arrange报名地址 https://bm.ruankao.org.cn/sign/welcome刷题 51cto刷题小程序 5cto题库点击进去选择信息安全工程师 可以刷选择题和大题 还可以刷真题非常好用 …

Mysql数据库指定某数据库或某表赋予增删改查操作权限各类划分权限的方法总结实战

一、mysql创建用户只赋予指定数据库的增删改查操作权限 在日常生产运维工作中&#xff0c;我们经常需要给其他厂商或者合作伙伴提供数据库的账号&#xff0c;并且需要指定某个用户只能查询指定的数据库&#xff0c;并且赋予增删改查的指定权限。 &#xff08;1&#xff09;创…

面试算法38:每日温度

题目 输入一个数组&#xff0c;它的每个数字是某天的温度。请计算每天需要等几天才会出现更高的温度。例如&#xff0c;如果输入数组[35&#xff0c;31&#xff0c;33&#xff0c;36&#xff0c;34]&#xff0c;那么输出为[3&#xff0c;1&#xff0c;1&#xff0c;0&#xff…

软硬件架构分层总结

一、前言 软件系统很多架构图我们经常看到是这样的三段 就是这三段就可以演化出很多层 二、硬件架构分层 硬件层&#xff0c;基本是计算机硬件的体系结构&#xff0c;包括硬盘设备&#xff0c;cpu&#xff0c;内存&#xff0c;控制器&#xff0c;运算器&#xff0c;寄存器&am…