C# OpenCvSharp DNN Yolov8-OBB 旋转目标检测

2024-02-27 07:44

本文主要是介绍C# OpenCvSharp DNN Yolov8-OBB 旋转目标检测,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

效果

模型信息

项目

代码

下载


C# OpenCvSharp DNN Yolov8-OBB 旋转目标检测

效果

模型信息

Model Properties
-------------------------
date:2024-02-26T08:38:44.171849
description:Ultralytics YOLOv8s-obb model trained on runs/DOTAv1.0-ms.yaml
author:Ultralytics
task:obb
license:AGPL-3.0 https://ultralytics.com/license
version:8.1.18
stride:32
batch:1
imgsz:[640, 640]
names:{0: 'plane', 1: 'ship', 2: 'storage tank', 3: 'baseball diamond', 4: 'tennis court', 5: 'basketball court', 6: 'ground track field', 7: 'harbor', 8: 'bridge', 9: 'large vehicle', 10: 'small vehicle', 11: 'helicopter', 12: 'roundabout', 13: 'soccer ball field', 14: 'swimming pool'}
---------------------------------------------------------------

Inputs
-------------------------
name:images
tensor:Float[1, 3, 640, 640]
---------------------------------------------------------------

Outputs
-------------------------
name:output0
tensor:Float[1, 20, 8400]
---------------------------------------------------------------

项目

代码

using OpenCvSharp;
using OpenCvSharp.Dnn;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Windows.Forms;

namespace OpenCvSharp_DNN_Demo
{
    public partial class frmMain : Form
    {
        public frmMain()
        {
            InitializeComponent();
        }

        string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";
        string image_path = "";

        DateTime dt1 = DateTime.Now;
        DateTime dt2 = DateTime.Now;

        string modelpath;
        string classer_path;

        List<string> class_names;

        Net opencv_net;
        Mat BN_image;

        Mat image;
        Mat result_image;

        string[] class_lables;

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = fileFilter;
            if (ofd.ShowDialog() != DialogResult.OK) return;

            pictureBox1.Image = null;
            pictureBox2.Image = null;
            textBox1.Text = "";

            image_path = ofd.FileName;
            pictureBox1.Image = new Bitmap(image_path);
            image = new Mat(image_path);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            modelpath = "model/yolov8s-obb.onnx";
            classer_path = "model/lable.txt";

            opencv_net = CvDnn.ReadNetFromOnnx(modelpath);

            List<string> str = new List<string>();
            StreamReader sr = new StreamReader(classer_path);
            string line;
            while ((line = sr.ReadLine()) != null)
            {
                str.Add(line);
            }
            class_lables = str.ToArray();

            image_path = "test_img/1.png";
            pictureBox1.Image = new Bitmap(image_path);

        }

        private  void button2_Click(object sender, EventArgs e)
        {
            if (image_path == "")
            {
                return;
            }
            textBox1.Text = "检测中,请稍等……";
            pictureBox2.Image = null;
            button2.Enabled = false;
            Application.DoEvents();

            image = new Mat(image_path);

            //图片缩放
            image = new Mat(image_path);
            int max_image_length = image.Cols > image.Rows ? image.Cols : image.Rows;
            Mat max_image = Mat.Zeros(new OpenCvSharp.Size(max_image_length, max_image_length), MatType.CV_8UC3);
            Rect roi = new Rect(0, 0, image.Cols, image.Rows);
            image.CopyTo(new Mat(max_image, roi));

            float[] result_array;
            float factor = (float)(max_image_length / 640.0);

            // 将图片转为RGB通道
            Mat image_rgb = new Mat();
            Cv2.CvtColor(max_image, image_rgb, ColorConversionCodes.BGR2RGB);
            Mat resize_image = new Mat();
            Cv2.Resize(image_rgb, resize_image, new OpenCvSharp.Size(640, 640));

            BN_image = CvDnn.BlobFromImage(resize_image, 1 / 255.0, new OpenCvSharp.Size(640, 640), new Scalar(0, 0, 0), true, false);

            //配置图片输入数据
            opencv_net.SetInput(BN_image);

            //模型推理,读取推理结果
            Mat[] outs = new Mat[1] { new Mat() };
            string[] outBlobNames = opencv_net.GetUnconnectedOutLayersNames().ToArray();

            dt1 = DateTime.Now;

            opencv_net.Forward(outs, outBlobNames);

            dt2 = DateTime.Now;

            int num_proposal = outs[0].Size(1);
            int nout = outs[0].Size(2);

            if (outs[0].Dims > 2)
            {
                outs[0] = outs[0].Reshape(0, num_proposal);
            }

            Mat result_data = new Mat(20, 8400, MatType.CV_32F);
            result_data = outs[0].T();
            List<Rect2d> position_boxes = new List<Rect2d>();
            List<int> class_ids = new List<int>();
            List<float> confidences = new List<float>();
            List<float> rotations = new List<float>();
            // Preprocessing output results
            for (int i = 0; i < result_data.Rows; i++)
            {
                Mat classes_scores = new Mat(result_data, new Rect(4, i, 15, 1));
                OpenCvSharp.Point max_classId_point, min_classId_point;
                double max_score, min_score;
                // Obtain the maximum value and its position in a set of data
                Cv2.MinMaxLoc(classes_scores, out min_score, out max_score,
                    out min_classId_point, out max_classId_point);
                // Confidence level between 0 ~ 1
                // Obtain identification box information
                if (max_score > 0.25)
                {
                    float cx = result_data.At<float>(i, 0);
                    float cy = result_data.At<float>(i, 1);
                    float ow = result_data.At<float>(i, 2);
                    float oh = result_data.At<float>(i, 3);
                    double x = (cx - 0.5 * ow) * factor;
                    double y = (cy - 0.5 * oh) * factor;
                    double width = ow * factor;
                    double height = oh * factor;
                    Rect2d box = new Rect2d();
                    box.X = x;
                    box.Y = y;
                    box.Width = width;
                    box.Height = height;
                    position_boxes.Add(box);
                    class_ids.Add(max_classId_point.X);
                    confidences.Add((float)max_score);
                    rotations.Add(result_data.At<float>(i, 19));
                }
            }

            // NMS 
            int[] indexes = new int[position_boxes.Count];
            CvDnn.NMSBoxes(position_boxes, confidences, 0.25f, 0.7f, out indexes);
            List<RotatedRect> rotated_rects = new List<RotatedRect>();
            for (int i = 0; i < indexes.Length; i++)
            {
                int index = indexes[i];
                float w = (float)position_boxes[index].Width;
                float h = (float)position_boxes[index].Height;
                float x = (float)position_boxes[index].X + w / 2;
                float y = (float)position_boxes[index].Y + h / 2;
                float r = rotations[index];
                float w_ = w > h ? w : h;
                float h_ = w > h ? h : w;
                r = (float)((w > h ? r : (float)(r + Math.PI / 2)) % Math.PI);
                RotatedRect rotate = new RotatedRect(new Point2f(x, y), new Size2f(w_, h_), (float)(r * 180.0 / Math.PI));
                rotated_rects.Add(rotate);
            }

            result_image = image.Clone();

            for (int i = 0; i < indexes.Length; i++)
            {
                int index = indexes[i];
                Point2f[] points = rotated_rects[i].Points();

                for (int j = 0; j < 4; j++)
                {
                    Cv2.Line(result_image, (OpenCvSharp.Point)points[j], (OpenCvSharp.Point)points[(j + 1) % 4], new Scalar(0, 255, 0), 2);
                }

                Cv2.PutText(result_image, class_lables[class_ids[index]] + "-" + confidences[index].ToString("0.00"),
                    (OpenCvSharp.Point)points[0], HersheyFonts.HersheySimplex, 0.8, new Scalar(0, 0, 255), 2);
            }

            pictureBox2.Image = new Bitmap(result_image.ToMemoryStream());
            textBox1.Text = "推理耗时:" + (dt2 - dt1).TotalMilliseconds + "ms";

            button2.Enabled = true;
        }

        private void pictureBox2_DoubleClick(object sender, EventArgs e)
        {
            Common.ShowNormalImg(pictureBox2.Image);
        }

        private void pictureBox1_DoubleClick(object sender, EventArgs e)
        {
            Common.ShowNormalImg(pictureBox1.Image);
        }
    }
}

using OpenCvSharp;
using OpenCvSharp.Dnn;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Windows.Forms;namespace OpenCvSharp_DNN_Demo
{public partial class frmMain : Form{public frmMain(){InitializeComponent();}string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";string image_path = "";DateTime dt1 = DateTime.Now;DateTime dt2 = DateTime.Now;string modelpath;string classer_path;List<string> class_names;Net opencv_net;Mat BN_image;Mat image;Mat result_image;string[] class_lables;private void button1_Click(object sender, EventArgs e){OpenFileDialog ofd = new OpenFileDialog();ofd.Filter = fileFilter;if (ofd.ShowDialog() != DialogResult.OK) return;pictureBox1.Image = null;pictureBox2.Image = null;textBox1.Text = "";image_path = ofd.FileName;pictureBox1.Image = new Bitmap(image_path);image = new Mat(image_path);}private void Form1_Load(object sender, EventArgs e){modelpath = "model/yolov8s-obb.onnx";classer_path = "model/lable.txt";opencv_net = CvDnn.ReadNetFromOnnx(modelpath);List<string> str = new List<string>();StreamReader sr = new StreamReader(classer_path);string line;while ((line = sr.ReadLine()) != null){str.Add(line);}class_lables = str.ToArray();image_path = "test_img/1.png";pictureBox1.Image = new Bitmap(image_path);}private  void button2_Click(object sender, EventArgs e){if (image_path == ""){return;}textBox1.Text = "检测中,请稍等……";pictureBox2.Image = null;button2.Enabled = false;Application.DoEvents();image = new Mat(image_path);//图片缩放image = new Mat(image_path);int max_image_length = image.Cols > image.Rows ? image.Cols : image.Rows;Mat max_image = Mat.Zeros(new OpenCvSharp.Size(max_image_length, max_image_length), MatType.CV_8UC3);Rect roi = new Rect(0, 0, image.Cols, image.Rows);image.CopyTo(new Mat(max_image, roi));float[] result_array;float factor = (float)(max_image_length / 640.0);// 将图片转为RGB通道Mat image_rgb = new Mat();Cv2.CvtColor(max_image, image_rgb, ColorConversionCodes.BGR2RGB);Mat resize_image = new Mat();Cv2.Resize(image_rgb, resize_image, new OpenCvSharp.Size(640, 640));BN_image = CvDnn.BlobFromImage(resize_image, 1 / 255.0, new OpenCvSharp.Size(640, 640), new Scalar(0, 0, 0), true, false);//配置图片输入数据opencv_net.SetInput(BN_image);//模型推理,读取推理结果Mat[] outs = new Mat[1] { new Mat() };string[] outBlobNames = opencv_net.GetUnconnectedOutLayersNames().ToArray();dt1 = DateTime.Now;opencv_net.Forward(outs, outBlobNames);dt2 = DateTime.Now;int num_proposal = outs[0].Size(1);int nout = outs[0].Size(2);if (outs[0].Dims > 2){outs[0] = outs[0].Reshape(0, num_proposal);}Mat result_data = new Mat(20, 8400, MatType.CV_32F);result_data = outs[0].T();List<Rect2d> position_boxes = new List<Rect2d>();List<int> class_ids = new List<int>();List<float> confidences = new List<float>();List<float> rotations = new List<float>();// Preprocessing output resultsfor (int i = 0; i < result_data.Rows; i++){Mat classes_scores = new Mat(result_data, new Rect(4, i, 15, 1));OpenCvSharp.Point max_classId_point, min_classId_point;double max_score, min_score;// Obtain the maximum value and its position in a set of dataCv2.MinMaxLoc(classes_scores, out min_score, out max_score,out min_classId_point, out max_classId_point);// Confidence level between 0 ~ 1// Obtain identification box informationif (max_score > 0.25){float cx = result_data.At<float>(i, 0);float cy = result_data.At<float>(i, 1);float ow = result_data.At<float>(i, 2);float oh = result_data.At<float>(i, 3);double x = (cx - 0.5 * ow) * factor;double y = (cy - 0.5 * oh) * factor;double width = ow * factor;double height = oh * factor;Rect2d box = new Rect2d();box.X = x;box.Y = y;box.Width = width;box.Height = height;position_boxes.Add(box);class_ids.Add(max_classId_point.X);confidences.Add((float)max_score);rotations.Add(result_data.At<float>(i, 19));}}// NMS int[] indexes = new int[position_boxes.Count];CvDnn.NMSBoxes(position_boxes, confidences, 0.25f, 0.7f, out indexes);List<RotatedRect> rotated_rects = new List<RotatedRect>();for (int i = 0; i < indexes.Length; i++){int index = indexes[i];float w = (float)position_boxes[index].Width;float h = (float)position_boxes[index].Height;float x = (float)position_boxes[index].X + w / 2;float y = (float)position_boxes[index].Y + h / 2;float r = rotations[index];float w_ = w > h ? w : h;float h_ = w > h ? h : w;r = (float)((w > h ? r : (float)(r + Math.PI / 2)) % Math.PI);RotatedRect rotate = new RotatedRect(new Point2f(x, y), new Size2f(w_, h_), (float)(r * 180.0 / Math.PI));rotated_rects.Add(rotate);}result_image = image.Clone();for (int i = 0; i < indexes.Length; i++){int index = indexes[i];Point2f[] points = rotated_rects[i].Points();for (int j = 0; j < 4; j++){Cv2.Line(result_image, (OpenCvSharp.Point)points[j], (OpenCvSharp.Point)points[(j + 1) % 4], new Scalar(0, 255, 0), 2);}Cv2.PutText(result_image, class_lables[class_ids[index]] + "-" + confidences[index].ToString("0.00"),(OpenCvSharp.Point)points[0], HersheyFonts.HersheySimplex, 0.8, new Scalar(0, 0, 255), 2);}pictureBox2.Image = new Bitmap(result_image.ToMemoryStream());textBox1.Text = "推理耗时:" + (dt2 - dt1).TotalMilliseconds + "ms";button2.Enabled = true;}private void pictureBox2_DoubleClick(object sender, EventArgs e){Common.ShowNormalImg(pictureBox2.Image);}private void pictureBox1_DoubleClick(object sender, EventArgs e){Common.ShowNormalImg(pictureBox1.Image);}}
}

下载

源码下载

这篇关于C# OpenCvSharp DNN Yolov8-OBB 旋转目标检测的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/751684

相关文章

C#连接SQL server数据库命令的基本步骤

《C#连接SQLserver数据库命令的基本步骤》文章讲解了连接SQLServer数据库的步骤,包括引入命名空间、构建连接字符串、使用SqlConnection和SqlCommand执行SQL操作,... 目录建议配合使用:如何下载和安装SQL server数据库-CSDN博客1. 引入必要的命名空间2.

Linux系统性能检测命令详解

《Linux系统性能检测命令详解》本文介绍了Linux系统常用的监控命令(如top、vmstat、iostat、htop等)及其参数功能,涵盖进程状态、内存使用、磁盘I/O、系统负载等多维度资源监控,... 目录toppsuptimevmstatIOStatiotopslabtophtopdstatnmon

C#读写文本文件的多种方式详解

《C#读写文本文件的多种方式详解》这篇文章主要为大家详细介绍了C#中各种常用的文件读写方式,包括文本文件,二进制文件、CSV文件、JSON文件等,有需要的小伙伴可以参考一下... 目录一、文本文件读写1. 使用 File 类的静态方法2. 使用 StreamReader 和 StreamWriter二、二进

C#中Guid类使用小结

《C#中Guid类使用小结》本文主要介绍了C#中Guid类用于生成和操作128位的唯一标识符,用于数据库主键及分布式系统,支持通过NewGuid、Parse等方法生成,感兴趣的可以了解一下... 目录前言一、什么是 Guid二、生成 Guid1. 使用 Guid.NewGuid() 方法2. 从字符串创建

C# 比较两个list 之间元素差异的常用方法

《C#比较两个list之间元素差异的常用方法》:本文主要介绍C#比较两个list之间元素差异,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. 使用Except方法2. 使用Except的逆操作3. 使用LINQ的Join,GroupJoin

C++ 检测文件大小和文件传输的方法示例详解

《C++检测文件大小和文件传输的方法示例详解》文章介绍了在C/C++中获取文件大小的三种方法,推荐使用stat()函数,并详细说明了如何设计一次性发送压缩包的结构体及传输流程,包含CRC校验和自动解... 目录检测文件的大小✅ 方法一:使用 stat() 函数(推荐)✅ 用法示例:✅ 方法二:使用 fsee

基于 HTML5 Canvas 实现图片旋转与下载功能(完整代码展示)

《基于HTML5Canvas实现图片旋转与下载功能(完整代码展示)》本文将深入剖析一段基于HTML5Canvas的代码,该代码实现了图片的旋转(90度和180度)以及旋转后图片的下载... 目录一、引言二、html 结构分析三、css 样式分析四、JavaScript 功能实现一、引言在 Web 开发中,

OpenCV实现实时颜色检测的示例

《OpenCV实现实时颜色检测的示例》本文主要介绍了OpenCV实现实时颜色检测的示例,通过HSV色彩空间转换和色调范围判断实现红黄绿蓝颜色检测,包含视频捕捉、区域标记、颜色分析等功能,具有一定的参考... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间

C#如何去掉文件夹或文件名非法字符

《C#如何去掉文件夹或文件名非法字符》:本文主要介绍C#如何去掉文件夹或文件名非法字符的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#去掉文件夹或文件名非法字符net类库提供了非法字符的数组这里还有个小窍门总结C#去掉文件夹或文件名非法字符实现有输入字

C#之List集合去重复对象的实现方法

《C#之List集合去重复对象的实现方法》:本文主要介绍C#之List集合去重复对象的实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C# List集合去重复对象方法1、测试数据2、测试数据3、知识点补充总结C# List集合去重复对象方法1、测试数据