c# 通过emgucv4.5.5调用gpu推理yolov7和yolov7-tiny,darknet版本。注意不是pytorch。
GitHub - WongKinYiu/yolov7 at darknet
RTX2060显卡推理yolov7总耗时26ms,yolov7-tiny总耗时6ms。
全部demo代码下载,由于带了cuda,cudnn,文件很多。
https://download.csdn.net/download/vokxchh/86561885https://download.csdn.net/download/vokxchh/86561885部分推理代码如下
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Emgu.CV.Dnn;
using Emgu.CV;
using Emgu.CV.Util;
using System.Drawing;
using Emgu.CV.Structure;
using DarknetYolo.Models;
using System.IO;
namespace WindowsFormsApp11
{
public class DarknetYOLO
{
///
/// Model to load
///
public Net Network { get; set; }
///
/// Prediction confidence threshold
///
public float ConfidenceThreshold { get; set; }
///
/// Non-Max Suppression Threshold
///
public float NMSThreshold { get; set; }
private string[] _labels;
///
/// Initialize Darknet network.
///
/// Path to the labels file.
/// Path to the weights file.
/// Path to the config file.
/// Preferred computation implementation.
/// Preferred computation target.
public DarknetYOLO(string labelsPath, string weightsPath, string configPath, PreferredBackend backend = PreferredBackend.OpenCV, PreferredTarget target = PreferredTarget.Cuda)
{
Enum.TryParse(backend.ToString(), out Emgu.CV.Dnn.Backend b);
Enum.TryParse(target.ToString(), out Emgu.CV.Dnn.Target t);
Network = DnnInvoke.ReadNetFromDarknet(configPath, weightsPath);
Network.SetPreferableBackend(b);
Network.SetPreferableTarget(t);
_labels = File.ReadAllLines(labelsPath);
}
///
/// Detect objects from image.
///
/// The network's input image.
/// (Optional) Resize image width before feeding it to the network (smaller results in faster predictions but may hurt accuracy).
/// (Optional) Resize image height before feeding it to the network (smaller results in faster predictions but may hurt accuracy)
/// List of all detected objects.
public List Predict(Image inputImage, int resizedWidth = 416, int resizedHeight =416)
{
if (resizedWidth % 32 is int rest)
{
if (resizedWidth < 32)
resizedWidth = 32;
if (rest < 16)
resizedWidth = (int)(32 * Math.Floor(resizedWidth / 32f));
else
resizedWidth = (int)(32 * Math.Ceiling(resizedWidth / 32f));
}
if (resizedHeight % 32 is int rest2)
{
if (resizedHeight < 32)
resizedHeight = 32;
if (rest2 < 16)
resizedHeight = (int)(32 * Math.Floor(resizedHeight / 32f));
else
resizedHeight = (int)(32 * Math.Ceiling(resizedHeight / 32f));
}
// Mat t = new Mat();
int width = inputImage.Width;
int height = inputImage.Height;
VectorOfMat layerOutputs = new VectorOfMat();
string[] outNames = Network.UnconnectedOutLayersNames;
var blob = DnnInvoke.BlobFromImage(inputImage, 1 / 255f, new System.Drawing.Size(resizedWidth, resizedHeight), swapRB: true, crop: false);
Network.SetInput(blob);
Network.Forward(layerOutputs, outNames);
List boxes = new List();
List confidences = new List();
List classIDs = new List();
for (int k = 0; k < layerOutputs.Size; k++)
{
float[,] lo = (float[,])layerOutputs[k].GetData();
int len = lo.GetLength(0);
for (int i = 0; i < len; i++)
{
if (lo[i, 4] < ConfidenceThreshold)
continue;
float max = 0;
int idx = 0;
int len2 = lo.GetLength(1);
for (int j = 5; j < len2; j++)
if (lo[i, j] > max)
{
max = lo[i, j];
idx = j - 5;
}
if (max > ConfidenceThreshold)
{
lo[i, 0] *= width;
lo[i, 1] *= height;
lo[i, 2] *= width;
lo[i, 3] *= height;
int x = (int)(lo[i, 0] - (lo[i, 2] / 2));
int y = (int)(lo[i, 1] - (lo[i, 3] / 2));
var rect = new Rectangle(x, y, (int)lo[i, 2], (int)lo[i, 3]);
rect.X = rect.X < 0 ? 0 : rect.X;
rect.X = rect.X > width ? width - 1 : rect.X;
rect.Y = rect.Y < 0 ? 0 : rect.Y;
rect.Y = rect.Y > height ? height - 1 : rect.Y;
rect.Width = rect.X + rect.Width > width ? width - rect.X - 1 : rect.Width;
rect.Height = rect.Y + rect.Height > height ? height - rect.Y - 1 : rect.Height;
boxes.Add(rect);
confidences.Add(max);
classIDs.Add(idx);
}
}
}
int[] bIndexes = DnnInvoke.NMSBoxes(boxes.ToArray(), confidences.ToArray(), ConfidenceThreshold, NMSThreshold);
List filteredBoxes = new List();
if (bIndexes.Length > 0)
{
foreach (var idx in bIndexes)
{
filteredBoxes.Add(new YoloPrediction()
{
Rectangle = boxes[idx],
Confidence = Math.Round(confidences[idx], 4),
Label = _labels[classIDs[idx]]
});
}
}
return filteredBoxes;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DarknetYolo.Models
{
public enum PreferredBackend
{
///
/// Default equals to InferenceEngine if OpenCV is built with Intel's Inference Engine library or Opencv otherwise.
///
Default = 0,
///
/// Halide backend
///
Halide = 1,
///
/// Intel's Inference Engine library
/// Intel's Inference Engine library
InferenceEngine = 2,
///
/// OpenCV's implementation
///
OpenCV = 3,
///
/// Vulkan based backend
///
VkCom = 4,
///
/// Cuda backend
///
Cuda = 5,
///
/// Inference Engine NGraph
///
InferenceEngineNgraph = 1000000,
///
/// Inference Engine NN Builder 2019
///
InferenceEngineNnBuilder2019 = 1000001
}
}
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using System.Windows.Forms;
using DarknetYolo.Models;
//using DarknetYOLO.Bitmap0;
using Emgu.CV;
using Emgu.CV.Structure;
using static System.Windows.Forms.DataFormats;
namespace WindowsFormsApp11
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
DarknetYOLO model;
ConcurrentQueue listqueue = new ConcurrentQueue();//
System.Timers.Timer ti2 = new System.Timers.Timer(10);//
Stopwatch _stopWath = new Stopwatch();
int cout = 0;
class Pic
{
private string name;
private Image data;
public string Name
{
get { return name; }
set { name = value; }
}
public Image Data
{
get { return data; }
set { data = value; }
}
}
private void button1_Click(object sender, EventArgs e)
{
cout = 0;
icout = 0;
DirectoryInfo dir = new DirectoryInfo(Environment.CurrentDirectory + "\\picture\\");
FileInfo[] fileInfo = dir.GetFiles("*.jpg");
cout = fileInfo.Count();
_stopWath = new Stopwatch();
ti2.Enabled = true;
richTextBox1.Clear();
sb.Clear();
_stopWath.Start();
//Parallel.ForEach(fileInfo, i =>
foreach (var i in fileInfo)
{
string imagePath = Environment.CurrentDirectory + "\\picture\\" + i.Name;
//Image frame = new Image(imagePath);//low
var frame = new Bitmap(imagePath).ToImage();//5ms
listqueue.Enqueue(new Pic { Name = i.Name, Data = frame} );
}
//);
}
private void Form1_Load(object sender, EventArgs e)
{
Form2 fm = new Form2();
fm.Show();
ti2.Elapsed += new System.Timers.ElapsedEventHandler(this.ti2_Elapsed);//到达时间的时候执行事件;
string labels = @"vocTR.names";
// string weights = @"yolov7_last.weights";
// string cfg = @"yolov7.cfg";
string weights = @"yolov7-tiny_last.weights";
string cfg = @"yolov7-tiny.cfg";
model = new DarknetYOLO(labels, weights, cfg, PreferredBackend.Cuda, PreferredTarget.Cuda);
model.NMSThreshold = 0.4f;
model.ConfidenceThreshold = 0.5f;
var frame = new Bitmap("demo.jpg").ToImage();
List results = model.Predict(frame, 416, 416);//预热
fm.Close();
}
StringBuilder sb = new StringBuilder();
int icout = 0;
private void ti2_Elapsed(object sender, ElapsedEventArgs e)//1#
{
ti2.Enabled = false;
while (icout results = model.Predict(result0.Data, 416, 416);//
foreach (var item in results)
{
sb.AppendLine(result0.Name+" " + item.Label + " " + item.Confidence);
}
icout++;
}
if (icout == cout)
{
_stopWath.Stop();
string aa = _stopWath.ElapsedMilliseconds.ToString();
richTextBox1.BeginInvoke(new MethodInvoker(delegate ()
{
richTextBox1.AppendText(sb.ToString() + "\r\n" + "Total: " + aa + " ms " + " Count:" + icout+" each time:"+(( _stopWath.ElapsedMilliseconds / (float)icout)).ToString("0.00")+"ms");
}));
ti2.Enabled = false;
return;
}
}
}
ti2.Enabled = true;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DarknetYolo.Models
{
public enum PreferredTarget
{
///
/// CPU
///
Cpu = 0,
///
/// OpenCL
///
OpenCL = 1,
///
/// Will fall back to OPENCL if the hardware does not support FP16
///
OpenCLFp16 = 2,
///
/// Myriad
///
Myriad = 3,
///
/// Vulkan
///
Vulkan = 4,
///
/// FPGA device with CPU fallbacks using Inference Engine's Heterogeneous plugin.
///
FPGA = 5,
///
/// Cuda
///
Cuda = 6,
///
/// Cuda Fp16
///
CudaFp16 = 7
}
}
C#运用emgucv调用gpu,推理yolov7和yolov7-tiny。darknet版本80分类原始weights和cfg-数据集文档类资源-CSDN文库https://download.csdn.net/download/vokxchh/86590551原始80分类demo 代码下载
更新emgucv4.6.0
c#emgucv4.6.0版本gpu推理yolov7-tiny,darknet版本-C#文档类资源-CSDN文库https://download.csdn.net/download/vokxchh/86854081