[C#]基于opencvsharp实现15关键点人体姿态估计

news2024/12/23 20:46:59

数据集

正确选择数据集以对结果产生适当影响也是非常必要的。在此姿势检测中,模型在两个不同的数据集即COCO关键点数据集和MPII人类姿势数据集上进行了预训练。

1. COCO:COCO关键点数据集是一个多人2D姿势估计数据集,其中包含从Flickr收集的图像。迄今为止,COCO是最大的2D姿势估计数据集,并被视为测试2D姿势估计算法的基准。COCO模型有18种分类。COCO输出格式:鼻子— 0,脖子—1,右肩—2,右肘—3,右手腕—4,左肩—5,左手肘—6,左手腕—7,右臀部—8,右膝盖—9,右脚踝—10,左臀部—11,左膝—12,左脚踝—13,右眼—14,左眼—15,右耳—16,左耳—17,背景—18

2. MPII:MPII人体姿势数据集是一个多人2D姿势估计数据集,包含从Youtube视频中收集的近500种不同的人类活动。MPII是第一个包含各种姿势范围的数据集,也是第一个在2014年发起2D姿势估计挑战的数据集。MPII模型输出15分。MPII输出格式:头—0,脖子—1,右肩—2,右肘—3,右腕—4,左肩—5,左肘—6,左腕—7,右臀部—8,右膝盖—9,右脚踝—10,左臀部—11,左膝盖—12,左脚踝—13,胸部—14,背景—15

这些点是在对数据集进行处理并通过卷积神经网络(CNN)进行全面训练时生成的。

具体步骤

步骤1:需求收集(模型权重)和负载网络

训练有素的模型需要加载到OpenCV中。这些模型在Caffe深度学习框架上进行了训练。Caffe模型包含两个文件,即.prototxt文件和.caffemodel文件。

  1. .prototxt文件指定了神经网络的体系结构。
  2. .caffemodel文件存储训练后的模型的权重。

然后我们将这两个文件加载到网络中。

1

2

3

4

5

# Specify the paths for the 2 files

protoFile = "pose/mpi/pose_deploy_linevec_faster_4_stages.prototxt"

weightsFile = "pose/mpi/pose_iter_160000.caffemodel"

# Read the network into Memory

net = cv2.dnn.readNetFromCaffe(protoFile, weightsFile)

步骤2:读取图像并准备输入网络

首先,我们需要使用blobFromImage函数将图像从OpenCV格式转换为Caffe blob格式,以便可以将其作为输入输入到网络。这些参数将在blobFromImage函数中提供。由于OpenCV和Caffe都使用BGR格式,因此无需交换R和B通道。

1

2

3

4

5

6

7

8

9

# Read image

frame = cv2.imread("image.jpg")

# Specify the input image dimensions

inWidth = 368

inHeight = 368

# Prepare the frame to be fed to the network

inpBlob = cv2.dnn.blobFromImage(frame, 1.0 / 255, (inWidth, inHeight), (0, 0, 0), swapRB=False, crop=False)

# Set the prepared object as the input blob of the network

net.setInput(inpBlob)

步骤3:做出预测并解析关键点

一旦将图像传递到模型,就可以使用OpenCV中DNN类的正向方法进行预测,该方法通过网络进行正向传递,这只是说它正在进行预测的另一种方式。

1

output = net.forward()

输出为4D矩阵:

  1. 第一个维度是图片ID(如果您将多个图片传递到网络)。
  2. 第二个维度指示关键点的索引。该模型会生成置信度图(在图像上的概率分布,表示每个像素处关节位置的置信度)和所有已连接的零件亲和度图。对于COCO模型,它由57个部分组成-18个关键点置信度图+ 1个背景+ 19 * 2个部分亲和度图。同样,对于MPI,它会产生44点。我们将仅使用与关键点相对应的前几个点。
  3. 第三维是输出图的高度。
  4. 第四个维度是输出图的宽度。

然后,我们检查图像中是否存在每个关键点。我们通过找到关键点的置信度图的最大值来获得关键点的位置。我们还使用阈值来减少错误检测。

置信度图

一旦检测到关键点,我们便将其绘制在图像上。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

H = out.shape[2]

W = out.shape[3]

# Empty list to store the detected keypoints

points = []

for i in range(len()):

# confidence map of corresponding body's part.

    probMap = output[0, i, :, :]

# Find global maxima of the probMap.

    minVal, prob, minLoc, point = cv2.minMaxLoc(probMap)

# Scale the point to fit on the original image

x = (frameWidth * point[0]) / W

y = (frameHeight * point[1]) / H

if prob > threshold :

        cv2.circle(frame, (int(x), int(y)), 15, (0, 255, 255), thickness=-1, lineType=cv.FILLED)

        cv2.putText(frame, "{}".format(i), (int(x), int(y)), cv2.FONT_HERSHEY_SIMPLEX, 1.4, (0, 0, 255), 3, lineType=cv2.LINE_AA)

# Add the point to the list if the probability is greater than the threshold

        points.append((int(x), int(y)))

else :

        points.append(None)

cv2.imshow("Output-Keypoints",frame)

cv2.waitKey(0)

cv2.destroyAllWindows()

步骤4:绘制骨架

由于我们已经绘制了关键点,因此我们现在只需将两对连接即可绘制骨架。

1

2

3

4

5

for pair in POSE_PAIRS:

partA = pair[0]

partB = pair[1]

if points[partA] and points[partB]:

cv2.line(frameCopy, points[partA], points[partB], (0, 255, 0), 3)

结果

上面显示的输出向我们显示了运动员在特定时刻的准确姿势。下面是视频的检测结果。

【界面展示】

【效果演示】

【部分实现源码】

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using OpenCvSharp;

namespace FIRC
{
    public partial class Form1 : Form
    {
        Mat src = new Mat();
        PoseManager detector = new PoseManager(Application.StartupPath+ "\\weights\\pose_deploy_linevec_faster_4_stages.prototxt", Application.StartupPath + "\\weights\\pose_iter_160000.caffemodel");
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "图文件(*.*)|*.jpg;*.png;*.jpeg;*.bmp";
            openFileDialog.RestoreDirectory = true;
            openFileDialog.Multiselect = false;
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
              
                src = Cv2.ImRead(openFileDialog.FileName);
                pictureBox1.Image = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(src);


            }


        }

        private void button2_Click(object sender, EventArgs e)
        {
            if(pictureBox1.Image==null)
            {
                return;
            }
            var resultMat = detector.Inference(src);
            pictureBox2.Image= OpenCvSharp.Extensions.BitmapConverter.ToBitmap(resultMat); //Mat转Bitmap
        }

        private void Form1_Load(object sender, EventArgs e)
        {
          
        }

        private void button3_Click(object sender, EventArgs e)
        {
            VideoCapture capture = new VideoCapture("test.mp4");
            if (!capture.IsOpened())
            {
                Console.WriteLine("video not open!");
                return;
            }
            Mat frame = new Mat();
            var sw = new Stopwatch();
            int fps = 0;
            while (true)
            {

                capture.Read(frame);
                if (frame.Empty())
                {
                    Console.WriteLine("data is empty!");
                    break;
                }
                sw.Start();
                var result = detector.Inference(frame);
                sw.Stop();
                fps = Convert.ToInt32(1 / sw.Elapsed.TotalSeconds);
                sw.Reset();
                Cv2.PutText(result, "FPS=" + fps, new OpenCvSharp.Point(30, 30), HersheyFonts.HersheyComplex, 1.0, new Scalar(255, 0, 0), 3);
                //显示结果
                Cv2.ImShow("Result", result);
                int key = Cv2.WaitKey(10);
                if (key == 27)
                    break;
            }

            capture.Release();
        }
    }
}

【视频演示】

C# winform基于opencvsharp实现15关键点人体姿态估计_哔哩哔哩_bilibili【测试环境】vs2019netfframework4.7.2opencvsharp4.8.0【演示源码下载】【注意事项】源码演示只支持单人姿态估计,不支持一个图片多人姿态估计,如果需要支持多人姿态估计可以先检测出人,然后截取出来进行单人估计即可更多信息参考博文:https://blog.csdn.net/FL1623863129/article/details/140002519, 视频播放量 1、弹幕量 0、点赞数 0、投硬币枚数 0、收藏人数 0、转发人数 0, 视频作者 未来自主研究中心, 作者简介 未来自主研究中心,相关视频:Python自动化脚本,Python训练AI自动玩王者荣耀,简直不要太秀!!!,yolov9+deepsort+pyqt5实现目标追踪结果演示,将yolov5-6.2封装成一个类几行代码完成语义分割任务,基于onnx模型加密与解密深度学习模型保护方法介绍,C# OpenCvSharp Yolov8 Face Landmarks 人脸五点关键点检测,C++使用纯opencv去部署yolov8官方obb旋转框检测,基于yolov8+bytetrack实现目标追踪视频演示,使用C++部署yolov8的onnx和bytetrack实现目标追踪,C#实现全网yolov7目前最快winform目标检测,C#使用opencvsharp进行年龄和性别预测支持视频图片检测icon-default.png?t=N7T8https://www.bilibili.com/video/BV1m1421C7So/?vd_source=989ae2b903ea1b5acebbe2c4c4a635ee 

【测试环境】

vs2019

netframework4.7.2

opencvsharp4.8.0

【演示源码下载】

https://download.csdn.net/download/FL1623863129/89486922

【注意事项】

源码演示只支持单人姿态估计,不支持一个图片多人姿态估计,如果需要支持多人姿态估计可以先检测出人,然后截取出来进行单人估计即可

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

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

相关文章

matlab绘制二维曲线,如何设置线型、颜色、标记点类型、如何设置坐标轴、matlab 图表标注、在图中标记想要的点

matlab绘制二维曲线,如何设置线型、颜色、标记点类型、如何设置坐标轴、matlab 图表如何标注、如何在图中标记想要的点 matlab绘制二维曲线,如何在图中标记想要的点。。。如何设置线型、颜色、标记点类型。。。如何设置坐标轴。。。matlab 图表标注操作…

头歌资源库(18)接龙序列

一、 问题描述 二、算法思想 首先,我们需要判断一个数列是否是接龙数列。可以通过遍历数列的每一个元素,判断该元素的首位数字是否等于前一个元素的末位数字。如果所有元素都满足条件,则该数列是接龙数列。 接下来,我们需要计算…

Java | Leetcode Java题解之第201题数字范围按位与

题目&#xff1a; 题解&#xff1a; class Solution {public int rangeBitwiseAnd(int m, int n) {while (m < n) {// 抹去最右边的 1n n & (n - 1);}return n;} }

Java | Leetcode Java题解之第202题快乐数

题目&#xff1a; 题解&#xff1a; class Solution {private static Set<Integer> cycleMembers new HashSet<>(Arrays.asList(4, 16, 37, 58, 89, 145, 42, 20));public int getNext(int n) {int totalSum 0;while (n > 0) {int d n % 10;n n / 10;totalS…

在eclipse中导入idea项目步骤

一、可以把其它项目的.project&#xff0c; .classpath文件拷贝过来&#xff0c;修改相应的地方则可。 1、.project文件只需要修改<name>xxx</name>这个项目名称则可 2、.classpath文件通常不用改&#xff0c; 二、右击 项目名 >选择“Properties”>选择 Re…

【2024-热-办公软件】ONLYOFFICE8.1版本桌面编辑器测评

在今日快速发展的数字化办公环境中&#xff0c;选择一个功能全面且高效的办公软件是至关重要的。最近&#xff0c;我有幸体验了ONLYOFFICE 8.1版本的桌面编辑器&#xff0c;这款软件不仅提供了强大的编辑功能&#xff0c;还拥有众多改进&#xff0c;让办公更加流畅和高效。在本…

C++ | Leetcode C++题解之第202题快乐数

题目&#xff1a; 题解&#xff1a; class Solution { public:int ProductSum(int n){int sum 0;while(n){int temp n % 10;sum temp*temp;n / 10;}return sum;}bool isHappy(int n) {int slow n,fast n;// 快慢指针&#xff0c;找环的相遇位置do{slow ProductSum(slow)…

58.鸿蒙系统app(HarmonyOS)(ArkUI)更改应用程序图标

替换xx\MyApplication4.30\entry\src\main\resources\base\media目录下icon.png文件 54.HarmonyOS鸿蒙系统 App(ArkTS)tcp socket套接字网络连接收发测试_鸿蒙socket连接测试-CSDN博客

Vuetify3:​快捷回到顶部

在Vuetify 3中&#xff0c;要实现回到顶部&#xff0c;我们需要创建悬浮按钮&#xff0c;如下&#xff1a; <template><v-list><div class"position-fixed right-0 bottom-0" style"top:50%;"><v-list-item ><v-btn icon"…

第十节 动态面板实现推动和拉动效果

在原型设计中我们经常会遇到元件使用显示更多或者收起效果&#xff0c;下面以面板元件推动与拉动效果做案件说明。 一、设置原有内容 我这里添加一个表格内容&#xff0c;添加“显示更多”文本超链接 二、设置在更多显示面板内容 添加一个动态面板&#xff0c;设置有内容、无…

Linux运维:MySQL数据库(1)

1.信息与数据&#xff1a; 数据是信息的载体&#xff0c;信息是数据的内涵。数据库就是存储数据的仓库&#xff0c;并长期存储在计算机磁盘中&#xff0c;可由多个用户和应用程序共享的数据集合&#xff0c;就是数据库。 2.数据库中的数据的特点&#xff1a; 2.1.数据是按照某…

【Docker】创建 swarm 集群

目录 1. 更改防火墙设置 2. 安装 Docker 组件 3. 启动 Docker 服务&#xff0c;并检查服务状态。 4. 修改配置文件&#xff0c;监听同一端口号。 5. 下载 Swarm 组件 6. 创建集群&#xff0c;加入节点 7. 启动集群 8. 查询集群节点信息 9. 查询集群具体信息 10. 查询…

vscode 安装Vue插件

打开扩展面板 --> 点击左侧的扩展图标&#xff0c;或者按下快捷键 Ctrl Shift X 搜索插件,在搜索框中输入 Vue vue-helper 用来快捷提示&#xff0c;如果使用elementui的话&#xff0c;插件不会自动提示&#xff0c;安装了它&#xff0c;组件、属性都会有提示了 Vetur V…

live555的核心数据结构值之闭环双向链表

live555是采用单进程,单线程的服务器,能够同时支持多个客户端连接,并且有条不紊的进行媒体流的调度,很大一部分原因在于对数据结构的巧妙应用。 下面介绍live555核心的数据结构:闭环双向链表 什么是闭环双向链表? 描述: 一个节点保存有前一个节点的地址和后一个节点的…

Spring自带的持久层模板类:JdbcTemplate+Spring框架声明式事务管理实战

模板技术 Spring框架中提供了很多模板类来简化编程&#xff0c;使用模板类编写程序会变的简单 持久层模板JdbcTemplate JdbcTemplate是什么 JDBCTemplate是Spring Framework中的一个核心类&#xff0c;用于简化JDBC&#xff08;Java数据库连接&#xff09;代码的编写。它提供…

4A的「A」会变成AI的「A」吗?

戛纳国际创意节上&#xff0c;广告集团WPP的全球CEO Mark Read 和英国CEO Karen Blackett 解释了WPP如何应对AIGC所带来的「威胁」。同时&#xff0c;Mark Read 与Elon Musk对话&#xff0c;讨论「技术创新的变革力量&#xff0c;人工智能如何重塑创造力、商业和社会&#xff0…

基于uni-app与图鸟UI的移动应用模板构建研究

摘要 随着移动互联网技术的迅猛发展&#xff0c;移动端应用已成为企业展示形象、提供服务的重要窗口。本文基于uni-app框架和图鸟UI设计&#xff0c;深入探讨了如何高效构建覆盖多个领域的移动端应用模板。通过对商城、办公、投票、生活服务等多种类型模板的详细介绍&#xff…

使用uniapp.pageScrollTo方法进行页面滚动

先看看是不是你想要的&#xff1a; 需求&#xff1a; 有个填写数据的单子在提交的时候&#xff0c;会对必填项做校验&#xff0c;如果必填项没有数据的话&#xff0c;必填项校验生效给出提示&#xff0c;并且页面滚动到第一个需要填写数据的地方。 开发&#xff1a; 因为这个…

Ubuntu无法安全地用该源进行更新,所以默认禁用该源。

解决方案 1. 获取并添加缺失的 GPG 公钥 可以使用 apt-key 命令来添加缺失的公钥。根据错误信息&#xff0c;缺失的公钥是 3B4FE6ACC0B21F32。 sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3B4FE6ACC0B21F322. 更新软件包列表 添加公钥后&#xff0c;更…

[Go Web] Kratos 验证码业务

文章目录 1.环境准备2.验证码服务2.1 kratos 初始化验证码服务项目2.2 使用 Protobuf 定义验证码生成接口2.3 业务逻辑代码实现 1.环境准备 protoc和protoc-gen-go插件安装和kratos工具安装 protoc下载 下载二进制文件&#xff1a;https://github.com/protocolbuffers/protobu…