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

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

下载

源码下载

参考

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

相关推荐
亲持红叶7 分钟前
神经网络常见激活函数 5-PReLU函数
人工智能·pytorch·python·深度学习·神经网络·机器学习
牛奶咖啡.85410 分钟前
DeepSeek-R1相关论文解读
人工智能·深度学习·ai·语言模型
拾荒的小海螺16 分钟前
JAVA:CloseableHttpClient 进行 HTTP 请求的技术指南
java·开发语言·http
亲持红叶18 分钟前
神经网络常见激活函数 1-sigmoid函数
人工智能·pytorch·深度学习·神经网络·机器学习·tensorflow2
普通网友19 分钟前
Stable Diffusion室内设计文生图实操
大数据·人工智能·网络协议·tcp/ip·stable diffusion
小杨爱编程23 分钟前
Spring Boot接入Deep Seek的API
人工智能·spring boot·后端
uesowys35 分钟前
阿里云 | DeepSeek人工智能大模型安装部署
人工智能·阿里云·云计算·deepseek
cwtlw36 分钟前
mybatisPlus介绍
java·开发语言·spring boot·学习
我们的五年36 分钟前
从算法到落地:DeepSeek如何突破AI工具的同质化竞争困局
人工智能·python·opencv·算法·数据挖掘·gpt-3·文心一言
灵魂画师向阳1 小时前
Stable Diffusion实现模特换衣等功能
java·人工智能·学习·ai作画·stable diffusion