C# RestoreFormer image (face) repair

Introduction

github address: https://github.com/wzhouxiff/RestoreFormer

[CVPR 2022] RestoreFormer: High-Quality Blind Face Restoration from Undegraded Key-Value Pairs

RestoreFormer tends to explore fully-spatial attentions to model contextual information and surpasses existing works that use local operators. It has several benefits compared to prior arts. First, it incorporates a multi-head coross-attention layer to learn fully-spatial interations between corrupted queries and high-quality key-value pairs. Second, the key-value pairs in RestoreFormer are sampled from a reconstruction-oriented high-quality dictionary, whose elements are rich in high-quality facial features specifically aimed for face reconstruction.

Effect

Model information

Inputs
———————–
name: input
tensor: Float[-1, 3, 512, 512]
————————————————– ————-

Outputs
———————–
name:output
tensor: Float[-1, 3, -1, -1]
————————————————– ————-

Project

VS2022

.net framework 4.8

OpenCvSharp 4.8

Microsoft.ML.OnnxRuntime 1.16.2

Code

CreateTensor
input_tensor = new DenseTensor(new[] { 1, 3, 512, 512 });
for (int y = 0; y < resize_image.Height; y + + )
{
for (int x = 0; x < resize_image.Width; x + + )
{
input_tensor[0, 0, y, x] = (resize_image.At(y, x)[0] / 255f – 0.5f) / 0.5f;
input_tensor[0, 1, y, x] = (resize_image.At(y, x)[1] / 255f – 0.5f) / 0.5f;
input_tensor[0, 2, y, x] = (resize_image.At(y, x)[2] / 255f – 0.5f) / 0.5f;
}
}

using Microsoft.ML.OnnxRuntime;
using Microsoft.ML.OnnxRuntime.Tensors;
using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;


namespace image repair
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";
        string image_path = "";
        string startupPath;
        DateTime dt1 = DateTime.Now;
        DateTime dt2 = DateTime.Now;
        int modelSize = 512;
        string model_path;

        Mat image;
        Mat result_image;

        SessionOptions options;
        InferenceSession onnx_session;
        Tensor<float> input_tensor;
        List<NamedOnnxValue> input_container;

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = fileFilter;
            if (ofd.ShowDialog() != DialogResult.OK) return;
            pictureBox1.Image = null;
            image_path = ofd.FileName;
            pictureBox1.Image = new Bitmap(image_path);
            textBox1.Text = "";
            image = new Mat(image_path);
            pictureBox2.Image = null;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (image_path == "")
            {
                return;
            }

            textBox1.Text = "";
            pictureBox2.Image = null;

            result_image = OnnxHelper.Run(image, modelSize, input_tensor, input_container, onnx_session, ref dt1, ref dt2);

            if (!result_image.Empty())
            {
                pictureBox2.Image = new Bitmap(result_image.ToMemoryStream());
                textBox1.Text = "Inference time consumption:" + (dt2 - dt1).TotalMilliseconds + "ms";
            }
            else
            {
                textBox1.Text = "No information";
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            startupPath = Application.StartupPath;

            model_path = startupPath + "\model\restoreformer.onnx";

            modelSize = 512;

            //Create an output session to output model reading information
            options = new SessionOptions();
            options.LogSeverityLevel = OrtLoggingLevel.ORT_LOGGING_LEVEL_INFO;
            //Set to run on CPU
            options.AppendExecutionProvider_CPU(0);

            //Create an inference model class and read local model files
            onnx_session = new InferenceSession(model_path, options);

            //Input Tensor
            input_tensor = new DenseTensor<float>(new[] { 1, 3, modelSize, modelSize });

            //Create input container
            input_container = new List<NamedOnnxValue>();
        }

        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 = "Save";
            sdf.Filter = "Images (*.jpg)|*.jpg|Images (*.png)|*.png|Images (*.bmp)|*.bmp|Images (*.emf)|*.emf|Images (*.exif)|*.exif|Images (*.gif)|*.gif|Images (*.ico)|*.ico|Images (*.tiff)|*.tiff|Images (*.wmf)| *.wmf";
            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;
                        }
                    case 4:
                        {
                            output.Save(sdf.FileName, ImageFormat.Emf);
                            break;
                        }
                    case 5:
                        {
                            output.Save(sdf.FileName, ImageFormat.Exif);
                            break;
                        }
                    case 6:
                        {
                            output.Save(sdf.FileName, ImageFormat.Gif);
                            break;
                        }
                    case 7:
                        {
                            output.Save(sdf.FileName, ImageFormat.Icon);
                            break;
                        }
                    case 8:
                        {
                            output.Save(sdf.FileName, ImageFormat.Tiff);
                            break;
                        }
                    case 9:
                        {
                            output.Save(sdf.FileName, ImageFormat.Wmf);
                            break;
                        }
                }
                MessageBox.Show("Save successfully, location: " + sdf.FileName);
            }
        }
    }
}

Download

Runnable program exe download

Source code download

Others

C# CodeFormer Image Repair-CSDN Blog

C# GFPGAN Image Repair-CSDN Blog

C# GPEN-BFR Image Repair-CSDN Blog

The knowledge points of the article match the official knowledge archive, and you can further learn related knowledge. OpenCV skill treeDeep learning in OpenCVImage classification 23363 people are learning the system