EmguCV学习笔记 VB.Net 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 Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click

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

        Dim classnames() As String

        classnames = File.ReadAllLines("C:\learnEmgucv\yolo\coco.names")

        '需要测试的图像文件

        Dim m As New Mat("C:\learnEmgucv\dnntest.jpg", ImreadModes.Color)

        Dim hm As Integer = m.Height

        Dim wm As Integer = m.Width

        Dim net As Dnn.Net

        '读取yolo的推理模型文件

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

        net.SetPreferableBackend(Dnn.Backend.OpenCV)

        net.SetPreferableTarget(Target.Cpu)

        Dim blob As Mat

        '注意: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)

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

        Dim names() As String = net.UnconnectedOutLayersNames

        '或者以下方法获得

        'Dim outLayers() As Integer = net.UnconnectedOutLayers        ''

        'Dim layerNames() As String = net.LayerNames

        'Dim names(outLayers.Length - 1) As String

        'For i As Integer = 0 To outLayers.Length - 1

        '    names(i) = layerNames(outLayers(i) - 1)

        'Next

        Dim mout As New VectorOfMat

        net.Forward(mout, names)

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

        Dim mout1 As New Mat

        mout1 = mout(0)

        '返回二维数组

        Dim detection(,) As Single

        detection = mout1.GetData()

        Dim rows As Integer = detection.GetLength(0)

        Dim cols As Integer = detection.GetLength(1)

        '置信度

        Dim lstYoloConf As New List(Of Single)

        '方框坐标

        Dim lstYoloRects As New List(Of Rectangle)

        '识别到的物体序号

        Dim lstYoloIndex As New List(Of Integer)

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

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

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

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

        '    4为矩形区域的置信度

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

        '存在两个置信度

        For i As Integer = 0 To rows - 1

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

            Dim conf As Single = detection(i 4)

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

            If conf > 0.5 Then

                Dim x As Single = detection(i 0) * wm  '百分比,需要乘以源图像的宽度

                Dim y As Single = detection(i 1) * hm  '百分比,需要乘以源图像的高度

                Dim w As Single = detection(i 2) * wm  '百分比,需要乘以源图像的宽度

                Dim h As Single = detection(i 3) * hm  '百分比,需要乘以源图像的高度

                For k As Integer = 5 To 84

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

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

                    If detection(i, k) > 0.5 Then

                        lstYoloConf.Add(conf)

                        lstYoloRects.Add(New Rectangle(CInt(x - w / 2), CInt(y - h / 2), w, h))

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

                        lstYoloIndex.Add(k - 5)

                    End If

                Next

            End If

        Next

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

        Dim selectedObj() As Integer

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

        For i As Integer = 0 To lstYoloRects.Count - 1

            '只画出被保留下來的rectangle

            If (selectedObj.Contains(i)) Then

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

                CvInvoke.Rectangle(m, lstYoloRects(i), New MCvScalar(0, 255, 0), 1)

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

                Dim objName As 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),

                                 New Point(lstYoloRects(i).X + 40, lstYoloRects(i).Y - 5),

                                 FontFace.HersheyComplex, 0.3, New MCvScalar(255, 0, 0))

            End If

        Next

        ImageBox1.Image = m

End Sub

输出结果如下图所示:

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

11.5.2 SSD

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

【代码位置:frmChapter11】Button4_Click

   'ssd

    Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click

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

        Dim classnames() As String

        classnames = File.ReadAllLines("C:\learnEmgucv\ssd\object_detection_classes_pascal_voc.txt")

        '需要测试的图像文件

        Dim m As New Mat("C:\learnEmgucv\dnntest.jpg", ImreadModes.Color)

        Dim hm As Single = m.Height

        Dim wm As Single = m.Width

        Dim net As Dnn.Net

        '读取SSD的推理模型文件

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

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

        net.SetPreferableBackend(Dnn.Backend.OpenCV)

        net.SetPreferableTarget(Target.Cpu)

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

        Dim mCopy As New Mat

        CvInvoke.Resize(m, mCopy, New Drawing.Size(300, 300))

        Dim blob As Mat

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

                                       New MCvScalar(127.5 127.5 127.5), False, False)

        net.SetInput(blob)

        '

        Dim mout As New Mat

        mout = net.Forward()

        '返回四维数组

        Dim fout(,,,) As Single

        fout = mout.GetData()

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

        Dim allObjCount As Integer = fout.GetLength(2)

        '识别到的对象序号

        Dim lstSsdIndex As New List(Of Integer)

        '置信度

        Dim lstSsdConf As New List(Of Single)

        '矩形

        Dim lstSsdRects As New List(Of Rectangle)

        For i As Integer = 0 To allObjCount - 1

            '置信度

            Dim conf As Single

            conf = fout(0, 0, i, 2)

            If conf > 0.5 Then

                lstSsdConf.Add(conf)

                '对应对象序号

                lstSsdIndex.Add(fout(0, 0, i, 1))

                '左上角X

                Dim lbx As Integer = CInt(fout(0, 0, i, 3) * wm)

                '左上角Y

                Dim lby As Integer = CInt(fout(0, 0, i, 4) * hm)

                '右下角X

                Dim rtx As Integer = CInt(fout(0, 0, i, 5) * wm)

                '右下角Y

                Dim rty As Integer = CInt(fout(0, 0, i, 6) * hm)

                '对应矩形

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

            End If

        Next

        For i As Integer = 0 To lstSsdIndex.Count - 1

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

            CvInvoke.Rectangle(m, lstSsdRects(i), New MCvScalar(0, 255, 0), 1)

            Dim objName As 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),

                                 New Point(lstSsdRects(i).X + 40, lstSsdRects(i).Y - 5),

                                 FontFace.HersheyComplex, 0.3, New MCvScalar(255, 0, 0))

        Next

        ImageBox1.Image = m

End Sub

输出结果如下图所示:

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值