效果

测试图片来自网络,如有侵权,联系删除。

项目

关注微信公众号,回复关键字:“一秒变身艺术家”,获取程序!

模型信息

Inputs
-------------------------
name:input_image
tensor:Float[1, 3, 512, 512]
--------------------------------------------------------------- Outputs
-------------------------
name:output_image
tensor:Float[1, 1, 512, 512]
name:2016
tensor:Float[1, 1, 512, 512]
name:2017
tensor:Float[1, 1, 512, 512]
name:2018
tensor:Float[1, 1, 512, 512]
name:2019
tensor:Float[1, 1, 512, 512]
name:2020
tensor:Float[1, 1, 512, 512]
name:2021
tensor:Float[1, 1, 512, 512]
---------------------------------------------------------------

代码

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.Windows.Forms; namespace U2Net_Portrait
{
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;
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;
} Mat result_image = new Mat(512, 512, MatType.CV_32F, result_array); //还原图像大小
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_portrait.onnx"; modelSize = 512; //创建输出会话,用于输出模型读取信息
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, 512, 512 }); } 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); }
}
}
}

参考

https://github.com/xuebinqin/U-2-Net

一秒变身艺术家!U2Net 跨界肖像画,让你的头像瞬间细节完美复刻,打造个性化头像新风潮!的更多相关文章

  1. XMOS发布集单片机,AI,FPGA,DSP于一身的跨界处理器完全体xcore.ai,致力于AIOT,售价1美元起步

    说明:XMOS这次致力于打造全新的,颠覆性的嵌入式平台,简化开发人员要学一堆东西才能开发一款高性能AIOT产品的痛点. XCORE.AI集单片机,AI,FPGA,DSP于一身,嵌入式软件开发人员可以灵 ...

  2. 跨界玩AR,迪奥、Hugo Boss等知名奢侈品牌将制造AR眼镜

    Snapchat因为阅后即焚消息应用而被人所熟知,前段时间这家公司拓展主要业务,未来将不再只有消息应用,还有款名为"Spectacles"的AR太阳镜.内置了一个摄像头,戴上之后即 ...

  3. JJ Ying:越来越跨界的界面设计

    2013年6月29号  星期六  小雨  @大众点评 利用非界面设计的专业知识来提升界面设计 向平面设计跨界 向工业设计的跨界 向摄影跨界 向动向的的跨界 向程序跨界 讲师介绍: JJ Ying /  ...

  4. 跨界!Omi 发布多端统一框架 Omip 打通小程序与 Web 腾讯开源 2月28日

    https://mp.weixin.qq.com/s/z5qm-2bHk_BCJAwaodrMIg 跨界!Omi 发布多端统一框架 Omip 打通小程序与 Web 腾讯开源 2月28日

  5. 2016年终总结--一个Python程序猿的跨界之旅

    时间过得真快.感觉15年年终总结刚写完,16年就结束了.看了blog,16年就写了可怜的8篇,对我来说16年还算顺风顺水. 真正可能出乎意料的是年底我离开了呆了2年半的龙图游戏,临时放弃了用了3年半的 ...

  6. java web框架发展的新趋势--跨界轻型App

    “跨界(cross over)在汽车界已然成风,将轿车.SUV.跑车和MPV等多种不同元素融为一体的混搭跨界车型,正在成为汽车设计领域的新趋势.从个人而言,当包容.多元的审美要求和物质要求越来越强烈时 ...

  7. 在路上:安全公司“跨界”SD-WAN

    编者按:本文是SDNLAB“企业+”特别报道之一.“企业+”是SDNLAB重点打造的栏目,汇聚信息行业运营商.设备商.互联网公司.软件公司.集成公司.融创投资公司.科研院所等企业,重新定义IT行业撮合 ...

  8. 记View跨界平局

    <?xml version="1.0" encoding="utf-8"? > <RelativeLayout xmlns:android=& ...

  9. 跨界 - Omi 发布多端统一框架 Omip 打通小程序与 Web

    Omip 今天,Omi 不仅仅可以开发桌面 Web.移动 H5,还可以直接开发小程序!直接开发小程序!直接开发小程序! Github Omi 简介 Omi 框架是微信支付线研发部研发的下一代前端框架, ...

  10. 伪类+js实现CSS3 media queries跨界准确判断

    @media screen and (min-width: 45em) { body:after{ content:"宽屏" } } var content = window.ge ...

随机推荐

  1. IPFS Gateway Selector IPFS下载网关选择工具

    简介 用IPFS作文件分享可以覆盖很多场景, 现在IPFS网关也相当多了, 但是因为国内网络的状况, 不同网关在不同网络运营商的表现差别很大, 导致你提供的下载链接在对方那里可能速度很慢, 甚至无法访 ...

  2. git bash 的一些使用

    一般使用git bash需要的命令 先打开git bash: git init 可以初始化一个本地的仓库 git status 查看仓库信息 mkdir test 创建一个test的文件夹 cd te ...

  3. git bash走代理

    git config --global http.proxy 'http://127.0.0.1:7890' git config --global https.proxy 'http://127.0 ...

  4. 【Android 逆向】看雪题目:找出flag 如果输入正确则屏幕上的 hello会变成success

    1. apk 安装到手机,只有一个输入框,随便输入点什么,提示error 2. apk拖入到jadx中 public class MainActivity extends AppCompatActiv ...

  5. MySQL重新设置auto_increment值

    需求描述 通常,我们都会在数据库表中设置一个自增字段作为主键,该字段的值会随着添加新记录而自增. 同时也必须注意,这个自增字段的值只会一直增加,即使把记录删除了,该自增字段的值也不会变小. 因此,就会 ...

  6. Rock Pi开发笔记(三):Rock Pi 4B plus(基于瑞星微RK3399)板子硬件资源介绍

    前言   上一篇,概览了整个的rock pi大致系列,我们开始定位为RK3399做评估,入手RK3399,对基本的外设进行解说.   板载外设      USB3.0 × 2 USB2.0 × 2 千 ...

  7. 迭代器,map,filter,reduce,sorted函数---day12

    1.迭代器 迭代器能被next调用,并不断返回下一个值的对象,叫作迭代器(迭代器是对象) 概念:迭代器指的是迭代取值的工具,迭代是一个重复的过程每次重复都是基于上一次的结果而继续单纯的重复不是迭代. ...

  8. springboot多线程TaskExecutor的使用,以及使用@Async实现异步调用

    目录 @Async实现异步调用 pom.xml 启动类 定义controller 定义接口 实现类 将isDone换程CountDownLatch来判断线程是否执行完实例化CountDownLatch ...

  9. 【Azure Logic App】消费型逻辑应用在消费Service Bus时遇见消息并发速度慢,消息积压

    问题描述 消费型逻辑应用(Consumption Logic App)使用触发器模式消费 Azure Service Bus的消息,当Service Bus中存在大量消息等待消费时,Logic App ...

  10. 【Azure 应用服务】在创建App Service时,遇见“No available instances to satisfy this request. App Service is attempting to increase capacity.”错误

    问题描述 在创建新的App Service,遇见了资源不满足当前需求的提示.详细消息为: "Code": "Conflict","Message&qu ...