EmguCV学习笔记 VB.Net 11.9 姿势识别 OpenPose

news2024/11/24 10:49:55

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

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.9 姿势识别 OpenPose

OpenPose模型是一种用于人体姿态估计的深度学习模型,它能够检测出包括眼睛、鼻子、手臂、腿等18个人体的关键点,并估计它们的坐标位置和置信度。

0:Nose(鼻子)、1:neck(脖子)、2:rshoulder(右肩)、3:relbow(右肘部)、4:rwrist(右手腕)、5:shoulder(左肩)、6:lelbow(左肘部)、7:lwrist(左手腕)、8:rhip(右臀部)、9:rknee(右膝盖)、10:rankle(右脚踝)、11:lhip(左臀部)、12:lknee(左膝盖)、13:lankle(左脚踝)、14:reye(右眼)、15:leye(左眼)、16:rear(右耳)、17:lear(左耳)、18:background(背景,主要是作为下一步扩展使用,在实际中不处理)

在使用OpenPose模型时,通常需要将输入图像作为模型的输入,经过处理后得到一个四维数组作为输出结果。这个四维数组,其维度为(N, P, H, W),

各个维度的含义:

  1. N:在输入图像中检测到的人体数量。
  2. P:估计的关键点数,包括了人体的身体部位和手指关节等,只需要取前18个。
  3. H:关键点的坐标信息在输出结果中的高度,在实际使用中就是DnnInvoke.BlobFromImage中size参数设置输出的Height,如果最终输出到源图像,那么应该按照比例进行还原。
  4. W:关键点的坐标信息在输出结果中的宽度,在实际使用中就是DnnInvoke.BlobFromImage中size参数设置输出的Width,如果最终输出到源图像,那么应该按照比例进行还原。

具体到某个元素的值就是该点是人体关键点的置信度,例如(0,2,10,30)返回(0,2,height,width)中的最大值为0.759,那么可以认为坐标(10,30)是右肩的可能性为75.9%。

从上面可以看出,在这个四维数组中,每个元素包含了x坐标(维度W)、y坐标(维度H)和置信度三个值。因此,可以通过遍历该四维数组并解析每个元素来获取所有关键点的坐标信息和置信度,从而进行人体姿态估计的后续处理。

【代码位置:frmChapter11】Button10_Click、getMaxPoint

   '关键点信息

    Structure Keypoint

        Dim conf As Single  '置信度

        Dim p As Point     '关键点坐标

    End Structure

    '使用openpose显示人体关键点

    Private Sub Button10_Click(sender As Object, e As EventArgs) Handles Button10.Click

        '人体关键点

        Dim body_Keypoint() As String = {"nose", "neck", "rshoulder", "relbow", "rwrist", "lshoulder",

     "lelbow", "lwrist", "rhip", "rknee", "rankle", "lhip",

     "lknee", "lankle", "reye", "leye", "rear", "lear", "background"}

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

        Dim net As Dnn.Net = DnnInvoke.ReadNetFromTensorflow("C:\learnEmgucv\openpose\graph_opt.pb")

        Dim blob As Mat = DnnInvoke.BlobFromImage(m, 1.0, New Drawing.Size(360, 360), New MCvScalar(127.5, 127.5, 127.5), False, False)

        net.SetInput(blob)

        Dim mout As Mat = net.Forward()

        '返回四维数组

        Dim fout(,,,) As Single

        fout = mout.GetData()

        Dim H As Integer = fout.GetLength(2)

        Dim W As Integer = fout.GetLength(3)

        Dim lkeypoint As New List(Of Keypoint)

        '获得关键点信息

        lkeypoint = getMaxPoint(fout)

        Dim x, y As Single

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

            '按照比例获得关键点在源图像中的坐标

            x = (lkeypoint(i).p.X / W) * m.Width

            y = (lkeypoint(i).p.Y / H) * m.Height

            '调试时输出信息

            'Console.WriteLine(body_Keypoint(i) & " " & lkeypoint(i).conf & " " & lkeypointi).p.X & "-" & lkeypoint(i).p.Y)

            '置信度超过某个值才能认为是正确的结果

            If lkeypoint(i).conf > 0.1 Then

                CvInvoke.Circle(m, New Point(x, y), 4, New MCvScalar(255, 0, 0), -1)

            End If

        Next

        CvInvoke.Imshow("m", m)

    End Sub

    '获得人体18个关键点列表,这里考虑只有一个人体的情况

    Private Function getMaxPoint(ByVal inputarray(,,,) As Single) As List(Of Keypoint)

        Dim lkeypoint As New List(Of Keypoint)

        Dim peoplecount As Integer = 1  '考虑只有一个人体的情况,如果多个人体,请使用 inputarray.GetLength(0)

        Dim modecount As Integer = 18   '只考虑18个人体关键点, inputarray.GetLength(1)

        Dim dim3 As Integer = inputarray.GetLength(2)   '图像高度

        Dim dim4 As Integer = inputarray.GetLength(3)   '图像宽度

        '循环,检测到的人体个数

        For i As Integer = 0 To peoplecount - 1

            '循环,检测到的人体关键点

            For j As Integer = 0 To modecount - 1

                Dim maxvalue As Single = 0

                Dim maxX As Integer = 0

                Dim maxY As Integer = 0

                '循环,图像高度,即对应Y坐标

                For k As Integer = 0 To dim3 - 1

                    '循环,图像宽度,即对应X坐标

                    For l As Integer = 0 To dim4 - 1

                        '获得置信度最大的值,并获得其坐标

                        If maxvalue < inputarray(i, j, k, l) Then

                            maxvalue = inputarray(i, j, k, l)

                            maxX = l

                            maxY = k

                        End If

                    Next

                Next

                '添加到关键点列表

                Dim kp As New Keypoint

                kp.conf = maxvalue

                kp.p = New Point(maxX, maxY)

                lkeypoint.Add(kp)

            Next

        Next

        Return lkeypoint

End Function

输出结果如下图所示:

图11-9 获得人体关键点

下面的代码通过人体关键点的关联,建立关键点的连线。

【代码位置:frmChapter11】Button11_Click、PointFToPoint

    '关键点关联

    Structure Relation

        '开始关键点

        Dim startpoint As Integer

        '结束关键点

        Dim endpoint As Integer

        Sub New(ByVal startpoint As Integer, ByVal endpoint As Integer)

            Me.startpoint = startpoint

            Me.endpoint = endpoint

        End Sub

    End Structure

    '获得人体关键点,并将关键点关联起来

    Private Sub Button11_Click(sender As Object, e As EventArgs) Handles Button11.Click

        Dim body_Keypoint() As String = {"nose", "neck", "rshoulder", "relbow", "rwrist", "lshoulder",

      "lelbow", "lwrist", "rhip", "rknee", "rankle", "lhip",

      "lknee", "lankle", "reye", "leye", "rear", "lear", "background"}

        '18个关键点关联

        Dim body_Relations As New List(Of Relation)

        body_Relations.Add(New Relation(16, 14))

        body_Relations.Add(New Relation(14, 0))

        body_Relations.Add(New Relation(17, 15))

        body_Relations.Add(New Relation(15, 0))

        body_Relations.Add(New Relation(0, 1))

        body_Relations.Add(New Relation(1, 2))

        body_Relations.Add(New Relation(2, 3))

        body_Relations.Add(New Relation(3, 4))

        body_Relations.Add(New Relation(1, 5))

        body_Relations.Add(New Relation(5, 6))

        body_Relations.Add(New Relation(6, 7))

        body_Relations.Add(New Relation(1, 8))

        body_Relations.Add(New Relation(8, 9))

        body_Relations.Add(New Relation(9, 10))

        body_Relations.Add(New Relation(1, 11))

        body_Relations.Add(New Relation(11, 12))

        body_Relations.Add(New Relation(12, 13))

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

        Dim net As Dnn.Net

        net = DnnInvoke.ReadNetFromTensorflow("C:\learnEmgucv\openpose\graph_opt.pb")

        Dim blob As Mat

        blob = DnnInvoke.BlobFromImage(m, 1.0, New Drawing.Size(360, 360), 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 H As Integer = fout.GetLength(2)

        Dim W As Integer = fout.GetLength(3)

        Dim lkeypoint As New List(Of Keypoint)

        lkeypoint = getMaxPoint(fout)

        Dim x, y As Single

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

            '按照比例获得关键点在源图像中的坐标

            x = (lkeypoint(i).p.X / W) * m.Width

            y = (lkeypoint(i).p.Y / H) * m.Height

            '置信度超过某个值才能认为是正确的结果

            If lkeypoint(i).conf > 0.1 Then

                CvInvoke.Circle(m, New Point(x, y), 5, New MCvScalar(255, 0, 0), -1)

            End If

        Next

        Dim startpoint As PointF

        Dim startpointx, startpointy As Single

        Dim endpoint As PointF

        Dim endpointx, endpointy As Single

        For Each body_Relation As Relation In body_Relations

            startpointx = (lkeypoint(body_Relation.startpoint).p.X / W) * m.Width

            startpointy = (lkeypoint(body_Relation.startpoint).p.Y / H) * m.Height

            startpoint = New PointF(startpointx, startpointy)

            endpointx = (lkeypoint(body_Relation.endpoint).p.X / W) * m.Width

            endpointy = (lkeypoint(body_Relation.endpoint).p.Y / H) * m.Height

            endpoint = New PointF(endpointx, endpointy)

            '关键点置信度是否符合要求

            If lkeypoint(body_Relation.startpoint).conf > 0.1 And lkeypoint(body_Relation.endpoint).conf > 0.1 Then

                '关键点建立连线

                CvInvoke.Line(m, PointFToPoint(startpoint), PointFToPoint(endpoint), New MCvScalar(0, 255, 0), 3)

            End If

        Next

        CvInvoke.Imshow("m", m)

    End Sub

    'PointFPoint方法

    Public Shared Function PointFToPoint(ByVal pf As PointF) As Point

        Return New Point(CInt(pf.X), CInt(pf.Y))

End Function

输出结果如下图所示:

 

图11-10 人体关键点连线

下面代码是在上面代码基础上,实现在视频中显示人体关键点的连线。

【代码位置:frmChapter11】Button12_Click、vc_ImageGrabbed

    Dim vc As VideoCapture

    Dim body_Relations As New List(Of Relation)

    '将视频人物标注人体关键点和关键点连线

    Private Sub Button12_Click(sender As Object, e As EventArgs) Handles Button12.Click

        '18个关键点关联

        body_Relations = New List(Of Relation)

        body_Relations.Add(New Relation(16, 14))

        body_Relations.Add(New Relation(14, 0))

        body_Relations.Add(New Relation(17, 15))

        body_Relations.Add(New Relation(15, 0))

        body_Relations.Add(New Relation(0, 1))

        body_Relations.Add(New Relation(1, 2))

        body_Relations.Add(New Relation(2, 3))

        body_Relations.Add(New Relation(3, 4))

        body_Relations.Add(New Relation(1, 5))

        body_Relations.Add(New Relation(5, 6))

        body_Relations.Add(New Relation(6, 7))

        body_Relations.Add(New Relation(1, 8))

        body_Relations.Add(New Relation(8, 9))

        body_Relations.Add(New Relation(9, 10))

        body_Relations.Add(New Relation(1, 11))

        body_Relations.Add(New Relation(11, 12))

        body_Relations.Add(New Relation(12, 13))

        vc = New VideoCapture("C:\learnEmgucv\action.mp4")

        If vc.IsOpened = False Then

            MessageBox.Show("打开文件失败")

            Exit Sub

        End If

        '添加ImageGrabbed事件

        AddHandler vc.ImageGrabbed, AddressOf vc_ImageGrabbed

        vc.Start()

    End Sub

    Private Sub vc_ImageGrabbed(sender As Object, e As EventArgs)

        Dim outangle As Double = 0

        Dim outpix As Double = 0

        Dim nextframe As New Mat

        vc.Retrieve(nextframe)

        If vc.Get(CapProp.PosFrames) >= vc.Get(CapProp.FrameCount) Then

            vc.Stop()

            vc.Dispose()

            RemoveHandler vc.ImageGrabbed, AddressOf vc_ImageGrabbed

            Exit Sub

        End If

        Dim net As Dnn.Net

        net = DnnInvoke.ReadNetFromTensorflow("graph_opt.pb")

        Dim blob As Mat

        blob = DnnInvoke.BlobFromImage(nextframe, 1.0, New Drawing.Size(360, 360), New MCvScalar(127.5, 127.5, 127.5), True, False)

        net.SetInput(blob)

        Dim mout As New Mat

        mout = net.Forward()

        Dim fout(,,,) As Single

        fout = mout.GetData()

        Dim H As Integer = fout.GetLength(2)

        Dim W As Integer = fout.GetLength(3)

        Dim lkeypoint As New List(Of Keypoint)

        lkeypoint = getMaxPoint(fout)

        Dim x, y As Single

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

            x = (lkeypoint(i).p.X / W) * nextframe.Width

            y = (lkeypoint(i).p.Y / H) * nextframe.Height

            If lkeypoint(i).conf > 0.1 Then

                CvInvoke.Circle(nextframe, New Point(x, y), 5, New MCvScalar(0, 0, 255), -1)

            End If

        Next

        Dim startpoint As PointF

        Dim startpointx, startpointy As Single

        Dim endpoint As PointF

        Dim endpointx, endpointy As Single

        For Each body_Relation As Relation In body_Relations

            startpointx = (lkeypoint(body_Relation.startpoint).p.X / W) * nextframe.Width

            startpointy = (lkeypoint(body_Relation.startpoint).p.Y / H) * nextframe.Height

            startpoint = New PointF(startpointx, startpointy)

            endpointx = (lkeypoint(body_Relation.endpoint).p.X / W) * nextframe.Width

            endpointy = (lkeypoint(body_Relation.endpoint).p.Y / H) * nextframe.Height

            endpoint = New PointF(endpointx, endpointy)

            If lkeypoint(body_Relation.startpoint).conf > 0.15 And lkeypoint(body_Relation.endpoint).conf > 0.15 Then

                CvInvoke.Line(nextframe, PointFToPoint(startpoint), PointFToPoint(endpoint), New MCvScalar(0, 255, 0), 4)

            End If

        Next

        ImageBox1.Image = nextframe

        Threading.Thread.Sleep(30)

End Sub

输出结果如下图所示:

 

图11-11 视频中使用人体关键点连线

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2164313.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AMEYA360代理:兆易创新GD32A7系列全新一代车规级MCU介绍

兆易创新GigaDevice(股票代码 603986)今日宣布&#xff0c;重磅推出全新一代车规级MCU GD32A7系列。与上一代采用Arm Cortex-M4/M33的产品相比&#xff0c;GD32A7系列搭载了超高性能Arm Cortex-M7内核&#xff0c;提供GD32A71x/GD32A72x/GD32A74x等多款型号供用户选择。该系列产…

git 生成和查看密钥

项目场景&#xff1a; 在前端项目开发中&#xff0c;经常会用到git。一般的小公司很少去设置git令牌或者密钥&#xff1b;而在一些大公司&#xff0c;会用到这个。今天主要整理下git如何生成和查看密钥。 密钥 1、生成密钥 cat ~/.ssh/id_rsa.pub 2、查看密钥 ssh-keygen…

电容笔最建议买哪一款?2024百元价位性价比首选榜单,速速码住!

现在电容笔已经成为我们日常学习、工作和创作中不可或缺的辅助工具。无论是记笔记、做习题&#xff0c;还是进行绘画、设计&#xff0c;电容笔都发挥着关键作用。然而&#xff0c;市场上的电容笔品牌和款式繁多&#xff0c;价格也从几十元到上千元不等&#xff0c;这让消费者在…

OSError: [Errno 16] Device or resource busy: ‘.nfs*‘报错解决办法

目录 1 项目场景&问题描述&#xff1a;2 原因分析&#xff1a;2.1 问题背景&#xff1a; 3 解决方案&#xff1a;3.1 创建存放临时文件的目录3.2 使用该目录3.2.1 设置环境变量 TMPDIR3.2.2 运行时设置&#xff08;推荐&#xff09;3.2.3 代码中设置 4 总结 1 项目场景&…

Redis 键值对数据库学习

目录 一、介绍 二、安装以及连接 三、设置连接密码 四、连接报错 五、redis 操作字符串以及过期时间 六、 redis 列表操作 七、redis 集合操作 八、hash 哈希操作 九、redis 发布和订阅操作 十、RDB和AOF的两种数据持久化机制 十一、 其他机器连接redis 十二、 pyt…

【Linux】解锁文件描述符奥秘,高效缓存区的实战技巧

fd和缓冲区 1. 文件描述符fd1.1. 概念与本质1.2. 打开文件的管理1.3. 一切皆文件的理解1.4. 分配规则1.5. 重定向的本质1.5.1. dup2 2. FILE中的缓冲区2.1. 概念2.2. 存在的原因2.3. 类型(刷新方案)2.4. 存放的位置2.4.1. 代码证明、现象解释 2.5. 模拟C标准库中的方法 1. 文件…

LiveGBS流媒体平台GB/T28181功能-支持电子放大拉框放大直播视频拉框放大录像视频流拉框放大电子放大

LiveGBS流媒体平台GB/T28181功能-支持电子放大拉框放大直播视频拉框放大录像视频流拉框放大电子放大 1、直播播放2、录像播放3、搭建GB28181视频直播平台 1、直播播放 国标设备-》查看通道-》播放 &#xff0c;左键单击可以拉取矩形框&#xff0c;放大选中的范围&#xff0c;释…

IPD如何解决产品开发的典型问题

IPD&#xff08;Integrated Product Development&#xff0c;集成产品开发&#xff09;是一种领先的、成熟的产品开发的管理思想和管理模式。它是根据大量成功的产品开发管理实践总结出来的&#xff0c;并被大量实践证明的高效的产品开发模式。从汉捷咨询二十多年来为五百多家企…

如何通过代理使用 Squid: 综合指南

文章目录 一、简介二、什么是 Squid?三、为什么在代理服务器中使用 Squid&#xff1f;四、设置代理五、使用代理设置 Squid5.1. 第一步5.2. 第二步5.3. 第三步 六、在网络搜索中使用代理&#xff1a;实用代码示例6.1. 使用代理的 cURL6.2. 使用代理的 Python 请求 七、结论 一…

嘉立创EDA-- 线宽、过孔和电流大小对比图

导线宽度和电流大小如何来考虑 1 电流大小需要考虑问题 1、允许的温升&#xff1a;如果能够允许的铜线升高的温度越高&#xff0c;那么允许通过的电流自然也就越高 2、走线的线宽&#xff1a;线越宽 &#xff0c;导线横截面积越大&#xff0c;电阻越小&#xff0c;发热越小&a…

磨具生产制造9人共用一台工作站

随着技术的不断进步与工业自动化的深入发展&#xff0c;如何优化生产流程、提高设备利用率成为了众多企业面临的重大课题。那么在磨具生产制造中实现9人共用一台工作站呢&#xff1f; 一、背景与挑战 在磨具制造行业&#xff0c;高精度、高效率的生产要求与复杂多变的工艺流程…

smartctl 命令:查看硬盘健康状态

一、命令简介 ​smartctl​ 命令用于获取硬盘的 SMART 信息。 介绍硬盘SMART 硬盘的 SMART (Self-Monitoring, Analysis, and Reporting Technology) 技术用于监控硬盘的健康状态&#xff0c;并能提供一些潜在故障的预警信息。通过查看 SMART 数据&#xff0c;用户可以了解硬…

如何选择渲染集群管理软件?

选择适合渲染集群管理软件可以考虑以下几个方面&#xff1a; 1.渲染需求&#xff1a;明确自己的渲染任务类型、规模和复杂度。如果需要处理大型、复杂的项目&#xff0c;对渲染效率和速度要求较高&#xff0c;就需要选择性能强劲的软件。 2.软件兼容性&#xff1a;确保软件支持…

[极客大挑战 2019]EasySQL1

前言&#xff1a; 记录一下web方面的题(第一次接触。。。&#xff09; 学校课程要学web…… - - 行吧&#xff0c;尝试一下&#xff0c;至少学过MySQL。。。 不过&#xff0c;实际上&#xff0c;现实现在SQL漏洞少得可怜&#xff0c;但学习不会有错。 参考&#xff1a;&…

vue-cli,element-plus,axios,proxy

一、vue-cli vue-cli俗称vue脚手架&#xff0c;是vue官方提供的快速生成vue 工程化项目的工具。 1.官网&#xff1a;https://cn.vuejs.org/ 中文官网: https://cli.vuejs.org/zh/ 特点&#xff1a;基于webpack&#xff0c;功能丰富且易于扩展&#xff0c;支持创建vue2和vu…

学校快递站点管理|基于springboot学校快递站点管理设计与实现(源码+数据库+文档)

学校快递站点管理系统目录 目录 基于springboot学校快递站点管理设计与实现 一、前言 二、系统功能设计 三、系统实现 前台功能模块 后台功能角模块 四、数据库设计 1、实体ER图 2、具体的表设计如下所示&#xff1a; 五、核心代码 六、论文参考 七、最新计算机毕设…

本地搭建OnlyOffice在线文档编辑器结合内网穿透实现远程协作

文章目录 前言1. 安装Docker2. 本地安装部署ONLYOFFICE3. 安装cpolar内网穿透4. 固定OnlyOffice公网地址 前言 本篇文章讲解如何使用Docker在本地Linux服务器上安装ONLYOFFICE&#xff0c;并结合cpolar内网穿透实现公网访问本地部署的文档编辑器与远程协作。 Community Editi…

LVM的基本概念,PD PP PV VG LV PE等概念

LVM&#xff08;Logical Volume Manager&#xff0c;逻辑卷管理器&#xff09;是 Linux 系统中一种灵活的磁盘分区管理工具&#xff0c;允许动态地调整存储设备的大小和配置&#xff0c;而无需停止系统。LVM 在传统的分区管理工具上添加了更灵活的管理功能&#xff0c;特别适合…

逆向推理+ChatGPT,让论文更具说服力

学境思源&#xff0c;一键生成论文初稿&#xff1a; AcademicIdeas - 学境思源AI论文写作 使用ChatGPT辅助“逆向推理”技巧&#xff0c;可以显著提升论文的质量和说服力。逆向推理从结论出发&#xff0c;倒推所需的证据和论点&#xff0c;确保整个论证过程逻辑严密且无漏洞。…

Linux快速安装ClickHouse(附官方文档)

在线安装 1.安装yum-utils yum-utils是一个与 yum 集成的实用程序集合&#xff0c;可以通过多种方式扩展其本机功能 yum install -y yum-utils 2.增加ClickHouse官方镜像源 yum-config-manager --add-repo https://packages.clickhouse.com/rpm/clickhouse.repo 3.安装Cl…