[C#]将opencvsharp的Mat对象转成onnxruntime的inputtensor的3种方法

第一种方法:在创建tensor时候直接赋值改变每个tensor的值,以下是伪代码:

复制代码
            var image = new Mat(image_path);
            inpWidth = image.Width;
            inpHeight = image.Height;
            //将图片转为RGB通道
            Mat image_rgb = new Mat();
            Cv2.CvtColor(image, image_rgb, ColorConversionCodes.BGR2RGB);
            //输入Tensor
            input_tensor = new DenseTensor<float>(new[] { 1, 3, inpHeight, inpWidth });
            for (int y = 0; y < image_rgb.Height; y++)
            {
                for (int x = 0; x < image_rgb.Width; x++)
                {
                    input_tensor[0, 0, y, x] = image_rgb.At<Vec3b>(y, x)[0] / 255f;
                    input_tensor[0, 1, y, x] = image_rgb.At<Vec3b>(y, x)[1] / 255f;
                    input_tensor[0, 2, y, x] = image_rgb.At<Vec3b>(y, x)[2] / 255f;
                }
            }

            //将 input_tensor 放入一个输入参数的容器,并指定名称
            input_container.Add(NamedOnnxValue.CreateFromTensor("input", input_tensor));

            //运行 Inference 并获取结果
            result_infer = onnx_session.Run(input_container);

第2种通过不安全指针进行赋值以下是伪代码:

复制代码
            var image = new Mat(image_path);

            Mat dstimg = new Mat();

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

            dstimg.ConvertTo(dstimg, MatType.CV_32FC3, 1 / 127.5, -1.0);

            float* pdata = (float*)dstimg.Data;
            float[] input_tensor_data = new float[1 * 3 * inpWidth * inpHeight];
            for (int i = 0; i < 1 * 3 * inpWidth * inpHeight; i++)
            {
                input_tensor_data[i] = pdata[i];
            }

            //输入Tensor
            input_tensor = new DenseTensor<float>(input_tensor_data, new[] { 1, inpHeight, inpWidth, 3 });

            //将 input_tensor 放入一个输入参数的容器,并指定名称
            input_container.Add(NamedOnnxValue.CreateFromTensor("input_1", input_tensor));
            //运行 Inference 并获取结果
            result_infer = onnx_session.Run(input_container);

第3种通过不安全指针进行赋值,本质和第2种方法一样,但是这个是通过图像指针直接赋值以下是伪代码:

示范代码1:

复制代码
            var image = new Mat(image_path);
 
            Mat resize_image = new Mat();
            Cv2.Resize(image, resize_image, new OpenCvSharp.Size(512, 512));
 
            float h_ratio = (float)image.Rows / 512;
            float w_ratio = (float)image.Cols / 512;
 
            int row = resize_image.Rows;
            int col = resize_image.Cols;
            float[] input_tensor_data = new float[1 * 4 * row * col];
            int k = 0;
            for (int i = 0; i < row; i++)
            {
                for (int j = 0; j < col; j++)
                {
                    for (int c = 0; c < 3; c++)
                    {
                        float pix = ((byte*)(resize_image.Ptr(i).ToPointer()))[j * 3 + c];
                        input_tensor_data[k] = pix;
                        k++;
                    }
                    input_tensor_data[k] = 1;
                    k++;
                }
            }
 
            input_tensor = new DenseTensor<float>(input_tensor_data, new[] { 1, 512, 512, 4 });
 
            //将 input_tensor 放入一个输入参数的容器,并指定名称
            input_container.Add(NamedOnnxValue.CreateFromTensor("input_image_with_alpha:0", input_tensor));
 
            //运行 Inference 并获取结果
            result_infer = onnx_session.Run(input_container);

示范代码2:

复制代码
            var image = new Mat(image_path);
 
            int img_height = image.Rows;
            int img_width = image.Cols;
 
            Mat resize_image = new Mat();
            Cv2.Resize(image, resize_image, new OpenCvSharp.Size(inpWidth, inpHeight));
 
            int row = resize_image.Rows;
            int col = resize_image.Cols;
 
            float[] input_tensor_data = new float[1 * 3 * inpHeight * inpWidth];
            for (int c = 0; c < 3; c++)
            {
                for (int i = 0; i < row; i++)
                {
                    for (int j = 0; j < col; j++)
                    {
                        float pix = ((byte*)(resize_image.Ptr(i).ToPointer()))[j * 3 + c];
                        input_tensor_data[c * row * col + i * col + j] = (float)((pix / 255.0 - mean[c]) / std[c]);
                    }
                }
            }
            input_tensor = new DenseTensor<float>(input_tensor_data, new[] { 1, 3, inpHeight, inpWidth });
 
            //将 input_tensor 放入一个输入参数的容器,并指定名称
            input_ontainer.Add(NamedOnnxValue.CreateFromTensor("input", input_tensor));
            //运行 Inference 并获取结果
            result_infer = onnx_session.Run(input_ontainer);
相关推荐
小码编匠6 小时前
WPF 中的高级交互通过右键拖动实现图像灵活缩放
后端·c#·.net
唐青枫13 小时前
C#.NET 定时任务与队列利器:Hangfire 完整教程
c#·.net
hez201019 小时前
Runtime Async - 步入高性能异步时代
c#·.net·.net core·clr
mudtools1 天前
.NET驾驭Word之力:玩转文本与格式
c#·.net
唐青枫1 天前
C#.NET 数据库开发提速秘籍:SqlSugar 实战详解
c#·.net
mudtools2 天前
.NET驾驭Word之力:理解Word对象模型核心 (Application, Document, Range)
c#·.net
侃侃_天下2 天前
最终的信号类
开发语言·c++·算法
echoarts2 天前
Rayon Rust中的数据并行库入门教程
开发语言·其他·算法·rust
Aomnitrix2 天前
知识管理新范式——cpolar+Wiki.js打造企业级分布式知识库
开发语言·javascript·分布式
大飞pkz2 天前
【设计模式】C#反射实现抽象工厂模式
设计模式·c#·抽象工厂模式·c#反射·c#反射实现抽象工厂模式