当前位置: 首页 > news >正文

C# OpenCvSharp 部署MOWA:多合一图像扭曲模型

目录

说明

效果

项目

代码

下载

参考


C# OpenCvSharp 部署MOWA:多合一图像扭曲模型

说明

算法模型的paper名称是《MOWA: Multiple-in-One Image Warping Model》

ariv链接 https://arxiv.org/pdf/2404.10716 

效果

Stitched Image

翻译成中文意思是:拼接图像。效果图如下,可以看到输入原图的边界是不规则的,在经过模型推理之后输出的图的边界是规整了。

Rectified Wide-Angle Image

翻译成中文意思是:矫正广角图像。效果图如下,可以看到输入原图的左右上下边界是扭曲的,在经过模型推理之后输出的图的边界是规整了。

Unrolling Shutter Image

翻译成中文意思是:卷帘快门图像。效果图如下,可以看到输入原图的右边界是弯曲的,在经过模型推理之后输出的图的边界是规整了。

Rotated Image

翻译成中文意思是:旋转图像。效果图如下,可以看到输入原图是有明显倾斜的,在经过模型推理之后输出的图是摆正了。

Fisheye Image

翻译成中文意思是:鱼眼图像。效果图如下,可以看到输入原图里的建筑物有明显扭曲的,在经过模型推理之后输出的图里的建筑物是正直的了。

项目

代码

using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

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

        Stopwatch stopwatch = new Stopwatch();
        Mat image;
        Mat mask;
        Mat mesh_img;
        Mat grid_mesh_img;
        Mat flow_img;

        string image_path;
        string mask_path;
        string startupPath;
        string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";
        const string DllName = "MOWASharp.dll";
        IntPtr engine;

        /*
         //初始化
        extern "C" _declspec(dllexport) int __cdecl  init(void** engine, char* model_dir,char* msg);

        //detect
        extern "C" _declspec(dllexport) int __cdecl  detect(void* engine, Mat* srcimg, Mat* maskimg, char* msg, Mat* mesh_img, Mat* grid_mesh_img, Mat* flow_img);

        //释放
        extern "C" _declspec(dllexport) void __cdecl destroy(void* engine);

         */

        [DllImport(DllName, EntryPoint = "init", CallingConvention = CallingConvention.Cdecl)]
        internal extern static int init(ref IntPtr engine, string model_dir, StringBuilder msg);

        [DllImport(DllName, EntryPoint = "detect", CallingConvention = CallingConvention.Cdecl)]
        internal extern static int detect(IntPtr engine, IntPtr srcimg, IntPtr maskimg, StringBuilder msg, IntPtr mesh_img, IntPtr grid_mesh_img, IntPtr flow_img);

        [DllImport(DllName, EntryPoint = "destroy", CallingConvention = CallingConvention.Cdecl)]
        internal extern static int destroy(IntPtr engine);

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

            string model_dir = startupPath + "\\model\\";

            StringBuilder msg = new StringBuilder(512);

            int res = init(ref engine, model_dir, msg);
            if (res == -1)
            {
                MessageBox.Show(msg.ToString());
                return;
            }
            else
            {
                Console.WriteLine(msg.ToString());
            }
            image_path = startupPath + "\\test_img\\39501.png";
            pictureBox1.Image = new Bitmap(image_path);

            mask_path = startupPath + "\\test_img\\39501_mask.png";
            pictureBox3.Image = new Bitmap(mask_path);
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            destroy(engine);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (image_path == "" || mask_path == "")
            {
                return;
            }

            textBox1.Text = "执行中……";
            button2.Enabled = false;
            if (pictureBox2.Image != null)
            {
                pictureBox2.Image.Dispose();
                pictureBox2.Image = null;
            }
            Application.DoEvents();

            Cv2.DestroyAllWindows();
            if (image != null) image.Dispose();
            if (mask != null) mask.Dispose();
            if (mesh_img != null) mesh_img.Dispose();
            if (grid_mesh_img != null) grid_mesh_img.Dispose();
            if (flow_img != null) flow_img.Dispose();

            StringBuilder msg = new StringBuilder(512);
            image = new Mat(image_path);
            mask = new Mat(mask_path,ImreadModes.Grayscale);
            mesh_img = new Mat();
            grid_mesh_img = new Mat();
            flow_img = new Mat();

            stopwatch.Restart();

            int res = detect(engine, image.CvPtr, mask.CvPtr, msg, mesh_img.CvPtr, grid_mesh_img.CvPtr, flow_img.CvPtr);
            if (res == 0)
            {
                stopwatch.Stop();
                double costTime = stopwatch.Elapsed.TotalMilliseconds;
                pictureBox2.Image = new Bitmap(flow_img.ToMemoryStream());
                Cv2.ImShow("mesh_img", mesh_img);
                Cv2.ImShow("grid_mesh_img", grid_mesh_img);
                textBox1.Text = $"耗时:{costTime:F2}ms";
            }
            else
            {
                textBox1.Text = "失败," + msg.ToString();
            }
            button2.Enabled = true;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = fileFilter;
            ofd.InitialDirectory = startupPath + "\\test_img";
            if (ofd.ShowDialog() != DialogResult.OK) return;

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

            image_path = ofd.FileName;
            pictureBox1.Image = new Bitmap(image_path);
            image = new Mat(image_path);
        }

        private void button4_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = fileFilter;
            ofd.InitialDirectory = startupPath+"\\test_img";
            if (ofd.ShowDialog() != DialogResult.OK) return;

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

            mask_path = ofd.FileName;
            pictureBox3.Image = new Bitmap(mask_path);
            mask = new Mat(image_path);
        }

        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 (*.jpg)|*.jpg|Images (*.png)|*.png|Images (*.bmp)|*.bmp";
            if (sdf.ShowDialog() == DialogResult.OK)
            {
                switch (sdf.FilterIndex)
                {
                    case 1:
                        {
                            output.Save(sdf.FileName, ImageFormat.Jpeg);
                            break;
                        }
                    case 2:
                        {
                            output.Save(sdf.FileName, ImageFormat.Png);
                            break;
                        }
                    case 3:
                        {
                            output.Save(sdf.FileName, ImageFormat.Bmp);
                            break;
                        }
                }
                MessageBox.Show("保存成功,位置:" + sdf.FileName);
            }
        }
    }
}
 

using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace MOWA
{public partial class Form1 : Form{public Form1(){InitializeComponent();}Stopwatch stopwatch = new Stopwatch();Mat image;Mat mask;Mat mesh_img;Mat grid_mesh_img;Mat flow_img;string image_path;string mask_path;string startupPath;string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";const string DllName = "MOWASharp.dll";IntPtr engine;/*//初始化extern "C" _declspec(dllexport) int __cdecl  init(void** engine, char* model_dir,char* msg);//detectextern "C" _declspec(dllexport) int __cdecl  detect(void* engine, Mat* srcimg, Mat* maskimg, char* msg, Mat* mesh_img, Mat* grid_mesh_img, Mat* flow_img);//释放extern "C" _declspec(dllexport) void __cdecl destroy(void* engine);*/[DllImport(DllName, EntryPoint = "init", CallingConvention = CallingConvention.Cdecl)]internal extern static int init(ref IntPtr engine, string model_dir, StringBuilder msg);[DllImport(DllName, EntryPoint = "detect", CallingConvention = CallingConvention.Cdecl)]internal extern static int detect(IntPtr engine, IntPtr srcimg, IntPtr maskimg, StringBuilder msg, IntPtr mesh_img, IntPtr grid_mesh_img, IntPtr flow_img);[DllImport(DllName, EntryPoint = "destroy", CallingConvention = CallingConvention.Cdecl)]internal extern static int destroy(IntPtr engine);private void Form1_Load(object sender, EventArgs e){startupPath = Application.StartupPath;string model_dir = startupPath + "\\model\\";StringBuilder msg = new StringBuilder(512);int res = init(ref engine, model_dir, msg);if (res == -1){MessageBox.Show(msg.ToString());return;}else{Console.WriteLine(msg.ToString());}image_path = startupPath + "\\test_img\\39501.png";pictureBox1.Image = new Bitmap(image_path);mask_path = startupPath + "\\test_img\\39501_mask.png";pictureBox3.Image = new Bitmap(mask_path);}private void Form1_FormClosed(object sender, FormClosedEventArgs e){destroy(engine);}private void button2_Click(object sender, EventArgs e){if (image_path == "" || mask_path == ""){return;}textBox1.Text = "执行中……";button2.Enabled = false;if (pictureBox2.Image != null){pictureBox2.Image.Dispose();pictureBox2.Image = null;}Application.DoEvents();Cv2.DestroyAllWindows();if (image != null) image.Dispose();if (mask != null) mask.Dispose();if (mesh_img != null) mesh_img.Dispose();if (grid_mesh_img != null) grid_mesh_img.Dispose();if (flow_img != null) flow_img.Dispose();StringBuilder msg = new StringBuilder(512);image = new Mat(image_path);mask = new Mat(mask_path,ImreadModes.Grayscale);mesh_img = new Mat();grid_mesh_img = new Mat();flow_img = new Mat();stopwatch.Restart();int res = detect(engine, image.CvPtr, mask.CvPtr, msg, mesh_img.CvPtr, grid_mesh_img.CvPtr, flow_img.CvPtr);if (res == 0){stopwatch.Stop();double costTime = stopwatch.Elapsed.TotalMilliseconds;pictureBox2.Image = new Bitmap(flow_img.ToMemoryStream());Cv2.ImShow("mesh_img", mesh_img);Cv2.ImShow("grid_mesh_img", grid_mesh_img);textBox1.Text = $"耗时:{costTime:F2}ms";}else{textBox1.Text = "失败," + msg.ToString();}button2.Enabled = true;}private void button1_Click(object sender, EventArgs e){OpenFileDialog ofd = new OpenFileDialog();ofd.Filter = fileFilter;ofd.InitialDirectory = startupPath + "\\test_img";if (ofd.ShowDialog() != DialogResult.OK) return;pictureBox1.Image = null;pictureBox2.Image = null;textBox1.Text = "";image_path = ofd.FileName;pictureBox1.Image = new Bitmap(image_path);image = new Mat(image_path);}private void button4_Click(object sender, EventArgs e){OpenFileDialog ofd = new OpenFileDialog();ofd.Filter = fileFilter;ofd.InitialDirectory = startupPath+"\\test_img";if (ofd.ShowDialog() != DialogResult.OK) return;pictureBox3.Image = null;pictureBox2.Image = null;textBox1.Text = "";mask_path = ofd.FileName;pictureBox3.Image = new Bitmap(mask_path);mask = new Mat(image_path);}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 (*.jpg)|*.jpg|Images (*.png)|*.png|Images (*.bmp)|*.bmp";if (sdf.ShowDialog() == DialogResult.OK){switch (sdf.FilterIndex){case 1:{output.Save(sdf.FileName, ImageFormat.Jpeg);break;}case 2:{output.Save(sdf.FileName, ImageFormat.Png);break;}case 3:{output.Save(sdf.FileName, ImageFormat.Bmp);break;}}MessageBox.Show("保存成功,位置:" + sdf.FileName);}}}
}

下载

源码下载

参考

https://github.com/hpc203/MOWA-onnxrun

相关文章:

C# OpenCvSharp 部署MOWA:多合一图像扭曲模型

目录 说明 效果 项目 代码 下载 参考 C# OpenCvSharp 部署MOWA:多合一图像扭曲模型 说明 算法模型的paper名称是《MOWA: Multiple-in-One Image Warping Model》 ariv链接 https://arxiv.org/pdf/2404.10716 效果 Stitched Image 翻译成中文意思是&…...

本地部署DeepSeek-R1模型(新手保姆教程)

背景 最近deepseek太火了,无数的媒体都在报道,很多人争相着想本地部署试验一下。本文就简单教学一下,怎么本地部署。 首先大家要知道,使用deepseek有三种方式: 1.网页端或者是手机app直接使用 2.使用代码调用API …...

神经网络常见激活函数 5-PReLU函数

文章目录 PReLU函数导函数函数和导函数图像优缺点pytorch中的PReLU函数tensorflow 中的PReLU函数 PReLU 参数化修正线性单元:Parametric ReLU 函数导函数 PReLU函数 P R e L U { x x > 0 α x x < 0 ( α 是可训练参数 ) \rm PReLU \left\{ \begin{array}{} x \qua…...

2025我的第二次社招,写在春招之季

先说一个好消息&#xff0c;C那些事 4w star了&#xff01; 前面断更了一个月&#xff0c;本篇文章就可以看到原因&#xff0c;哈哈。 大家好&#xff0c;我叫光城&#xff0c;腾讯实习转正做后端开发&#xff0c;后去小公司做数据库内核&#xff0c;经过这几年的成长与积累&am…...

Visual Studio Code中文出现黄色框子的解决办法

Visual Studio Code中文出现黄色框子的解决办法 一、vsCode中文出现黄色框子-如图二、解决办法 一、vsCode中文出现黄色框子-如图 二、解决办法 点击 “文件”点击 “首选项”点击 “设置” 搜索框直接搜索unicode选择“文本编辑器”&#xff0c;往下滑动&#xff0c;找到“Un…...

threejs开源代码之-旋转的彩色立方体

效果&#xff1a;旋转的彩色立方体 效果描述&#xff1a; 一个立方体在场景中旋转。立方体的每个面有不同的颜色。使用自定义着色器为立方体添加动态的光影效果。 代码实现 import * as THREE from three; import { OrbitControls } from three/examples/jsm/controls/OrbitC…...

visual studio 2008的试用版评估期已结束的解决办法

visual studio 2008试用期过了后&#xff0c;再次启动时提示&#xff1a;visual studio的试用版评估期已结束。 需要的工具&#xff1a;补丁文件PatchVS2008.exe 解决办法&#xff1a; 1.在“控制面板”-“添加删除程序”中选择visual studio 2008&#xff0c;点击“更改/卸载”…...

解锁 DeepSeek 模型高效部署密码:蓝耘平台深度剖析与实战应用

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…...

Http和Socks的区别?

HTTP 和 SOCKS 的区别 HTTP 和 SOCKS 都是用于网络通信的协议&#xff0c;但它们在工作原理、应用场景和实现方式上有显著的区别。以下是详细的对比和说明。 一、HTTP 协议 1. 定义 HTTP&#xff08;HyperText Transfer Protocol&#xff09;是用于传输超文本数据的应用层协…...

VC播放mp3的方法

1、使用msi库 #include <mmsystem.h> #pragma comment(lib,"winmm.lib") .......//打开文件MCI_OPEN_PARMS mciOpen; mciOpen.lpstrDeviceType _T("mpegvideo"); mciOpen.lpstrElementName _T("c://1.mp3"); MCIERROR mciError mci…...

Docker 部署 verdaccio 搭建 npm 私服

一、镜像获取 # 获取 verdaccio 镜像 docker pull verdaccio/verdaccio 二、修改配置文件 cd /wwwroot/opt/docker/verdaccio/conf vim config.yaml config.yaml 配置文件如下&#xff0c;可以根据自己的需要进行修改 # # This is the default configuration file. It all…...

49-拓展(1)

49-拓展&#xff08;1&#xff09; 扩展概述 扩展可以为在当前 package 可见的类型&#xff08;除函数、元组、接口&#xff09;添加新功能。 当不能破坏被扩展类型的封装性&#xff0c;但希望添加额外的功能时&#xff0c;可以使用扩展。 可以添加的功能包括&#xff1a; …...

国产编辑器EverEdit - 在文件中查找和替换

1 在文件中查找和替换 1.1 应用场景 某些场景&#xff0c;用户需要在所有工程文件中进行查找和替换关键词&#xff0c;比如&#xff1a;查找工程中哪些文件使用了某个常量。 1.2 使用方法 选择主菜单查找 -> 在文件中查找和替换&#xff0c;或使用快捷键Ctrl Shift F&a…...

安全行业大模型SecLLM技术白皮书

在ChatGPT 呈现全球现象级热度时&#xff0c;通用大语言模型&#xff08;Large Language Model, LLM&#xff09;技术成为了推动创新和变革的关键驱动力。但由于安全行业的特殊性和复杂性&#xff0c;LLM 并不能满足其应用需求。安全行业大模型(Security Large Language Model,…...

基础入门-HTTP数据包红蓝队研判自定义构造请求方法请求头修改状态码判断

知识点&#xff1a; 1、请求头&返回包-方法&头修改&状态码等 2、数据包分析-红队攻击工具&蓝队流量研判 3、数据包构造-Reqable自定义添加修改请求 一、演示案例-请求头&返回包-方法&头修改&状态码等 数据包 客户端请求Request 请求方法 …...

2025年日祭

本文将同步发表于洛谷&#xff08;暂无法访问&#xff09;、CSDN 与 Github 个人博客&#xff08;暂未发布&#xff09; 本蒟自2025.2.8开始半停课。 任务计划&#xff08;站外题与专题&#xff09; 数了一下&#xff0c;通过人数比较高的题&#xff0c;也就是我准备补的题&a…...

git命令行删除远程分支、删除远程提交日志

目录 1、从本地通过命令行删除远程git分支2、删除已 commit 并 push 的记录 1、从本地通过命令行删除远程git分支 git push origin --delete feature/feature_xxx 删除远程分支 feature/feature_xxx 2、删除已 commit 并 push 的记录 git reset --hard 7b5d01xxxxxxxxxx 恢复到…...

centOS8安装MySQL8设置开机自动启动失败

提供一个终极解决方案虽然systemctl 更符合管理预期但是不能用 使用一下命令 修改配置文件、修改mysql.service全是问题 systemctl start mysqld systemctl enable mysqld systemctl daemon-reload完全不生效各种报错 提示配置文件内容有问题 Main process exited, codeexite…...

对接DeepSeek

其实&#xff0c;整个对接过程很简单&#xff0c;就四步&#xff0c;获取key&#xff0c;找到接口文档&#xff0c;接口测试&#xff0c;代码对接。 获取 KEY https://platform.deepseek.com/transactions 直接付款就是了&#xff08;现在官网暂停充值2025年2月7日&#xff0…...

SpringSecurity高级用法

SpringSecurity的高级用法&#xff0c;包括自定义loginUrl携带参数&#xff0c;自定义认证校验逻辑&#xff0c;自定义权限校验逻辑。 示例项目 https://github.com/qihaiyan/springcamp/tree/master/spring-advanced-security 一、概述 在项目实际开发过程中&#xff0c;Spr…...

web vue 项目 Docker化部署

Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段&#xff1a; 构建阶段&#xff08;Build Stage&#xff09;&#xff1a…...

Cursor实现用excel数据填充word模版的方法

cursor主页&#xff1a;https://www.cursor.com/ 任务目标&#xff1a;把excel格式的数据里的单元格&#xff0c;按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例&#xff0c;…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)

2025年能源电力系统与流体力学国际会议&#xff08;EPSFD 2025&#xff09;将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会&#xff0c;EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

循环冗余码校验CRC码 算法步骤+详细实例计算

通信过程&#xff1a;&#xff08;白话解释&#xff09; 我们将原始待发送的消息称为 M M M&#xff0c;依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)&#xff08;意思就是 G &#xff08; x ) G&#xff08;x) G&#xff08;x) 是已知的&#xff09;&#xff0…...

基础测试工具使用经验

背景 vtune&#xff0c;perf, nsight system等基础测试工具&#xff0c;都是用过的&#xff0c;但是没有记录&#xff0c;都逐渐忘了。所以写这篇博客总结记录一下&#xff0c;只要以后发现新的用法&#xff0c;就记得来编辑补充一下 perf 比较基础的用法&#xff1a; 先改这…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面

代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口&#xff08;适配服务端返回 Token&#xff09; export const login async (code, avatar) > {const res await http…...

基于Docker Compose部署Java微服务项目

一. 创建根项目 根项目&#xff08;父项目&#xff09;主要用于依赖管理 一些需要注意的点&#xff1a; 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件&#xff0c;否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等

&#x1f50d; 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术&#xff0c;可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势&#xff0c;还能有效评价重大生态工程…...

前端开发面试题总结-JavaScript篇(一)

文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包&#xff08;Closure&#xff09;&#xff1f;闭包有什么应用场景和潜在问题&#xff1f;2.解释 JavaScript 的作用域链&#xff08;Scope Chain&#xff09; 二、原型与继承3.原型链是什么&#xff1f;如何实现继承&a…...

Java入门学习详细版(一)

大家好&#xff0c;Java 学习是一个系统学习的过程&#xff0c;核心原则就是“理论 实践 坚持”&#xff0c;并且需循序渐进&#xff0c;不可过于着急&#xff0c;本篇文章推出的这份详细入门学习资料将带大家从零基础开始&#xff0c;逐步掌握 Java 的核心概念和编程技能。 …...