C# OpenCV 部署RecRecNet广角图像畸变矫正

news2024/11/24 22:45:30

C# OpenCV 部署RecRecNet广角图像畸变矫正

目录

说明

效果

模型信息

项目

代码

下载


说明

ICCV2023 - RecRecNet: Rectangling Rectified Wide-Angle Images by Thin-Plate Spline Model and DoF-based Curriculum Learning

参考:

https://github.com/KangLiao929/RecRecNet

https://github.com/hpc203/recrecnet-opencv-dnn

效果

模型信息

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

Inputs
-------------------------
name:input
tensor:Float[1, 3, 256, 256]
---------------------------------------------------------------

Outputs
-------------------------
name:output
tensor:Float[1, 162]
---------------------------------------------------------------

项目

代码

using OpenCvSharp;
using OpenCvSharp.Dnn;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;

namespace OpenCvSharp_DNN_Demo
{
    public partial class frmMain : Form
    {
        public frmMain()
        {
            InitializeComponent();
        }

        string fileFilter = "图片|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";
        string image_path = "";

        DateTime dt1 = DateTime.Now;
        DateTime dt2 = DateTime.Now;

        int inpHeight;
        int inpWidth;
        string modelpath;

        int grid_h = 8;
        int grid_w = 8;
        Mat grid;
        Mat W_inv;

        Net opencv_net;
        Mat BN_image;

        Mat image;
        Mat result_image;

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = fileFilter;
            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 Form1_Load(object sender, EventArgs e)
        {
            modelpath = "model/model_deploy.onnx";

            inpHeight = 256;
            inpWidth = 256;

            opencv_net = CvDnn.ReadNetFromOnnx(modelpath);

            Common.get_norm_rigid_mesh_inv_grid(ref grid, ref W_inv, inpHeight, inpWidth, grid_h, grid_w);

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

        }

        private unsafe void button2_Click(object sender, EventArgs e)
        {
            if (image_path == "")
            {
                return;
            }
            textBox1.Text = "检测中,请稍等……";
            pictureBox2.Image = null;
            Application.DoEvents();

            image = new Mat(image_path);
            dt1 = DateTime.Now;

            Mat img = new Mat();

            Cv2.Resize(image, img, new OpenCvSharp.Size(inpWidth, inpHeight));

            img.ConvertTo(img, MatType.CV_32FC3, 1.0f / 127.5f, -1.0f);

            BN_image = CvDnn.BlobFromImage(img);

            //配置图片输入数据
            opencv_net.SetInput(BN_image);

            //模型推理,读取推理结果
            Mat[] outs = new Mat[1] { new Mat() };
            string[] outBlobNames = opencv_net.GetUnconnectedOutLayersNames().ToArray();

            opencv_net.Forward(outs, outBlobNames);

            dt2 = DateTime.Now;

            float* offset = (float*)outs[0].Data;

            Mat tp = new Mat();
            Mat ori_mesh_np_x = new Mat();
            Mat ori_mesh_np_y = new Mat();
            Common.get_ori_rigid_mesh_tp(tp, ori_mesh_np_x, ori_mesh_np_y, offset, inpHeight, inpWidth, grid_h, grid_w);
            Mat T = W_inv * tp;   
            T = T.T();    

            Mat T_g = T * grid;

            Mat output_tps = Common._interpolate(BN_image, T_g, new OpenCvSharp.Size(inpWidth, inpHeight));
            Mat rectangling_np = (output_tps + 1) * 127.5;
            rectangling_np.ConvertTo(rectangling_np, MatType.CV_8UC3);
            Mat input_np = (img + 1) * 127.5;

            List<Mat> outputs = new List<Mat>();
            outputs.Add(rectangling_np);
            outputs.Add(input_np);
            outputs.Add(ori_mesh_np_x);
            outputs.Add(ori_mesh_np_y);

            Mat input_with_mesh = Common.draw_mesh_on_warp(outputs[1], outputs[2], outputs[3]);

            Cv2.CvtColor(outputs[0], outputs[0], ColorConversionCodes.BGR2RGB);

            Cv2.ImShow("mesh", input_with_mesh);

            result_image = outputs[0].Clone();
            pictureBox2.Image = new Bitmap(result_image.ToMemoryStream());
            textBox1.Text = "推理耗时:" + (dt2 - dt1).TotalMilliseconds + "ms";

        }

        private void pictureBox2_DoubleClick(object sender, EventArgs e)
        {
            Common.ShowNormalImg(pictureBox2.Image);
        }

        private void pictureBox1_DoubleClick(object sender, EventArgs e)
        {
            Common.ShowNormalImg(pictureBox1.Image);
        }
    }
}
 

using OpenCvSharp;
using OpenCvSharp.Dnn;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;

namespace OpenCvSharp_DNN_Demo
{
    public partial class frmMain : Form
    {
        public frmMain()
        {
            InitializeComponent();
        }

        string fileFilter = "图片|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";
        string image_path = "";

        DateTime dt1 = DateTime.Now;
        DateTime dt2 = DateTime.Now;

        int inpHeight;
        int inpWidth;
        string modelpath;

        int grid_h = 8;
        int grid_w = 8;
        Mat grid;
        Mat W_inv;

        Net opencv_net;
        Mat BN_image;

        Mat image;
        Mat result_image;

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = fileFilter;
            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 Form1_Load(object sender, EventArgs e)
        {
            modelpath = "model/model_deploy.onnx";

            inpHeight = 256;
            inpWidth = 256;

            opencv_net = CvDnn.ReadNetFromOnnx(modelpath);

            Common.get_norm_rigid_mesh_inv_grid(ref grid, ref W_inv, inpHeight, inpWidth, grid_h, grid_w);

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

        }

        private unsafe void button2_Click(object sender, EventArgs e)
        {
            if (image_path == "")
            {
                return;
            }
            textBox1.Text = "检测中,请稍等……";
            pictureBox2.Image = null;
            Application.DoEvents();

            image = new Mat(image_path);
            dt1 = DateTime.Now;

            Mat img = new Mat();

            Cv2.Resize(image, img, new OpenCvSharp.Size(inpWidth, inpHeight));

            img.ConvertTo(img, MatType.CV_32FC3, 1.0f / 127.5f, -1.0f);

            BN_image = CvDnn.BlobFromImage(img);

            //配置图片输入数据
            opencv_net.SetInput(BN_image);

            //模型推理,读取推理结果
            Mat[] outs = new Mat[1] { new Mat() };
            string[] outBlobNames = opencv_net.GetUnconnectedOutLayersNames().ToArray();

            opencv_net.Forward(outs, outBlobNames);

            dt2 = DateTime.Now;

            float* offset = (float*)outs[0].Data;

            Mat tp = new Mat();
            Mat ori_mesh_np_x = new Mat();
            Mat ori_mesh_np_y = new Mat();
            Common.get_ori_rigid_mesh_tp(tp, ori_mesh_np_x, ori_mesh_np_y, offset, inpHeight, inpWidth, grid_h, grid_w);
            Mat T = W_inv * tp;   
            T = T.T();    

            Mat T_g = T * grid;

            Mat output_tps = Common._interpolate(BN_image, T_g, new OpenCvSharp.Size(inpWidth, inpHeight));
            Mat rectangling_np = (output_tps + 1) * 127.5;
            rectangling_np.ConvertTo(rectangling_np, MatType.CV_8UC3);
            Mat input_np = (img + 1) * 127.5;

            List<Mat> outputs = new List<Mat>();
            outputs.Add(rectangling_np);
            outputs.Add(input_np);
            outputs.Add(ori_mesh_np_x);
            outputs.Add(ori_mesh_np_y);

            Mat input_with_mesh = Common.draw_mesh_on_warp(outputs[1], outputs[2], outputs[3]);

            Cv2.CvtColor(outputs[0], outputs[0], ColorConversionCodes.BGR2RGB);

            Cv2.ImShow("mesh", input_with_mesh);

            result_image = outputs[0].Clone();
            pictureBox2.Image = new Bitmap(result_image.ToMemoryStream());
            textBox1.Text = "推理耗时:" + (dt2 - dt1).TotalMilliseconds + "ms";

        }

        private void pictureBox2_DoubleClick(object sender, EventArgs e)
        {
            Common.ShowNormalImg(pictureBox2.Image);
        }

        private void pictureBox1_DoubleClick(object sender, EventArgs e)
        {
            Common.ShowNormalImg(pictureBox1.Image);
        }
    }
}

下载

源码下载

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

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

相关文章

Vue52-scoped样式

一、scoped样式的作用 1-1、scoped样式的作用 vue中组件的样式都是汇总到一起的。容易出现一个问题&#xff1a;类名冲突。 示例&#xff1a; school和student组件的类名都叫demo&#xff0c;则student的样式将覆盖school的样式&#xff0c;因为App.vue中&#xff0c;先引入的…

Spring事务管理、SpringAop

目录 ​编辑 Spring事务管理 注解:Transactional rollbackFor 事务属性-传播行为 propagation SpringAOP AOP核心概念 通知类型 通知顺序 切入点表达式 切入点表达式-execution 切入点表达式-annotation 连接点 ​编辑 将案例中 增、删、改 相关接口的操作日志记…

unity跑酷游戏(源码)

包括&#xff1a;触发机关&#xff0c; 优化 fog的调试 效果 碰到障碍物游戏时间暂停&#xff08;挂载到障碍物上&#xff09; 上面需要有碰撞体 游戏物体上需要有标签 using System.Collections; using System.Collections.Generic; using UnityEngine;public class Barri…

【仿真建模-anylogic】FlowchartBlock原理解析

Author&#xff1a;赵志乾 Date&#xff1a;2024-06-17 Declaration&#xff1a;All Right Reserved&#xff01;&#xff01;&#xff01; 1. 类图 2. 原理解析 2.1 核心函数 函数功能FlowchartBlock(Engine engine ,Agent owner, AgentList population )构造函数&#xff…

C语言王国——深入自定义类型(结构体)

目录 一、引言 二、结构体 1. 结构体类型的声明 2. 结构体变量的创建和初始化 2.1 创建 2.2 初始化 2.3 typedef 2.4 特殊声明 2.5 自引用 3. 结构成员访问操作符 4. 结构体内存对齐 4.1 对齐规则 4.2 offsetof 4.3 为什么存在内存对齐 5. 结构体传参 6. 结构体实现…

仅靠独立网站也能赚到100万,真的太牛了

你听说过 Photopea 吗&#xff1f;这是一个免费的类似 Photoshop 的图像编辑器。 这个项目&#xff1a; 每月1300万访问量每月150万用户使用小时每月10万美元的广告收入 Photopea 项目的天才创造者是 Ivan Kutskir。 令人惊讶的是&#xff0c;他独自处理了每日50万用户&…

数组趣味玩法:在Java SE中尝试创新玩法

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。运营社区&#xff1a;C站/掘金/腾讯云&#xff1b;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相学习&#xff0c;一…

C++ | Leetcode C++题解之第160题相交链表

题目&#xff1a; 题解&#xff1a; class Solution { public:ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {if (headA nullptr || headB nullptr) {return nullptr;}ListNode *pA headA, *pB headB;while (pA ! pB) {pA pA nullptr ? headB : p…

【Vue3】插槽的使用及其分类

历史小剧场 后来我才明白&#xff0c;造反的宋江&#xff0c;和招安的宋江&#xff0c;始终是同一个人。 为什么要造反&#xff1f; 造反&#xff0c;就是为了招安。 ----《明朝那些事儿》 概念 在日常的项目开发中&#xff0c;当我们在编写一个完整的组件时&#xff0c;不可避…

款基于SpringBoot+Vue+ElementUI技术栈开发的自定义表单工具(已开源)

TDuck填鸭表单是一个开源的问卷调查系统&#xff0c;一款基于SpringBootVueElementUI技术栈开发的自定义表单工具&#xff0c;它不仅支持问卷调查&#xff0c;还能进行数据收集。TDuck团队经过两年的优化&#xff0c;使得社区版功能趋于稳定。2023年5月&#xff0c;团队推出了可…

flstudio怎么调中文

FL Studio设置中文的步骤如下&#xff1a; 打开FL Studio&#xff1a;首先&#xff0c;需要打开FL Studio编曲软件。 进入常规设置&#xff1a;在软件顶部菜单栏中&#xff0c;选择“OPTIONS”&#xff0c;然后点击“General setting”&#xff0c;进入常规设置窗口。 切换语言…

Centos部署openGauss6.0创新版本,丝滑的体验

作者&#xff1a;IT邦德 中国DBA联盟(ACDU)成员&#xff0c;10余年DBA工作经验&#xff0c; Oracle、PostgreSQL ACE CSDN博客专家及B站知名UP主&#xff0c;全网粉丝10万 擅长主流Oracle、MySQL、PG、高斯及Greenplum备份恢复&#xff0c; 安装迁移&#xff0c;性能优化、故障…

Pytest框架中fixture功能详解

文章目录 1 定义 Fixture函数 2 Fixture 的函数参数 2.1 传入其他fixture函数作为参数 2.2 传入request对象参数 示例1&#xff1a;访问fixture的调用者 示例2&#xff1a;使用fixture的参数 3 Fixture 的作用域参数scope 3.1 scopeclass场景 3.2 scopesession场景 4…

ImageNet-1k 测试集 两大坑

1、官方网站提交test set标签时&#xff0c;千万不能提交zip文件&#xff0c;即便明文说可以 https://image-net.org/challenges/LSVRC/eval_server.php 不然就会浪费一次提交机会&#xff0c;直接提交submission.txt就可以&#xff0c;注意每排5个预测结果&#xff0c;用于计…

Excel报表

(Apache POI) 入门案例 P164 使用POI需要导入下面2个坐标&#xff1a; <dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId> </dependency> <dependency><groupId>org.apache.poi</groupId>&…

[个人感悟] 缓存应该考察哪些问题?

前言 缓存, 根据冯诺依曼计算机模型, 无非是为了更高效的交互, 使用内存IO替换本地磁盘IO. 又因为内存的稀缺性, 其必然存储的是热点数据, 且较小的数据. [虽然直至今日, 已有使用缓存作为数据库的使用, 但是与磁盘IO相比, 其价格仍是数倍之多.] 当涉及缓存问题时, 又分为本地…

springboot+vue+mybatis教师工作审核系统+PPT+论文+讲解+售后

随着社会不断进步与发展&#xff0c;生活节奏不断加快&#xff0c;信息已经成为我们生活中不可缺少的一部分&#xff0c;很多学校需要掌握大量的信息来了解特定学生的需求&#xff0c;传统的做法是组织大量的人力物力对学生散发调查表&#xff0c;然后对收集的信息进行统计并得…

【SOEM主站】EtherCAT主站时钟偏移补偿

在进行EtherCAT主从通讯测试时&#xff0c;比较容易在DC配置出现错误&#xff0c;特别是使用到从站DC模式时&#xff0c;有时会报同步错误&#xff0c;有时即使没报错误伺服从站运行过程中也会出现电机轴的抖动。引起同步错误其中一个原因就是主站发送数据帧时间存在较大的抖动…

一文带你精通Android中的Activity

本文将会从活动的生命周期、启动模式、Intent数据传输、最佳实践等多维度来讲解Activity&#xff0c;希望对你有用 生命周期 深入理解活动的生命周期&#xff0c;可以帮助我们更加流畅地编程&#xff0c;并在管理系统资源方面更加游刃有余 活动状态 每个活动在生命周期中最…

《Windows API每日一练》4.4 绘制填充区域

本节讲述如何填充由线条构建的封闭区域。当我们初始化一个窗口类时&#xff0c;往往已经指定了窗口的背景色画刷&#xff08;WHITE_BRUSH&#xff09;&#xff0c;即默认的填充封闭区域背景的画刷。如果我们想更换背景颜色&#xff0c;需要选入其他系统预定义的画刷&#xff08…