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