[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);
相关推荐
·心猿意码·18 小时前
C# 垃圾回收机制深度解析
开发语言·c#
bin915318 小时前
PHP文档保卫战:AI自动生成下的创意守护与反制指南
开发语言·人工智能·php·工具·ai工具
歪歪10018 小时前
解决多 Linux 客户端向 Windows 服务端的文件上传、持久化与生命周期管理问题
linux·运维·服务器·开发语言·前端·数据库·windows
Ryan ZX18 小时前
【Go语言基础】序列化和反序列化
开发语言·后端·golang
helloworddm18 小时前
Java和.NET的核心差异
java·开发语言·.net
学习编程的Kitty19 小时前
JavaEE初阶——JUC的工具类和死锁
java·开发语言
草莓熊Lotso19 小时前
《算法闯关指南:优选算法--位运算》--36.两个整数之和,37.只出现一次的数字 ||
开发语言·c++·算法
唐青枫19 小时前
C#.NET 开发必备:常用特性与注解用法大全
c#·.net
yugi98783819 小时前
MyBatis框架如何处理字符串相等的判断条件
java·开发语言·tomcat
彩旗工作室19 小时前
如何在自己的服务器上部署 n8n
开发语言·数据库·nodejs·n8n