当前位置: 首页 > 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…...

Ubuntu系统下交叉编译openssl

一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机&#xff1a;Ubuntu 20.04.6 LTSHost&#xff1a;ARM32位交叉编译器&#xff1a;arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

前端倒计时误差!

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂

蛋白质结合剂&#xff08;如抗体、抑制肽&#xff09;在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上&#xff0c;高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术&#xff0c;但这类方法普遍面临资源消耗巨大、研发周期冗长…...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增&#xff1a;通道注意力模块&#xff08;SE模块&#xff09; class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

Reasoning over Uncertain Text by Generative Large Language Models

https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...

【C++进阶篇】智能指针

C内存管理终极指南&#xff1a;智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...

省略号和可变参数模板

本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...

怎么开发一个网络协议模块(C语言框架)之(六) ——通用对象池总结(核心)

+---------------------------+ | operEntryTbl[] | ← 操作对象池 (对象数组) +---------------------------+ | 0 | 1 | 2 | ... | N-1 | +---------------------------+↓ 初始化时全部加入 +------------------------+ +-------------------------+ | …...

Canal环境搭建并实现和ES数据同步

作者&#xff1a;田超凡 日期&#xff1a;2025年6月7日 Canal安装&#xff0c;启动端口11111、8082&#xff1a; 安装canal-deployer服务端&#xff1a; https://github.com/alibaba/canal/releases/1.1.7/canal.deployer-1.1.7.tar.gz cd /opt/homebrew/etc mkdir canal…...