• yolov10--C#接口


    一、前言

         本章主要讲解yolov10的C#接口,主要是使用微软开发的openvinocsharp工具加载yolov10模型,并做推理。

    二、yolov10模型转换

         这里为了演示,使用官方yolov10m模型(其他大小的模型同理)做演示,可从下方下载,当然也可以是自己训练好的模型

    https://github.com/THU-MIG/yolov10/releases/download/v1.1/yolov10m.pt

          该原始模型,需要被转换为openvinocsharp所支持的模型格式,为此需要建立一个yolov10的python环境,使用conda创建,requirements.txt 为 yolov10官方代码下的所需包

    1. conda create -n yolov10 python=3.9
    2. conda activate yolov10
    3. pip install -r requirements.txt
    4. pip install -e .

    然后安装OpenVINO™环境,输入以下指令

    pip install openvino==2024.1.0
    

    在该创建好的虚拟环境,cd 至下载好的yolov10m.pt 所在目录,执行

    1. yolo export model=yolov10m.pt format=onnx opset=11 simplify
    2. ovc yolov10m.onnx

    这样,pt文件的模型将转换为onnx文件,再换换为 openvino 所需的 bin 和 xml 文件格式

    三、C#端openvinosharp相关包安装

             首先需使用VS2022构建项目,其次将openvinosharp相关包安装上

    1. "Microsoft.NET.Sdk">
    2. Exe
    3. net6.0
    4. enable
    5. enable
    6. "OpenCvSharp4" Version="4.9.0.20240103" />
    7. "OpenCvSharp4.Extensions" Version="4.9.0.20240103" />
    8. "OpenCvSharp4.runtime.win" Version="4.9.0.20240103" />
    9. "OpenVINO.CSharp.API" Version="2024.1.0.1" />
    10. "OpenVINO.CSharp.API.Extensions.OpenCvSharp" Version="1.0.4" />
    11. "OpenVINO.runtime.win" Version="2024.1.0.1" />

    也就是  OpenCvSharp4、OpenCvSharp4.Extensions、OpenCvSharp4.runtime.win、OpenVINO.CSharp.API、OpenVINO.CSharp.API.Extensions.OpenCvSharp、OpenVINO.runtime.win,这6个包给装上

    这部分参考自下面博客

    【OpenVINO™】在C#中使用 OpenVINO™ 部署 YOLOv10 模型实现目标_yolov10 openvino-CSDN博客

    四、C#加载yolo10推理代码

    这样就可以创建C# winform项目,愉快地加载前面转换好的模型文件做前向推理了

    1. // See https://aka.ms/new-console-template for more information
    2. //Console.WriteLine("Hello, World!");
    3. using System.Reflection;
    4. using System.Runtime.InteropServices;
    5. using System;
    6. using OpenVinoSharp;
    7. using OpenVinoSharp.Extensions.utility;
    8. using OpenVinoSharp.Extensions;
    9. using OpenCvSharp;
    10. using OpenCvSharp.Dnn;
    11. using OpenVinoSharp.preprocess;
    12. namespace yolov10_det_opencvsharp
    13. {
    14. internal class Program
    15. {
    16. static void Main(string[] args)
    17. {
    18. string model_path = "./model_demo/yolov10m.xml";
    19. string image_path = "./model_demo/cat.png";
    20. string device = "AUTO"; //CPU GPU AUTO,可选AUTO模式
    21. // -------- Get OpenVINO runtime version --------
    22. OpenVinoSharp.Version version = Ov.get_openvino_version();
    23. Slog.INFO("---- OpenVINO INFO----");
    24. Slog.INFO("Description : " + version.description);
    25. Slog.INFO("Build number: " + version.buildNumber);
    26. Slog.INFO("Predict model files: " + model_path);
    27. Slog.INFO("Predict image files: " + image_path);
    28. Slog.INFO("Inference device: " + device);
    29. Slog.INFO("Start yolov10 model inference.");
    30. //yolov10_det(model_path, image_path, device);
    31. yolov10_det_process(model_path, image_path , device);
    32. }
    33. static void yolov10_det(string model_path, string image_path, string device)
    34. {
    35. DateTime start = DateTime.Now;
    36. // -------- Step 1. Initialize OpenVINO Runtime Core --------
    37. Core core = new Core();
    38. DateTime end = DateTime.Now;
    39. Slog.INFO("1. Initialize OpenVINO Runtime Core success, time spend: " + (end - start).TotalMilliseconds + "ms.");
    40. // -------- Step 2. Read inference model --------
    41. start = DateTime.Now;
    42. Model model = core.read_model(model_path);
    43. end = DateTime.Now;
    44. Slog.INFO("2. Read inference model success, time spend: " + (end - start).TotalMilliseconds + "ms.");
    45. OvExtensions.printf_model_info(model);
    46. // -------- Step 3. Loading a model to the device --------
    47. start = DateTime.Now;
    48. CompiledModel compiled_model = core.compile_model(model, device);
    49. end = DateTime.Now;
    50. Slog.INFO("3. Loading a model to the device success, time spend:" + (end - start).TotalMilliseconds + "ms.");
    51. // -------- Step 4. Create an infer request --------
    52. start = DateTime.Now;
    53. InferRequest infer_request = compiled_model.create_infer_request();
    54. end = DateTime.Now;
    55. Slog.INFO("4. Create an infer request success, time spend:" + (end - start).TotalMilliseconds + "ms.");
    56. // -------- Step 5. Process input images --------
    57. start = DateTime.Now;
    58. Mat image = new Mat(image_path); // Read image by opencvsharp
    59. int max_image_length = image.Cols > image.Rows ? image.Cols : image.Rows;
    60. Mat max_image = Mat.Zeros(new OpenCvSharp.Size(max_image_length, max_image_length), MatType.CV_8UC3);
    61. Rect roi = new Rect(0, 0, image.Cols, image.Rows);
    62. image.CopyTo(new Mat(max_image, roi));
    63. float factor = (float)(max_image_length / 640.0);
    64. end = DateTime.Now;
    65. Slog.INFO("5. Process input images success, time spend:" + (end - start).TotalMilliseconds + "ms.");
    66. // -------- Step 6. Set up input data --------
    67. start = DateTime.Now;
    68. Tensor input_tensor = infer_request.get_input_tensor();
    69. Shape input_shape = input_tensor.get_shape();
    70. Mat input_mat = CvDnn.BlobFromImage(max_image, 1.0 / 255.0, new OpenCvSharp.Size(input_shape[2], input_shape[3]), 0, true, false);
    71. float[] input_data = new float[input_shape[1] * input_shape[2] * input_shape[3]];
    72. Marshal.Copy(input_mat.Ptr(0), input_data, 0, input_data.Length);
    73. input_tensor.set_data<float>(input_data);
    74. end = DateTime.Now;
    75. Slog.INFO("6. Set up input data success, time spend:" + (end - start).TotalMilliseconds + "ms.");
    76. // -------- Step 7. Do inference synchronously --------
    77. infer_request.infer();
    78. start = DateTime.Now;
    79. infer_request.infer();
    80. end = DateTime.Now;
    81. Slog.INFO("7. Do inference synchronously success, time spend:" + (end - start).TotalMilliseconds + "ms.");
    82. // -------- Step 8. Get infer result data --------
    83. start = DateTime.Now;
    84. Tensor output_tensor = infer_request.get_output_tensor();
    85. int output_length = (int)output_tensor.get_size();
    86. float[] output_data = output_tensor.get_data<float>(output_length);
    87. end = DateTime.Now;
    88. Slog.INFO("8. Get infer result data success, time spend:" + (end - start).TotalMilliseconds + "ms.");
    89. -------- Step 9. Process reault --------
    90. start = DateTime.Now;
    91. List position_boxes = new List();
    92. List<int> class_ids = new List<int>();
    93. List<float> confidences = new List<float>();
    94. // Preprocessing output results
    95. for (int i = 0; i < output_data.Length / 6; i++)
    96. {
    97. int s = 6 * i;
    98. if ((float)output_data[s + 4] > 0.5)
    99. {
    100. float cx = output_data[s + 0];
    101. float cy = output_data[s + 1];
    102. float dx = output_data[s + 2];
    103. float dy = output_data[s + 3];
    104. int x = (int)((cx) * factor);
    105. int y = (int)((cy) * factor);
    106. int width = (int)((dx - cx) * factor);
    107. int height = (int)((dy - cy) * factor);
    108. Rect box = new Rect();
    109. box.X = x;
    110. box.Y = y;
    111. box.Width = width;
    112. box.Height = height;
    113. position_boxes.Add(box);
    114. class_ids.Add((int)output_data[s + 5]);
    115. confidences.Add((float)output_data[s + 4]);
    116. }
    117. }
    118. end = DateTime.Now;
    119. Slog.INFO("9. Process reault success, time spend:" + (end - start).TotalMilliseconds + "ms.");
    120. for (int i = 0; i < class_ids.Count; i++)
    121. {
    122. int index = i;
    123. Cv2.Rectangle(image, position_boxes[index], new Scalar(0, 0, 255), 2, LineTypes.Link8);
    124. Cv2.Rectangle(image, new OpenCvSharp.Point(position_boxes[index].TopLeft.X, position_boxes[index].TopLeft.Y + 30),
    125. new OpenCvSharp.Point(position_boxes[index].BottomRight.X, position_boxes[index].TopLeft.Y), new Scalar(0, 255, 255), -1);
    126. Cv2.PutText(image, class_ids[index] + "-" + confidences[index].ToString("0.00"),
    127. new OpenCvSharp.Point(position_boxes[index].X, position_boxes[index].Y + 25),
    128. HersheyFonts.HersheySimplex, 0.8, new Scalar(0, 0, 0), 2);
    129. }
    130. string output_path = Path.Combine(Path.GetDirectoryName(Path.GetFullPath(image_path)),
    131. Path.GetFileNameWithoutExtension(image_path) + "_result.jpg");
    132. Cv2.ImWrite(output_path, image);
    133. Slog.INFO("The result save to " + output_path);
    134. Cv2.ImShow("Result", image);
    135. Cv2.WaitKey(0);
    136. }
    137. static void yolov10_det_process(string model_path, string image_path, string device)
    138. {
    139. DateTime start = DateTime.Now;
    140. // -------- Step 1. Initialize OpenVINO Runtime Core --------
    141. Core core = new Core();
    142. DateTime end = DateTime.Now;
    143. Slog.INFO("1. Initialize OpenVINO Runtime Core success, time spend: " + (end - start).TotalMilliseconds + "ms.");
    144. // -------- Step 2. Read inference model --------
    145. start = DateTime.Now;
    146. Model model = core.read_model(model_path);
    147. end = DateTime.Now;
    148. Slog.INFO("2. Read inference model success, time spend: " + (end - start).TotalMilliseconds + "ms.");
    149. OvExtensions.printf_model_info(model);
    150. PrePostProcessor processor = new PrePostProcessor(model);
    151. Tensor input_tensor_pro = new Tensor(new OvType(ElementType.U8), new Shape(1, 640, 640, 3)); //注意这个地方要改和模型窗口一致,模型是640,这里也要640
    152. InputInfo input_info = processor.input(0);
    153. InputTensorInfo input_tensor_info = input_info.tensor();
    154. input_tensor_info.set_from(input_tensor_pro).set_layout(new Layout("NHWC")).set_color_format(ColorFormat.BGR);
    155. PreProcessSteps process_steps = input_info.preprocess();
    156. process_steps.convert_color(ColorFormat.RGB).resize(ResizeAlgorithm.RESIZE_LINEAR)
    157. .convert_element_type(new OvType(ElementType.F32)).scale(255.0f).convert_layout(new Layout("NCHW"));
    158. Model new_model = processor.build();
    159. // -------- Step 3. Loading a model to the device --------
    160. start = DateTime.Now;
    161. CompiledModel compiled_model = core.compile_model(new_model, device);
    162. end = DateTime.Now;
    163. Slog.INFO("3. Loading a model to the device success, time spend:" + (end - start).TotalMilliseconds + "ms.");
    164. // -------- Step 4. Create an infer request --------
    165. start = DateTime.Now;
    166. InferRequest infer_request = compiled_model.create_infer_request();
    167. end = DateTime.Now;
    168. Slog.INFO("4. Create an infer request success, time spend:" + (end - start).TotalMilliseconds + "ms.");
    169. // -------- Step 5. Process input images --------
    170. start = DateTime.Now;
    171. Mat image = new Mat(image_path); // Read image by opencvsharp
    172. int max_image_length = image.Cols > image.Rows ? image.Cols : image.Rows;
    173. Mat max_image = Mat.Zeros(new OpenCvSharp.Size(max_image_length, max_image_length), MatType.CV_8UC3);
    174. Rect roi = new Rect(0, 0, image.Cols, image.Rows);
    175. image.CopyTo(new Mat(max_image, roi));
    176. Cv2.Resize(max_image, max_image, new OpenCvSharp.Size(640, 640)); //注意这个地方要改和模型窗口一致,模型是640,这里也要640
    177. float factor = (float)(max_image_length / 640.0);
    178. end = DateTime.Now;
    179. Slog.INFO("5. Process input images success, time spend:" + (end - start).TotalMilliseconds + "ms.");
    180. // -------- Step 6. Set up input data --------
    181. start = DateTime.Now;
    182. Tensor input_tensor = infer_request.get_input_tensor();
    183. Shape input_shape = input_tensor.get_shape();
    184. byte[] input_data = new byte[input_shape[1] * input_shape[2] * input_shape[3]];
    185. //max_image.GetArray(out input_data);
    186. Marshal.Copy(max_image.Ptr(0), input_data, 0, input_data.Length);
    187. IntPtr destination = input_tensor.data();
    188. Marshal.Copy(input_data, 0, destination, input_data.Length);
    189. end = DateTime.Now;
    190. Slog.INFO("6. Set up input data success, time spend:" + (end - start).TotalMilliseconds + "ms.");
    191. // -------- Step 7. Do inference synchronously --------
    192. infer_request.infer();
    193. start = DateTime.Now;
    194. infer_request.infer();
    195. end = DateTime.Now;
    196. Slog.INFO("7. Do inference synchronously success, time spend:" + (end - start).TotalMilliseconds + "ms.");
    197. // -------- Step 8. Get infer result data --------
    198. start = DateTime.Now;
    199. Tensor output_tensor = infer_request.get_output_tensor();
    200. int output_length = (int)output_tensor.get_size();
    201. float[] output_data = output_tensor.get_data<float>(output_length);
    202. end = DateTime.Now;
    203. Slog.INFO("8. Get infer result data success, time spend:" + (end - start).TotalMilliseconds + "ms.");
    204. -------- Step 9. Process reault --------
    205. start = DateTime.Now;
    206. List position_boxes = new List();
    207. List<int> class_ids = new List<int>();
    208. List<float> confidences = new List<float>();
    209. // Preprocessing output results
    210. for (int i = 0; i < output_data.Length / 6; i++)
    211. {
    212. int s = 6 * i;
    213. if ((float)output_data[s + 4] > 0.2)
    214. {
    215. float cx = output_data[s + 0];
    216. float cy = output_data[s + 1];
    217. float dx = output_data[s + 2];
    218. float dy = output_data[s + 3];
    219. int x = (int)((cx) * factor);
    220. int y = (int)((cy) * factor);
    221. int width = (int)((dx - cx) * factor);
    222. int height = (int)((dy - cy) * factor);
    223. Rect box = new Rect();
    224. box.X = x;
    225. box.Y = y;
    226. box.Width = width;
    227. box.Height = height;
    228. position_boxes.Add(box);
    229. class_ids.Add((int)output_data[s + 5]);
    230. confidences.Add((float)output_data[s + 4]);
    231. }
    232. }
    233. end = DateTime.Now;
    234. Slog.INFO("9. Process reault success, time spend:" + (end - start).TotalMilliseconds + "ms.");
    235. for (int i = 0; i < class_ids.Count; i++)
    236. {
    237. int index = i;
    238. Cv2.Rectangle(image, position_boxes[index], new Scalar(0, 0, 255), 2, LineTypes.Link8);
    239. Cv2.Rectangle(image, new OpenCvSharp.Point(position_boxes[index].TopLeft.X, position_boxes[index].TopLeft.Y + 30),
    240. new OpenCvSharp.Point(position_boxes[index].BottomRight.X, position_boxes[index].TopLeft.Y), new Scalar(0, 255, 255), -1);
    241. Cv2.PutText(image, class_ids[index] + "-" + confidences[index].ToString("0.00"),
    242. new OpenCvSharp.Point(position_boxes[index].X, position_boxes[index].Y + 25),
    243. HersheyFonts.HersheySimplex, 0.8, new Scalar(0, 0, 0), 2);
    244. }
    245. string output_path = Path.Combine(Path.GetDirectoryName(Path.GetFullPath(image_path)),
    246. Path.GetFileNameWithoutExtension(image_path) + "_result.jpg");
    247. Cv2.ImWrite(output_path, image);
    248. Slog.INFO("The result save to " + output_path);
    249. Cv2.ImShow("Result", image);
    250. Cv2.WaitKey(0);
    251. }
    252. }
    253. }

    五、输出结果

            运行代码,可以得到统计的代码加载、预处理、推理的运行时间,并且得到识别结果,类别号、置信度、以及位置

           有显卡的话,可将模型AUTO改为GPU,运行时间会更快些。。。

  • 相关阅读:
    面向高速公路车辆切入场景的自动驾驶测试用例生成方法
    Java锁常见面试题
    OpenCV 4.0.0学习笔记 (一) 图像与视频的读写
    C语言题收录(四)
    RabbitMQ 消息队列学习 (四)
    《MongoDB入门教程》第15篇 文档更新之$inc操作符
    【MicroPython ESP32】ssd1306 0.96“OLED+气象数据中文显示
    01【什么是设计模式】
    springMVC01,【第一个springMVC例子(注解版):HelloWorld】
    围剿小程序
  • 原文地址:https://blog.csdn.net/AP1005834/article/details/139779710