基于OpenVinoSharp和PP-Vehicle的车辆检测
参考了C# Onnx PP-Vehicle 车辆分析(包含:车辆检测,识别车型和车辆颜色),但是使用Onnx加载PP-Vehicle模型失败,所以使用OpenVinoSharp以加载飞浆原生模型。
效果
项目
OpenCvSharp 4.11.0.20250507
OpenVINO.CSharp.Windows 2024.0.0.1
代码
private const int INPUT_WIDTH = 640;private const int INPUT_HEIGHT = 640;private const int INPUT_CHANNELS = 3;private Mat image;private void Detect(){float[] inputData = PreprocessImage();var core = new OpenVinoSharp.Core();var model = core.read_model(@"./mot_ppyoloe_l_36e_ppvehicle/model.pdmodel"); // 读取模型文件var compiled_model = core.compile_model(model, "CPU");var inferRequest = compiled_model.create_infer_request();Console.WriteLine("模型加载成功");float[] factor = new float[] { 640.0f / image.Rows, 640.0f / image.Cols };var ipunt = compiled_model.inputs()[1];var inputTensor = inferRequest.get_tensor("image");inputTensor.set_shape(new Shape(1, 3, 640, 640));inputTensor.set_data(inputData);Tensor input_tensor_factor = inferRequest.get_tensor("scale_factor");input_tensor_factor.set_shape(new Shape(1, 2));input_tensor_factor.set_data<float>(factor);// 执行推理inferRequest.infer();// 获取输出 Tensor output_tensor = inferRequest.get_output_tensor(0);var output_tensor_2 = inferRequest.get_output_tensor(1);int output_length = (int)output_tensor.get_size();float[] outputData = output_tensor.get_data<float>(output_length);pictureBox1.Image = new System.Drawing.Bitmap(image.ToMemoryStream());for (int i = 0; i < output_length / 6; i++){int offset = i * 6;int classId = (int)outputData[offset];float confidence = outputData[offset + 1];if (confidence > 0.5f) // 置信度阈值{Console.WriteLine(classId);int xMin = (int)outputData[offset + 2];int yMin = (int)outputData[offset + 3];int xMax = (int)outputData[offset + 4];int yMax = (int)outputData[offset + 5];image.Rectangle(new Rect(xMin, yMin, xMax - xMin, yMax - yMin), Scalar.Red, 3);}}pictureBox2.Image = new System.Drawing.Bitmap(image.ToMemoryStream());}private float[] PreprocessImage(){// 调整大小image = new Mat(@"1.bmp");var resizedImage = image.Resize(new OpenCvSharp.Size(640, 640));//image.SaveImage("640.bmp");// 转换为float数组并归一化float[] inputData = new float[INPUT_WIDTH * INPUT_HEIGHT * INPUT_CHANNELS];for (int y = 0; y < INPUT_HEIGHT; y++){for (int x = 0; x < INPUT_WIDTH; x++){int index = y * INPUT_HEIGHT + x;Vec3b pixel = resizedImage.Get<Vec3b>(y, x);inputData[index] = pixel.Item0;inputData[index+ 640 * 640] = pixel.Item1;inputData[index + 640 * 640 + 640 * 640] = pixel.Item2;}}return inputData;}