opencvsharp dnn调用yolov5模型

opencvsharp dnn调用yolov5模型,需要一个demo 求指点一下。

结合ChatGPT:
以下是使用 OpenCVSharp DNN 模块调用 YOLOv5 模型的基本步骤:

加载模型:
使用 ReadNetFromONNX 或 ReadNetFromTorch 函数加载预训练的 YOLOv5 模型。请注意,YOLOv5 默认是使用 PyTorch 训练的,因此您可能需要将其转换为 ONNX 格式。

string modelPath = "path/to/yolov5.onnx";
var net = CvDnn.ReadNetFromONNX(modelPath);


加载图像并预处理:
将图像加载到内存中,然后调整其大小以适应 YOLOv5 模型的输入尺寸。通常,YOLOv5 模型需要的输入尺寸是 640x640。

string imagePath = "path/to/image.jpg";
var img = new Mat(imagePath, ImreadModes.Color);
var inputBlob = CvDnn.BlobFromImage(img, 1.0 / 255.0, new Size(640, 640), new Scalar(), true, false);


设置模型的输入并运行前向传播:
将预处理后的图像设置为模型的输入,然后运行前向传播以获取模型的输出。


net.SetInput(inputBlob);
var output = net.Forward();

处理模型的输出:
模型输出包含检测到的目标的边界框、置信度和类别信息。您需要解析这些数据并将其转换为易于理解的格式。

float[] data = new float[output.Total()];
Marshal.Copy(output.DataPointer, data, 0, data.Length);

List<DetectionResult> results = new List<DetectionResult>();

for (int i = 0; i < data.Length / 85; i++)
{
    float confidence = data[i * 85 + 4];
    if (confidence > 0.5)
    {
        int classId = data.Skip(i * 85 + 5).Take(80).ToList().IndexOf(data.Max()) + 5;
        float x = data[i * 85] * img.Width;
        float y = data[i * 85 + 1] * img.Height;
        float width = data[i * 85 + 2] * img.Width;
        float height = data[i * 85 + 3] * img.Height;

        results.Add(new DetectionResult(classId, new Rect2d(x, y, width, height), confidence));
    }
}


显示检测结果:
将检测到的目标绘制在原始图像上,并显示图像。

foreach (var result in results)
{
    img.Rectangle(result.BoundingBox, new Scalar(0, 0, 255), 2);
    img.PutText($"Class: {result.ClassId}, Confidence: {result.Confidence}", new Point(result.BoundingBox.X, result.BoundingBox.Y -


绘制边界框和显示检测结果

foreach (var result in results)
{
    img.Rectangle(result.BoundingBox, new Scalar(0, 0, 255), 2);
    img.PutText($"Class: {result.ClassId}, Confidence: {result.Confidence}", new Point(result.BoundingBox.X, result.BoundingBox.Y - 10), HersheyFonts.HersheySimplex, 0.5, new Scalar(0, 0, 255), 1);
}

using (var window = new Window("YOLOv5 Detections"))
{
    window.ShowImage(img);
    Cv2.WaitKey();
}


在此代码示例中,我们首先遍历检测结果,为每个检测到的目标绘制边界框,并在边界框上方添加类别和置信度信息。然后,我们创建一个名为 "YOLOv5 Detections" 的窗口以显示包含检测结果的图像,并等待用户按键以关闭窗口。

这个示例应该可以帮助您开始使用 OpenCVSharp DNN 模块和 YOLOv5 模型。请注意,为了使这个示例工作,您可能需要根据实际情况调整文件路径、输入尺寸等参数。另外,这个示例仅用于演示目的,您可能需要根据您的需求对其进行优化和扩展。

结合ChatGPT:
以下是使用 OpenCVSharp DNN 模块调用 YOLOv5 模型的基本步骤:

加载模型:
使用 ReadNetFromONNX 或 ReadNetFromTorch 函数加载预训练的 YOLOv5 模型。请注意,YOLOv5 默认是使用 PyTorch 训练的,因此您可能需要将其转换为 ONNX 格式。

string modelPath = "path/to/yolov5.onnx";
var net = CvDnn.ReadNetFromONNX(modelPath);


加载图像并预处理:
将图像加载到内存中,然后调整其大小以适应 YOLOv5 模型的输入尺寸。通常,YOLOv5 模型需要的输入尺寸是 640x640。

string imagePath = "path/to/image.jpg";
var img = new Mat(imagePath, ImreadModes.Color);
var inputBlob = CvDnn.BlobFromImage(img, 1.0 / 255.0, new Size(640, 640), new Scalar(), true, false);


设置模型的输入并运行前向传播:
将预处理后的图像设置为模型的输入,然后运行前向传播以获取模型的输出。


net.SetInput(inputBlob);
var output = net.Forward();

处理模型的输出:
模型输出包含检测到的目标的边界框、置信度和类别信息。您需要解析这些数据并将其转换为易于理解的格式。

float[] data = new float[output.Total()];
Marshal.Copy(output.DataPointer, data, 0, data.Length);

List<DetectionResult> results = new List<DetectionResult>();

for (int i = 0; i < data.Length / 85; i++)
{
    float confidence = data[i * 85 + 4];
    if (confidence > 0.5)
    {
        int classId = data.Skip(i * 85 + 5).Take(80).ToList().IndexOf(data.Max()) + 5;
        float x = data[i * 85] * img.Width;
        float y = data[i * 85 + 1] * img.Height;
        float width = data[i * 85 + 2] * img.Width;
        float height = data[i * 85 + 3] * img.Height;

        results.Add(new DetectionResult(classId, new Rect2d(x, y, width, height), confidence));
    }
}


显示检测结果:
将检测到的目标绘制在原始图像上,并显示图像。

foreach (var result in results)
{
    img.Rectangle(result.BoundingBox, new Scalar(0, 0, 255), 2);
    img.PutText($"Class: {result.ClassId}, Confidence: {result.Confidence}", new Point(result.BoundingBox.X, result.BoundingBox.Y -


绘制边界框和显示检测结果

foreach (var result in results)
{
    img.Rectangle(result.BoundingBox, new Scalar(0, 0, 255), 2);
    img.PutText($"Class: {result.ClassId}, Confidence: {result.Confidence}", new Point(result.BoundingBox.X, result.BoundingBox.Y - 10), HersheyFonts.HersheySimplex, 0.5, new Scalar(0, 0, 255), 1);
}

using (var window = new Window("YOLOv5 Detections"))
{
    window.ShowImage(img);
    Cv2.WaitKey();
}


在此代码示例中,我们首先遍历检测结果,为每个检测到的目标绘制边界框,并在边界框上方添加类别和置信度信息。然后,我们创建一个名为 "YOLOv5 Detections" 的窗口以显示包含检测结果的图像,并等待用户按键以关闭窗口。

这个示例应该可以帮助您开始使用 OpenCVSharp DNN 模块和 YOLOv5 模型。请注意,为了使这个示例工作,您可能需要根据实际情况调整文件路径、输入尺寸等参数。另外,这个示例仅用于演示目的,您可能需要根据您的需求对其进行优化和扩展。

  • 这篇博客: yolov5_dnn python/c++用opencv的dnn模块做yolov5目标检测中的 yolov5_letterbox解释:以最长边放缩图片,然后最短边补灰边 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • def letterbox(self, im, new_shape=(640, 640), color=(114, 114, 114), auto=True, scaleFill=False, scaleup=True, stride=32):
         # Resize and pad image while meeting stride-multiple constraints
            shape = im.shape[:2]  # current shape [height, width]
            if isinstance(new_shape, int):
                new_shape = (new_shape, new_shape)
    
            # Scale ratio (new / old)
            r = min(new_shape[0] / shape[0], new_shape[1] / shape[1])
            if not scaleup:  # only scale down, do not scale up (for better val mAP)
                r = min(r, 1.0)
    
            # Compute padding
            ratio = r, r  # width, height ratios
            new_unpad = int(round(shape[1] * r)), int(round(shape[0] * r))
            dw, dh = new_shape[1] - new_unpad[0], new_shape[0] - new_unpad[1]  # wh padding
            if auto:  # minimum rectangle
                dw, dh = np.mod(dw, stride), np.mod(dh, stride)  # wh padding
            elif scaleFill:  # stretch
                dw, dh = 0.0, 0.0
                new_unpad = (new_shape[1], new_shape[0])
                ratio = new_shape[1] / shape[1], new_shape[0] / shape[0]  # width, height ratios
    
            dw /= 2  # divide padding into 2 sides
            dh /= 2
    
            if shape[::-1] != new_unpad:  # resize
                im = cv2.resize(im, new_unpad, interpolation=cv2.INTER_LINEAR)
            top, bottom = int(round(dh - 0.1)), int(round(dh + 0.1))
            left, right = int(round(dw - 0.1)), int(round(dw + 0.1))
            im = cv2.copyMakeBorder(im, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color)  # add border
            return im, ratio, (dw, dh)
    
  • 以下回答由chatgpt基于相关博客总结生成:

    由于OpenCVSharp DNN是基于OpenCV的深度神经网络模块,可以使用OpenCVSharp DNN来调用YOLOv5模型。下面是一个使用OpenCVSharp DNN调用YOLOv5模型的示例:

    1. 准备YOLOv5模型和权重文件。可以在YOLOv5官方GitHub上找到相关的模型和权重文件。

    2. 导入所需的库。

    using System;
    using System.Collections.Generic;
    using OpenCvSharp;
    using OpenCvSharp.Dnn;
    
    1. 加载YOLOv5模型和权重文件。
    string model = "path/to/yolov5s.onnx";
    string config = "path/to/yolov5s.cfg";
    string weights = "path/to/yolov5s.weights";
    
    var net = CvDnn.ReadNetFromDarknet(config, weights);
    net.SetPreferableBackend(Backend.OPENCV);
    net.SetPreferableTarget(Target.CPU);
    
    1. 定义输入图像和输出图像。
    string imagePath = "path/to/image.jpg";
    string savePath = "path/to/result.jpg";
    int frameWidth = 416;
    int frameHeight = 416;
    
    var frame = Cv2.ImRead(imagePath, ImreadModes.Color);
    var blob = CvDnn.BlobFromImage(frame, scalefactor: 1.0 / 255, size: new Size(frameWidth, frameHeight), mean: Scalar.All(0), swapRB: true, crop: false);
    var inputBlobName = net.GetLayerNames()[0];
    net.SetInput(blob, inputBlobName);
    
    string[] outputLayerNames = {
        "yolo_82",
        "yolo_94",
        "yolo_106"
    };
    
    var detections = new List<float[]>();
    foreach (var name in outputLayerNames)
    {
        detections.Add(net.GetLayerOutput(net.GetLayerId(name)));
    }
    
    1. 解析检测结果。
    const float confThreshold = 0.5f;
    const float nmsThreshold = 0.4f;
    
    var boxes = new List<float[]>();
    var confidences = new List<float>();
    var classIds = new List<int>();
    
    foreach (var output in detections)
    {
        for (int i = 0; i < output.Length; i += 6)
        {
            var confidence = output[i + 4];
            if (confidence > confThreshold)
            {
                var x = output[i] * frame.Width;
                var y = output[i + 1] * frame.Height;
                var w = output[i + 2] * frame.Width;
                var h = output[i + 3] * frame.Height;
    
                var box = new[] { x - w / 2, y - h / 2, w, h };
                boxes.Add(box);
                confidences.Add(confidence);
                classIds.Add((int)(output[i + 5]) + 1);
            }
        }
    }
    
    var indices = Cv2.NMSBoxes(boxes, confidences.ToArray(), confThreshold, nmsThreshold);
    
    1. 在图像上绘制结果。
    foreach (var idx in indices)
    {
        var box = boxes[idx];
        var classId = classIds[idx];
        var confidence = confidences[idx];
    
        var label = $"Class: {classId} | Confidence: {(confidence * 100).ToString("0.00")}%";
    
        var textColor = Scalar.White;
        var bboxColor = Scalar.Yellow;
    
        Cv2.Rectangle(frame, new Rect((int)box[0], (int)box[1], (int)box[2], (int)box[3]), bboxColor, 2);
        Cv2.PutText(frame, label, new Point((int)box[0], (int)box[1] - 10), HersheyFonts.HersheySimplex, 0.5, textColor, 1, LineTypes.AntiAlias, false);
    }
    
    Cv2.ImWrite(savePath, frame);
    

    上述示例代码中的yolov5s模型和相关文件需要自行准备。

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
可以用OpenCvSharp中的DNN模块来调用YOLOv5模型。

下面给出一个简单的示例:

using OpenCvSharp;
using OpenCvSharp.Dnn;

class Program
{
    static void Main(string[] args)
    {
        // 加载YOLOv5的网络结构和权重
        var model = CvDnn.ReadNetFromDarknet("<path_to_yolov5_cfg_file>", "<path_to_yolov5_weights_file>");

        // 获取输入图像的大小
        var size = new Size(640, 640); // 这里以640x640的大小为例

        // 读取输入图像
        var image = new Mat("<path_to_input_image>", ImreadModes.Color);

        // 对输入图像进行预处理,将像素值缩放到0~1之间,并进行归一化
        var blob = CvDnn.BlobFromImage(image, 1.0 / 255.0, size, new Scalar(0), true, false);

        // 将输入blob设置为网络的输入
        model.SetInput(blob);

        // 进行前向推理,得到检测结果
        var result = model.Forward();

        // 解析检测结果
        ParseResult(result);

        // 显示图像和检测结果
        Cv2.ImShow("Result", image);
        Cv2.WaitKey();
    }

    static void ParseResult(Mat result)
    {
        // 获取检测到的物体个数
        var rows = (int)result.Total();
        var cols = (int)result.Cols;

        // 将检测结果转换成2维数组
        var data = result.Reshape(1, rows);

        for (var i = 0; i < rows; i++)
        {
            var confidence = data.At<float>(i, 4);
            var class_id = (int)data.At<float>(i, 5);

            // 判断检测结果是否可信
            if (confidence > 0.5)
            {
                // 获取物体的位置信息
                var x = data.At<float>(i, 0) * image.Cols;
                var y = data.At<float>(i, 1) * image.Rows;
                var width = data.At<float>(i, 2) * image.Cols;
                var height = data.At<float>(i, 3) * image.Rows;

                // 绘制物体框和类别标签
                Cv2.Rectangle(image, new Rect((int)x, (int)y, (int)width, (int)height), new Scalar(0, 255,0), 2);
                Cv2.PutText(image, $"class:{class_id}, conf:{confidence:0.00}", new Point((int)x, (int)y - 10), HersheyFonts.HersheyPlain, 1, new Scalar(0, 0, 255), 2);
            }
        }
    }
}

需要注意的是,这里只是一个简单的示例,对于实际应用来说还需要对代码进行一些调整和优化。
如果我的回答解决了您的问题,请采纳!

引用chatGPT作答,以下是使用OpenCvSharp和YoloV5进行目标检测的基本示例代码:

using System;
using System.Drawing;
using OpenCvSharp;
using OpenCvSharp.Dnn;

class Program
{
    static void Main(string[] args)
    {
        // 加载模型和标签
        var model = CvDnn.ReadNetFromDarknet(@"path/to/yolov5s.cfg", @"path/to/yolov5s.weights");
        var labels = System.IO.File.ReadAllLines(@"path/to/coco.names");

        // 创建图像
        var image = new Mat(@"path/to/image.jpg");

        // 执行推断
        var blob = CvDnn.BlobFromImage(image, 1.0 / 255.0, new Size(640, 640), new Scalar(0, 0, 0), true, false);
        model.SetInput(blob);
        var output = model.Forward();

        // 解析输出
        var detections = ParseOutput(output, image.Width, image.Height);
        foreach (var detection in detections)
        {
            var label = labels[detection.ClassId];
            var confidence = detection.Confidence;
            var rect = detection.Rect;

            Cv2.Rectangle(image, rect, new Scalar(0, 255, 0), 2);
            Cv2.PutText(image, $"{label} {confidence:F2}", new Point(rect.X, rect.Y - 5), HersheyFonts.HersheyComplexSmall, 0.5, new Scalar(0, 255, 0));
        }

        // 显示结果
        Cv2.ImShow("Result", image);
        Cv2.WaitKey(0);
    }

    static DetectionResult[] ParseOutput(Mat output, int width, int height)
    {
        var results = new DetectionResult[output.Rows];
        var data = output.Data<float>();

        for (int i = 0; i < output.Rows; i++)
        {
            var detection = new DetectionResult();
            detection.ClassId = (int)data[i * output.Cols + 5];

            var x = data[i * output.Cols];
            var y = data[i * output.Cols + 1];
            var w = data[i * output.Cols + 2];
            var h = data[i * output.Cols + 3];

            detection.Rect = new Rect(
                (int)((x - w / 2.0) * width),
                (int)((y - h / 2.0) * height),
                (int)(w * width),
                (int)(h * height));

            detection.Confidence = data[i * output.Cols + 4];

            results[i] = detection;
        }

        return results;
    }

    struct DetectionResult
    {
        public int ClassId;
        public float Confidence;
        public Rect Rect;
    }
}

请注意,这是一个基本示例,可能需要根据您的要求进行修改和优化。要使用此示例,您需要将其保存到.cs文件中,然后使用您的编辑器进行编译和运行。另外,您需要将YOLOv5的配置文件、权重文件和标签文件替换为您自己的文件路径。