当前位置: 首页 > article >正文

EmguCV学习笔记 C# 11.5 目标检测

版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。

EmguCV是一个基于OpenCV的开源免费的跨平台计算机视觉库,它向C#和VB.NET开发者提供了OpenCV库的大部分功能。

教程VB.net版本请访问:EmguCV学习笔记 VB.Net 目录-CSDN博客

教程C#版本请访问:EmguCV学习笔记 C# 目录-CSDN博客

笔者的博客网址:https://blog.csdn.net/uruseibest

教程配套文件及相关说明以及如何获得pdf教程和代码,请移步:EmguCV学习笔记

学习VB.Net知识,请移步: vb.net 教程 目录_vb中如何用datagridview-CSDN博客

 学习C#知识,请移步:C# 教程 目录_c#教程目录-CSDN博客

11.5 目标检测

11.5.1 Yolo

YOLO(You Only Look Once)是一种流行的目标检测算法,它使用单个神经网络同时进行对象检测和对象分类。相比于传统的目标检测算法,YOLO在目标检测任务中表现优秀,有更快的速度和更高的准确性,被广泛应用于自动驾驶、安防监控等领域。

【代码位置:frmChapter11】Button3_Click

       //目标检测:yolo

        private void Button3_Click(object sender, EventArgs e)

        {

            //对象分类,coco.names文件提供了80类对象

            string[] classnames = System.IO.File.ReadAllLines("C:\\learnEmgucv\\yolo\\coco.names");

            //需要测试的图像文件

            Mat m = new Mat("C:\\learnEmgucv\\dnntest.jpg", ImreadModes.Color);

            int hm = m.Height;

            int wm = m.Width;

            Net net;

            //读取yolo的推理模型文件

            net = DnnInvoke.ReadNetFromDarknet("C:\\learnEmgucv\\yolo\\yolov3.cfg",

                    "C:\\learnEmgucv\\yolo\\yolov3.weights");

            net.SetPreferableBackend(Emgu.CV.Dnn.Backend.OpenCV);

            net.SetPreferableTarget(Target.Cpu);

            Mat blob;

            //注意:BlobFromImagesize参数

            //以前使用(416,416),现在是(608, 608),参看yolov3.cfg

            //如果继续使用(416,416),那么会有部分物体检测不出

            blob = DnnInvoke.BlobFromImage(m, 1.0 / 255.0, new Size(608, 608), new MCvScalar(0, 0, 0), true, false);

            net.SetInput(blob);

            //获取推理模型中未连接的输出层名称列表

            string[] names = net.UnconnectedOutLayersNames;

            //或者以下方法获得

            //int[] outLayers = net.UnconnectedOutLayers;

            //string[] layerNames = net.LayerNames;

            //string[] names = new string[outLayers.Length];

            //for (int i = 0; i < outLayers.Length; i++)

            //    names[i] = layerNames[outLayers[i] - 1];

            VectorOfMat mout = new VectorOfMat();

            net.Forward(mout, names);

            //只有一张图片,只需要mout(0)即可

            Mat mout1 = new Mat();

            mout1 = mout[0];

            //返回二维数组

            Single[,] detection;

            detection = (Single[,])mout1.GetData();

            int rows = detection.GetLength(0);

            int cols = detection.GetLength(1);

            //置信度

            List<Single> lstYoloConf = new List<Single>();

            //方框坐标

            List<Rectangle> lstYoloRects = new List<Rectangle>();

            //识别到的物体序号

            List<int> lstYoloIndex = new List<int>();

            //行数为检测出对象的数量

            //每列从 0 84,一共85个元素,

            //    0-1为矩形区域的中心坐标XY的百分比

            //    2-3为矩形的宽度和高度的百分比

            //    4为矩形区域的置信度

            //    5-84为对应的80类对象分别的置信度

            //存在两个置信度

            for (int i = 0; i < rows; i++)

            {

                //第一个置信度是矩形区域的置信度

                Single conf = detection[i, 4];

                //先判断矩形区域的置信度是否符合要求

                if (conf > 0.5)

                {

                    Single x = detection[i, 0] * wm;  //百分比,需要乘以源图像的宽度

                    Single y = detection[i, 1] * hm;  //百分比,需要乘以源图像的高度

                    Single w = detection[i, 2] * wm;  //百分比,需要乘以源图像的宽度

                    Single h = detection[i, 3] * hm;  //百分比,需要乘以源图像的高度

                    for (int k = 5; k <= 84; k++)

                    {

                        //第二个置信度是检测出的对象分类的置信度

                        //判断对象分类的置信度是否符合要求

                        if (detection[i, k] > 0.5)

                        {

                            lstYoloConf.Add(conf);

                            lstYoloRects.Add(new Rectangle((int)(x - w / 2), (int)(y - h / 2), (int)w, (int)h));

                            //注意,是从第6个(索引为5)开始

                            lstYoloIndex.Add(k - 5);

                        }

                    }

                }

            }

            //利用NMS把重复位置的rectangle去除

            int[] selectedObj;

            selectedObj = DnnInvoke.NMSBoxes(lstYoloRects.ToArray(), lstYoloConf.ToArray(), 0.2F, 0.3F);

            for (int i = 0; i < lstYoloRects.Count; i++)

            {

                //只画出被保留下來的rectangle

                if (selectedObj.Contains(i))

                {

                    //输出检测出的对象所在矩形区域

                    CvInvoke.Rectangle(m, lstYoloRects[i], new MCvScalar(0, 255, 0), 1);

                    //获得检测出的对象的种类名称

                    string objName = classnames[lstYoloIndex[i]];

                    //输出检测出的对象名称

                    CvInvoke.PutText(m, objName,

                               new Point(lstYoloRects[i].X, lstYoloRects[i].Y - 5),

                               FontFace.HersheyTriplex, 0.3, new MCvScalar(0, 0, 255));

                    //输出检测出的置信度

                    CvInvoke.PutText(m, lstYoloConf[i].ToString(),

                               new Point(lstYoloRects[i].X + 40, lstYoloRects[i].Y - 5),

                               FontFace.HersheyComplex, 0.3, new MCvScalar(255, 0, 0));

                }

            }

            ImageBox1.Image = m;

        }

输出结果如下图所示:

 

图11-2 使用YOLO进行目标检测的结果

11.5.2 SSD

SSD(Single Shot MultiBox Detector)是一种流行的目标检测算法,它使用单个神经网络同时进行对象检测和对象分类。相比于传统的目标检测算法,SSD可以快速准确地检测出图像中的对象,被广泛应用于自动驾驶、安防监控等领域。

【代码位置:frmChapter11】Button4_Click

        //ssd

        private void Button4_Click(object sender, EventArgs e)

        {

            //对象分类,object_detection_classes_pascal_voc.txt文件提供了21类对象(含background

            string[] classnames = System.IO.File.ReadAllLines("C:\\learnEmgucv\\ssd\\object_detection_classes_pascal_voc.txt");

            //需要测试的图像文件

            Mat m = new Mat("C:\\learnEmgucv\\dnntest.jpg", ImreadModes.Color);

            Single hm = m.Height;

            Single wm = m.Width;

            Net net;

            //读取SSD的推理模型文件

            net = DnnInvoke.ReadNetFromCaffe("C:\\learnEmgucv\\ssd\\MobileNetSSD_deploy.prototxt.txt",

                                               "C:\\learnEmgucv\\ssd\\MobileNetSSD_deploy.caffemodel");

            net.SetPreferableBackend(Emgu.CV.Dnn.Backend.OpenCV);

            net.SetPreferableTarget(Target.Cpu);

            //输入图像必须是(300,300),参看MobileNetSSD_deploy.prototxt.txtinput_shape

            Mat mCopy = new Mat();

            CvInvoke.Resize(m, mCopy, new Size(300, 300));

            Mat blob = DnnInvoke.BlobFromImage(mCopy, 0.007843, new Size(300, 300),

                                       new MCvScalar(127.5,127.5, 127.5), false, false);

            net.SetInput(blob);

            //

            Mat mout = new Mat();

            mout = net.Forward();

            //返回四维数组

            Single[,,,] fout;

            fout = (Single[,,,] )mout.GetData();

            //检测到的所有对象的数量

            int allObjCount = fout.GetLength(2);

            //识别到的对象序号

            List<int> lstSsdIndex = new List<int>();

            //置信度

            List<Single> lstSsdConf = new List<Single>();

            //矩形

            List<Rectangle> lstSsdRects = new List<Rectangle>();

            for (int i = 0; i < allObjCount; i++)

            {

                //置信度

                Single conf;

                conf = fout[0, 0, i, 2];

                if (conf > 0.5)

                {

                    lstSsdConf.Add(conf);

                    //对应对象序号

                    lstSsdIndex.Add((int)fout[0,0,i,1]);

                    //左上角X

                    int lbx = (int)(fout[0, 0, i, 3] * wm);

                    //左上角Y

                    int lby = (int)(fout[0, 0, i, 4] * hm);

                    //右下角X

                    int rtx = (int)(fout[0, 0, i, 5] * wm);

                    //右下角Y

                    int rty = (int)(fout[0, 0, i, 6] * hm);

                    //对应矩形

                    lstSsdRects.Add(new Rectangle(lbx, lby, rtx - lbx, rty - lby));

                }

            }

            for (int i = 0; i < lstSsdIndex.Count; i++)

            {

                //检测出的对象所在矩形区域

                CvInvoke.Rectangle(m, lstSsdRects[i], new MCvScalar(0, 255, 0), 1);

                string objName = classnames[lstSsdIndex[i]];

                Console.WriteLine(objName + lstSsdConf[i]);

                //输出检测出的对象名称

                CvInvoke.PutText(m, objName,

                            new Point(lstSsdRects[i].X, lstSsdRects[i].Y - 5),

                            FontFace.HersheyTriplex, 0.3, new MCvScalar(0, 0, 255));

                //输出检测出的置信度

                CvInvoke.PutText(m, lstSsdConf[i].ToString(),

                            new Point(lstSsdRects[i].X + 40, lstSsdRects[i].Y - 5),

                            FontFace.HersheyComplex, 0.3, new MCvScalar(255, 0, 0));   

            }

            ImageBox1.Image = m;

        }

输出结果如下图所示:

 

图11-3使用SSD进行目标检测的结果


http://www.kler.cn/a/304870.html

相关文章:

  • SNH48 GROUP燃动杭州 第五届偶像运动会落下帷幕
  • Android 如何实现不编译指定的apk,不加载系统应用
  • uniapp—android原生插件开发(1环境准备)
  • BGP线路的优势和使用场景有哪些?
  • Ente: 我们的 Monorepo 经验
  • DDei在线设计器V1.2.42版发布
  • 期货量化现在是要比股票量化更适合高频交易,程序化交易
  • 电脑桌面数据误删如何恢复?提供一份实用指南
  • spark sql详解
  • MVC 控制器
  • Qt-QLCDNumber显示类控件(26)
  • 如何简化机器人模型,加速仿真计算与可视化
  • 基于less和scss 循环生成css
  • Java中的高级I/O操作:NIO和AIO的比较
  • 大数据-129 - Flink CEP 详解 Complex Event Processing - 复杂事件处理
  • 哪个虚拟机软件在 Mac 上更好用,Mac 虚拟机会影响性能吗?
  • 计算机网络30——Linux-gdb调试命令makefile
  • [Linux#48][网络] 令牌环网 | IPv4 | socket 套接字 | TCP | UDP | 网络字节序列
  • Pytest配置文件pytest.ini如何编写生成日志文件?
  • AI创意引擎:优化Prompt提示词的高效提问技巧
  • 相机光学(三十八)——VCM(Voice Coil Motor)音圈马达
  • 数据分析-20-时间序列预测之基于PyTorch的LSTM数据准备及模型训练流程
  • Java后端编程语言进阶篇
  • 第158天:安全开发-Python-Socket编程反弹Shell分离免杀端口探针域名爆破
  • 前端知识点
  • Apache 的CollectionUtils各种集合操作好用的方法总结