C# LaMa Image Inpainting 图像修复 Onnx Demo

news2024/11/25 13:11:25

目录

介绍

效果 

模型信息

项目

代码

下载


LaMa Image Inpainting 图像修复 Onnx Demo

介绍

gihub地址:https://github.com/advimman/lama

🦙 LaMa Image Inpainting, Resolution-robust Large Mask Inpainting with Fourier Convolutions, WACV 2022

效果 

模型信息

Model Properties
-------------------------
---------------------------------------------------------------

Inputs
-------------------------
name:image
tensor:Float[1, 3, 1000, 1504]
name:mask
tensor:Float[1, 1, 1000, 1504]
---------------------------------------------------------------

Outputs
-------------------------
name:inpainted
tensor:Float[1, 1000, 1504, 3]
---------------------------------------------------------------

项目

代码

using Microsoft.ML.OnnxRuntime;
using Microsoft.ML.OnnxRuntime.Tensors;
using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Onnx_Demo
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";
        string image_path = "";
        string image_path_mask = "";
        DateTime dt1 = DateTime.Now;
        DateTime dt2 = DateTime.Now;
        string model_path;
        Mat image;
        Mat image_mask;

        SessionOptions options;
        InferenceSession onnx_session;
        Tensor<float> input_tensor;
        Tensor<float> input_tensor_mask;
        List<NamedOnnxValue> input_container;
        IDisposableReadOnlyCollection<DisposableNamedOnnxValue> result_infer;

        StringBuilder sb = new StringBuilder();

        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;
            }

            button2.Enabled = false;
            pictureBox2.Image = null;
            textBox1.Text = "";

            image = new Mat(image_path);
            int w = image.Width;
            int h = image.Height;
            image_mask = new Mat(image_path_mask);

            Common.Preprocess(image, image_mask, input_tensor, input_tensor_mask);

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

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

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

            Mat result = Common.Postprocess(result_infer);

            Cv2.Resize(result, result, new OpenCvSharp.Size(w, h));

            sb.AppendLine("推理耗时:" + (dt2 - dt1).TotalMilliseconds + "ms");

            pictureBox2.Image = new Bitmap(result.ToMemoryStream());
            textBox1.Text = sb.ToString();

            button2.Enabled = true;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            model_path = "model/big_lama_regular_inpaint.onnx";

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

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

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

            input_tensor_mask = new DenseTensor<float>(new[] { 1, 1, 1000, 1504 });

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

            image_path = "test_img/test.jpg";
            pictureBox1.Image = new Bitmap(image_path);

            image_path_mask = "test_img/mask.jpg";
            pictureBox3.Image = new Bitmap(image_path_mask);
        }
    }
}

using Microsoft.ML.OnnxRuntime;
using Microsoft.ML.OnnxRuntime.Tensors;
using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Onnx_Demo
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";
        string image_path = "";
        string image_path_mask = "";
        DateTime dt1 = DateTime.Now;
        DateTime dt2 = DateTime.Now;
        string model_path;
        Mat image;
        Mat image_mask;

        SessionOptions options;
        InferenceSession onnx_session;
        Tensor<float> input_tensor;
        Tensor<float> input_tensor_mask;
        List<NamedOnnxValue> input_container;
        IDisposableReadOnlyCollection<DisposableNamedOnnxValue> result_infer;

        StringBuilder sb = new StringBuilder();

        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;
            }

            button2.Enabled = false;
            pictureBox2.Image = null;
            textBox1.Text = "";

            image = new Mat(image_path);
            int w = image.Width;
            int h = image.Height;
            image_mask = new Mat(image_path_mask);

            Common.Preprocess(image, image_mask, input_tensor, input_tensor_mask);

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

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

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

            Mat result = Common.Postprocess(result_infer);

            Cv2.Resize(result, result, new OpenCvSharp.Size(w, h));

            sb.AppendLine("推理耗时:" + (dt2 - dt1).TotalMilliseconds + "ms");

            pictureBox2.Image = new Bitmap(result.ToMemoryStream());
            textBox1.Text = sb.ToString();

            button2.Enabled = true;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            model_path = "model/big_lama_regular_inpaint.onnx";

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

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

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

            input_tensor_mask = new DenseTensor<float>(new[] { 1, 1, 1000, 1504 });

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

            image_path = "test_img/test.jpg";
            pictureBox1.Image = new Bitmap(image_path);

            image_path_mask = "test_img/mask.jpg";
            pictureBox3.Image = new Bitmap(image_path_mask);
        }
    }
}

Common.cs

using Microsoft.ML.OnnxRuntime;
using Microsoft.ML.OnnxRuntime.Tensors;
using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Onnx_Demo
{
    internal class Common
    {
        public static void Preprocess(Mat image, Mat image_mask,  Tensor<float> input_tensor, Tensor<float> input_tensor_mask)
        {
            Cv2.Resize(image, image, new OpenCvSharp.Size(1504, 1000));
            // 输入Tensor
            for (int y = 0; y < image.Height; y++)
            {
                for (int x = 0; x < image.Width; x++)
                {
                    input_tensor[0, 0, y, x] = image.At<Vec3b>(y, x)[0] / 255.0f;
                    input_tensor[0, 1, y, x] = image.At<Vec3b>(y, x)[1] / 255.0f;
                    input_tensor[0, 2, y, x] = image.At<Vec3b>(y, x)[2] / 255.0f;
                }
            }

            Cv2.Resize(image_mask, image_mask, new OpenCvSharp.Size(1504, 1000));
            //膨胀核函数
            Mat element1 = new Mat();
            OpenCvSharp.Size size1 = new OpenCvSharp.Size(11, 11);
            element1 = Cv2.GetStructuringElement(MorphShapes.Rect, size1);

            //膨胀一次,让轮廓突出
            Mat dilation = new Mat();
            Cv2.Dilate(image_mask, image_mask, element1);

            //输入Tensor
            for (int y = 0; y < image_mask.Height; y++)
            {
                for (int x = 0; x < image_mask.Width; x++)
                {
                    float v = image_mask.At<Vec3b>(y, x)[0];
                    if (v > 127)
                    {
                        input_tensor_mask[0, 0, y, x] = 1.0f;
                    }
                    else
                    {
                        input_tensor_mask[0, 0, y, x] = 0.0f;
                    }
                }
            }

        }

        public static Mat Postprocess(IDisposableReadOnlyCollection<DisposableNamedOnnxValue> result_infer)
        {
            // 将输出结果转为DisposableNamedOnnxValue数组
            DisposableNamedOnnxValue[] results_onnxvalue = result_infer.ToArray();

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

            float[] result_array = result_tensors.ToArray();

            for (int i = 0; i < result_array.Length; i++)
            {
                result_array[i] = Math.Max(0, Math.Min(255, result_array[i]));
            }

            Mat result = new Mat(1000, 1504, MatType.CV_32FC3, result_array);

            return result;
        }
    }
}

下载

源码下载

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

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

相关文章

Python 应用程序编程接口库之pywin32使用详解

概要 在Python的世界里,有许多优秀的第三方库可以帮助开发者更轻松地处理各种任务。其中,pywin32库是一个特别引人注目的工具,它提供了对Windows API的完整访问,使得开发者能够利用Python来编写强大的Windows应用程序,从简单的脚本到复杂的桌面应用,pywin32都能胜任。 什…

anaconda创建虚拟环境(第一次玩)

首先需要打开anaconda prompt&#xff0c;打开后需要等待一会&#xff0c;他要加载。 然后你输入下面的代码&#xff0c;其中环境名和python版本可以自定义 conda create -n 环境名 python3.6比如我的是 conda create -n mnist python3.7.0 等待一会&#xff0c;中途需要你输…

【论文精读】基于知识图谱关系路径的多跳智能问答模型研究

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

Axure 入门文档 文件格式 全局样式 元件居中

文件格式 .rp 原型文件.rplib:元件库文件.rpteam 团队项目文件.html 项目网页文件 批量设置居中 选中多个&#xff0c;然后上方任务栏即可设置 设置自定义页面视图尺寸 项目-自适应视图设置 点击页面空白处就可以使用 添加元件说明 当一个元件创建好&#xff0c;可以设…

电脑怎么设置静态ip地址和动态

在数字时代&#xff0c;电脑与网络的关系日益紧密。对于大多数用户来说&#xff0c;电脑的网络设置可能是个相对陌生的领域&#xff0c;尤其是关于IP地址的选择与配置。IP地址&#xff0c;即“互联网协议地址”&#xff0c;是电脑在网络中的唯一标识。了解如何设置静态IP地址和…

JavaScript 原型链继承:掌握面向对象的基础

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

华为HQoS配置案例

HQoS基于层次化调度&#xff0c;cpe上支持三级队列&#xff1a; level3流队列&#xff1a;每个用户的同类业务是一个业务流&#xff0c;针对每个用户不同的业务流进行队列调度&#xff0c;流队列一般与业务类型对应&#xff08;EF、AF、BE等&#xff09;。 level2用户队列&…

Golang搭建grpc环境

简介 OS : Windows 11 Golang 版本: go1.22.0 grpc : 1.2 protobuffer: 1.28代理 没有代理国内环境下载不了库七牛CDN &#xff08;试过可用&#xff09; go env -w GOPROXYhttps://goproxy.cn,direct阿里云代理(运行grpc时下载包出现报错 ): go env -w GOPROXYhttps://mirr…

漫步者、南卡、Cleer开放式耳机怎么样?硬核对比测评性能强者!

​在当今市场上&#xff0c;开放式耳机的型号层出不穷&#xff0c;作为一名专业的测评博主&#xff0c;我对这类产品有着深入的了解和丰富的经验。最近&#xff0c;我的粉丝们通过私信向我咨询如何选择适合自己的开放式耳机&#xff0c;面对众多品牌的选择&#xff0c;他们感到…

基于springboot的场地预约小程序的设计与实现(程序+数据库+文档)

** &#x1f345;点赞收藏关注 → 私信领取本源代码、数据库&#x1f345; 本人在Java毕业设计领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目&#xff0c;希望你能有所收获&#xff0c;少走一些弯路。&#x1f345;关注我不迷路&#x1f345;** 目录 一、研…

OPC UA协议转换网关

在物联网和工业自动化的世界里&#xff0c;OPC UA&#xff08;OLE for Process Control Unified Architecture&#xff09;协议凭借其开放性和互操作性&#xff0c;正在逐渐成为不同设备和系统间通信的桥梁。然而&#xff0c;在实际应用中&#xff0c;由于各种历史和技术原因&a…

【MySQL】视图、索引

目录 视图视图的用途优点视图的缺点创建视图查看视图修改视图删除视图注意事项 索引索引的原理索引的数据结构二分查找法Hash结构Hash冲突&#xff01;&#xff01;&#xff01; B树二叉查找树 存在问题改造二叉树——B树降低树的高度 B树特点案例继续优化的方向 改造B树——B树…

基于Java的快递管理系统(Vue.js+SpringBoot)

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容2.1 数据中心模块2.2 快递类型模块2.3 快递区域模块2.4 快递货架模块2.5 快递档案模块 三、界面展示3.1 登录注册3.2 快递类型3.3 快递区域3.4 快递货架3.5 快递档案3.6 系统基础模块 四、免责说明 一、摘要 1.1 项目介绍 …

万物皆可Find My,伦茨科技ST17H6x芯片赋能产品苹果Find My功能

苹果的Find My功能使得用户可以轻松查找iPhone、Mac、AirPods以及Apple Watch等设备。如今Find My还进入了耳机、充电宝、箱包、电动车、保温杯等多个行业。苹果发布AirTag发布以来&#xff0c;大家都更加注重物品的防丢&#xff0c;苹果的 Find My 就可以查找 iPhone、Mac、Ai…

【RK3568+RV1126】NPU算力集成

通过瑞芯微RK3568使用USB RNDIS网络与多个RV1126算力棒进行网络通信&#xff0c;打造多算力集群&#xff0c;同时进行AI运算处理&#xff0c;NPU算力集成不仅能增加算力&#xff0c;更能灵活的控制成本&#xff0c;具有更高的性价比&#xff0c;更低的功耗。 Mini-PCIe接口的RV…

华为交换机vlan实验

一、目标 实现不同vlan之间的终端通信 二、命令学习 1.创建2个vlan # 进入系统视图 sy# 创建vlan vlan 10 vlan 202.查看vlan # 2.查看vlan display vlanThe total number of vlans is : 3 ---------------------------------------------------------------------------…

Flink JobGraph构建过程

文章目录 前言JobGraph创建的过程总结 前言 在StreamGraph构建过程中分析了StreamGraph的构建过程&#xff0c;在StreamGraph构建完毕之后会对StreamGraph进行优化构建JobGraph&#xff0c;然后再提交JobGraph。优化过程中&#xff0c;Flink会尝试将尽可能多的StreamNode聚合在…

【Redis】redis的基本使用

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;Redis ⛺️稳中求进&#xff0c;晒太阳 Redis的概述 为什么要有redis? redis是数据库&#xff0c;mysql也是数据库&#xff0c;redis做缓存的意义就是为了减轻数据库压力 数据库为什么…

【归并排序】AcWing. 505 / NOIP2013提高组《火柴排队》(c++)

【题目描述】 涵涵有两盒火柴&#xff0c;每盒装有 n 根火柴&#xff0c;每根火柴都有一个高度。 现在将每盒中的火柴各自排成一列&#xff0c;同一列火柴的高度互不相同&#xff0c;两列火柴之间的距离定义为&#xff1a; 其中 ai 表示第一列火柴中第 i 个火柴的高度&a…

OWASP Top 10 网络安全10大漏洞——A02:A02:2021-加密机制失效

10大Web应用程序安全风险 2021年top10中有三个新类别、四个类别的命名和范围变化&#xff0c;以及一些合并。 A02&#xff1a;A02:2021-加密机制失效 上升一个位置&#xff0c;当前top2&#xff0c;以前称为敏感数据泄露&#xff0c;是一种状况而不是根本原因。更新后的类别…