[项目实践] C# OpenCvSharp 部署MOWA:多合一图像扭曲模型

570 0
Honkers 2025-3-5 17:48:12 | 显示全部楼层 |阅读模式

目录

说明

效果

项目

代码

下载

参考


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

  1. using OpenCvSharp;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.ComponentModel;
  5. using System.Data;
  6. using System.Diagnostics;
  7. using System.Drawing;
  8. using System.Drawing.Imaging;
  9. using System.Linq;
  10. using System.Runtime.InteropServices;
  11. using System.Text;
  12. using System.Threading.Tasks;
  13. using System.Windows.Forms;
  14. namespace MOWA
  15. {
  16. public partial class Form1 : Form
  17. {
  18. public Form1()
  19. {
  20. InitializeComponent();
  21. }
  22. Stopwatch stopwatch = new Stopwatch();
  23. Mat image;
  24. Mat mask;
  25. Mat mesh_img;
  26. Mat grid_mesh_img;
  27. Mat flow_img;
  28. string image_path;
  29. string mask_path;
  30. string startupPath;
  31. string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";
  32. const string DllName = "MOWASharp.dll";
  33. IntPtr engine;
  34. /*
  35. //初始化
  36. extern "C" _declspec(dllexport) int __cdecl init(void** engine, char* model_dir,char* msg);
  37. //detect
  38. 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);
  39. //释放
  40. extern "C" _declspec(dllexport) void __cdecl destroy(void* engine);
  41. */
  42. [DllImport(DllName, EntryPoint = "init", CallingConvention = CallingConvention.Cdecl)]
  43. internal extern static int init(ref IntPtr engine, string model_dir, StringBuilder msg);
  44. [DllImport(DllName, EntryPoint = "detect", CallingConvention = CallingConvention.Cdecl)]
  45. internal extern static int detect(IntPtr engine, IntPtr srcimg, IntPtr maskimg, StringBuilder msg, IntPtr mesh_img, IntPtr grid_mesh_img, IntPtr flow_img);
  46. [DllImport(DllName, EntryPoint = "destroy", CallingConvention = CallingConvention.Cdecl)]
  47. internal extern static int destroy(IntPtr engine);
  48. private void Form1_Load(object sender, EventArgs e)
  49. {
  50. startupPath = Application.StartupPath;
  51. string model_dir = startupPath + "\\model\";
  52. StringBuilder msg = new StringBuilder(512);
  53. int res = init(ref engine, model_dir, msg);
  54. if (res == -1)
  55. {
  56. MessageBox.Show(msg.ToString());
  57. return;
  58. }
  59. else
  60. {
  61. Console.WriteLine(msg.ToString());
  62. }
  63. image_path = startupPath + "\\test_img\\39501.png";
  64. pictureBox1.Image = new Bitmap(image_path);
  65. mask_path = startupPath + "\\test_img\\39501_mask.png";
  66. pictureBox3.Image = new Bitmap(mask_path);
  67. }
  68. private void Form1_FormClosed(object sender, FormClosedEventArgs e)
  69. {
  70. destroy(engine);
  71. }
  72. private void button2_Click(object sender, EventArgs e)
  73. {
  74. if (image_path == "" || mask_path == "")
  75. {
  76. return;
  77. }
  78. textBox1.Text = "执行中……";
  79. button2.Enabled = false;
  80. if (pictureBox2.Image != null)
  81. {
  82. pictureBox2.Image.Dispose();
  83. pictureBox2.Image = null;
  84. }
  85. Application.DoEvents();
  86. Cv2.DestroyAllWindows();
  87. if (image != null) image.Dispose();
  88. if (mask != null) mask.Dispose();
  89. if (mesh_img != null) mesh_img.Dispose();
  90. if (grid_mesh_img != null) grid_mesh_img.Dispose();
  91. if (flow_img != null) flow_img.Dispose();
  92. StringBuilder msg = new StringBuilder(512);
  93. image = new Mat(image_path);
  94. mask = new Mat(mask_path,ImreadModes.Grayscale);
  95. mesh_img = new Mat();
  96. grid_mesh_img = new Mat();
  97. flow_img = new Mat();
  98. stopwatch.Restart();
  99. int res = detect(engine, image.CvPtr, mask.CvPtr, msg, mesh_img.CvPtr, grid_mesh_img.CvPtr, flow_img.CvPtr);
  100. if (res == 0)
  101. {
  102. stopwatch.Stop();
  103. double costTime = stopwatch.Elapsed.TotalMilliseconds;
  104. pictureBox2.Image = new Bitmap(flow_img.ToMemoryStream());
  105. Cv2.ImShow("mesh_img", mesh_img);
  106. Cv2.ImShow("grid_mesh_img", grid_mesh_img);
  107. textBox1.Text = $"耗时:{costTime:F2}ms";
  108. }
  109. else
  110. {
  111. textBox1.Text = "失败," + msg.ToString();
  112. }
  113. button2.Enabled = true;
  114. }
  115. private void button1_Click(object sender, EventArgs e)
  116. {
  117. OpenFileDialog ofd = new OpenFileDialog();
  118. ofd.Filter = fileFilter;
  119. ofd.InitialDirectory = startupPath + "\\test_img";
  120. if (ofd.ShowDialog() != DialogResult.OK) return;
  121. pictureBox1.Image = null;
  122. pictureBox2.Image = null;
  123. textBox1.Text = "";
  124. image_path = ofd.FileName;
  125. pictureBox1.Image = new Bitmap(image_path);
  126. image = new Mat(image_path);
  127. }
  128. private void button4_Click(object sender, EventArgs e)
  129. {
  130. OpenFileDialog ofd = new OpenFileDialog();
  131. ofd.Filter = fileFilter;
  132. ofd.InitialDirectory = startupPath+"\\test_img";
  133. if (ofd.ShowDialog() != DialogResult.OK) return;
  134. pictureBox3.Image = null;
  135. pictureBox2.Image = null;
  136. textBox1.Text = "";
  137. mask_path = ofd.FileName;
  138. pictureBox3.Image = new Bitmap(mask_path);
  139. mask = new Mat(image_path);
  140. }
  141. private void button3_Click(object sender, EventArgs e)
  142. {
  143. if (pictureBox2.Image == null)
  144. {
  145. return;
  146. }
  147. Bitmap output = new Bitmap(pictureBox2.Image);
  148. var sdf = new SaveFileDialog();
  149. sdf.Title = "保存";
  150. sdf.Filter = "Images (*.jpg)|*.jpg|Images (*.png)|*.png|Images (*.bmp)|*.bmp";
  151. if (sdf.ShowDialog() == DialogResult.OK)
  152. {
  153. switch (sdf.FilterIndex)
  154. {
  155. case 1:
  156. {
  157. output.Save(sdf.FileName, ImageFormat.Jpeg);
  158. break;
  159. }
  160. case 2:
  161. {
  162. output.Save(sdf.FileName, ImageFormat.Png);
  163. break;
  164. }
  165. case 3:
  166. {
  167. output.Save(sdf.FileName, ImageFormat.Bmp);
  168. break;
  169. }
  170. }
  171. MessageBox.Show("保存成功,位置:" + sdf.FileName);
  172. }
  173. }
  174. }
  175. }
复制代码

下载

源码下载

参考

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

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Honkers

荣誉红客

关注
  • 4008
    主题
  • 36
    粉丝
  • 0
    关注
这家伙很懒,什么都没留下!

中国红客联盟公众号

联系站长QQ:5520533

admin@chnhonker.com
Copyright © 2001-2025 Discuz Team. Powered by Discuz! X3.5 ( 粤ICP备13060014号 )|天天打卡 本站已运行