使用kinect2.0做动作识别和动作计数

article/2025/10/16 6:12:13

利用kinect2结构光相机进行运动动作识别和运动计数,不仅可以测量运动人员的卡路里,也可以测出运动速度和做功,并对于运动的动作做出科学规范的指导。

这里我们选用kinect2和windows系统作为开发工具来进行开发。如果要进行运动动作的识别,第一步需要对于采集运动的信息,比如人体的骨骼关键点信息,这里我们以手为采集对象,同时判断手是否有抓握杆的行为来进行运动的信息采集。同时我们这里以深蹲作为示范,举例如何进行运动动作的判定和计数。
人体关键点的效果如图所示
在这里插入图片描述

通过kinect2提供的接口,我们可以获取到人体各个骨骼关节点的三维信息

这里我把windows下获取人体骨骼关节点的信息的代码放在这里

//这里是.h文件
#ifndef __APP__
#define __APP__#include <Windows.h>
#include <Kinect.h>
#include <opencv2/opencv.hpp>#include <vector>
#include <array>#include <wrl/client.h>
using namespace Microsoft::WRL;class Kinect
{
private:// SensorComPtr<IKinectSensor> kinect;// Coordinate MapperComPtr<ICoordinateMapper> coordinateMapper;// ReaderComPtr<IColorFrameReader> colorFrameReader;ComPtr<IBodyFrameReader> bodyFrameReader;// Color Bufferstd::vector<BYTE> colorBuffer;int colorWidth;int colorHeight;unsigned int colorBytesPerPixel;cv::Mat colorMat;// Body Bufferstd::array<IBody*, BODY_COUNT> bodies = { nullptr };std::array<cv::Vec3b, BODY_COUNT> colors;public:// ConstructorKinect();// Destructor~Kinect();// Processingvoid run();private:// Initializevoid initialize();// Initialize Sensorinline void initializeSensor();// Initialize Colorinline void initializeColor();// Initialize Bodyinline void initializeBody();// Finalizevoid finalize();// Update Datavoid update();// Update Colorinline void updateColor();// Update Bodyinline void updateBody();// Draw Datavoid draw();// Draw Colorinline void drawColor();// Draw Bodyinline void drawBody();// Draw Circleinline void drawEllipse( cv::Mat& image, const Joint& joint, const int radius, const cv::Vec3b& color, const int thickness = -1 );// Draw Hand Stateinline void drawHandState( cv::Mat& image, const Joint& joint, HandState handState, TrackingConfidence handConfidence );// Show Datavoid show();// Show Bodyinline void showBody();
};#endif // __APP__
//这里是cpp文件
#include "app.h"
#include "util.h"#include <thread>
#include <chrono>#include <ppl.h>// Constructor
Kinect::Kinect()
{// Initializeinitialize();
}// Destructor
Kinect::~Kinect()
{// Finalizefinalize();
}// Processing
void Kinect::run()
{// Main Loopwhile( true ){// Update Dataupdate();// Draw Datadraw();// Show Datashow();// Key Checkconst int key = cv::waitKey( 10 );if( key == VK_ESCAPE ){break;}}
}// Initialize
void Kinect::initialize()
{cv::setUseOptimized( true );// Initialize SensorinitializeSensor();// Initialize ColorinitializeColor();// Initialize BodyinitializeBody();// Wait a Few Seconds until begins to Retrieve Data from Sensor ( about 2000-[ms] )std::this_thread::sleep_for( std::chrono::seconds( 2 ) );
}// Initialize Sensor
inline void Kinect::initializeSensor()
{// Open SensorERROR_CHECK( GetDefaultKinectSensor( &kinect ) );ERROR_CHECK( kinect->Open() );// Check OpenBOOLEAN isOpen = FALSE;ERROR_CHECK( kinect->get_IsOpen( &isOpen ) );if( !isOpen ){throw std::runtime_error( "failed IKinectSensor::get_IsOpen( &isOpen )" );}// Retrieve Coordinate MapperERROR_CHECK( kinect->get_CoordinateMapper( &coordinateMapper ) );
}// Initialize Color
inline void Kinect::initializeColor()
{// Open Color ReaderComPtr<IColorFrameSource> colorFrameSource;ERROR_CHECK( kinect->get_ColorFrameSource( &colorFrameSource ) );ERROR_CHECK( colorFrameSource->OpenReader( &colorFrameReader ) );// Retrieve Color DescriptionComPtr<IFrameDescription> colorFrameDescription;ERROR_CHECK( colorFrameSource->CreateFrameDescription( ColorImageFormat::ColorImageFormat_Bgra, &colorFrameDescription ) );ERROR_CHECK( colorFrameDescription->get_Width( &colorWidth ) ); // 1920ERROR_CHECK( colorFrameDescription->get_Height( &colorHeight ) ); // 1080ERROR_CHECK( colorFrameDescription->get_BytesPerPixel( &colorBytesPerPixel ) ); // 4// Allocation Color BuffercolorBuffer.resize( colorWidth * colorHeight * colorBytesPerPixel );
}// Initialize Body
inline void Kinect::initializeBody()
{// Open Body ReaderComPtr<IBodyFrameSource> bodyFrameSource;ERROR_CHECK( kinect->get_BodyFrameSource( &bodyFrameSource ) );ERROR_CHECK( bodyFrameSource->OpenReader( &bodyFrameReader ) );// Initialize Body BufferConcurrency::parallel_for_each( bodies.begin(), bodies.end(), []( IBody*& body ){SafeRelease( body );} );// Color Table for Visualizationcolors[0] = cv::Vec3b( 255,   0,   0 ); // Bluecolors[1] = cv::Vec3b(   0, 255,   0 ); // Greencolors[2] = cv::Vec3b(   0,   0, 255 ); // Redcolors[3] = cv::Vec3b( 255, 255,   0 ); // Cyancolors[4] = cv::Vec3b( 255,   0, 255 ); // Magentacolors[5] = cv::Vec3b(   0, 255, 255 ); // Yellow
}// Finalize
void Kinect::finalize()
{cv::destroyAllWindows();// Release Body BufferConcurrency::parallel_for_each( bodies.begin(), bodies.end(), []( IBody*& body ){SafeRelease( body );} );// Close Sensorif( kinect != nullptr ){kinect->Close();}
}// Update Data
void Kinect::update()
{// Update ColorupdateColor();// Update BodyupdateBody();
}// Update Color
inline void Kinect::updateColor()
{// Retrieve Color FrameComPtr<IColorFrame> colorFrame;const HRESULT ret = colorFrameReader->AcquireLatestFrame( &colorFrame );if( FAILED( ret ) ){return;}// Convert Format ( YUY2 -> BGRA )ERROR_CHECK( colorFrame->CopyConvertedFrameDataToArray( static_cast<UINT>( colorBuffer.size() ), &colorBuffer[0], ColorImageFormat::ColorImageFormat_Bgra ) );
}// Update Body
inline void Kinect::updateBody()
{// Retrieve Body FrameComPtr<IBodyFrame> bodyFrame;const HRESULT ret = bodyFrameReader->AcquireLatestFrame( &bodyFrame );if( FAILED( ret ) ){return;}// Release Previous BodiesConcurrency::parallel_for_each( bodies.begin(), bodies.end(), []( IBody*& body ){SafeRelease( body );} );// Retrieve Body DataERROR_CHECK( bodyFrame->GetAndRefreshBodyData( static_cast<UINT>( bodies.size() ), &bodies[0] ) );
}// Draw Datax
void Kinect::draw()
{// Draw ColordrawColor();// Draw BodydrawBody();
}// Draw Color
inline void Kinect::drawColor()
{// Create cv::Mat from Color BuffercolorMat = cv::Mat( colorHeight, colorWidth, CV_8UC4, &colorBuffer[0] );
}// Draw Body
inline void Kinect::drawBody()
{// Draw Body Data to Color DataConcurrency::parallel_for( 0, BODY_COUNT, [&]( const int count ){const ComPtr<IBody> body = bodies[count];if( body == nullptr ){return;}// Check Body TrackedBOOLEAN tracked = FALSE;ERROR_CHECK( body->get_IsTracked( &tracked ) );if( !tracked ){return;}// Retrieve Jointsstd::array<Joint, JointType::JointType_Count> joints;ERROR_CHECK( body->GetJoints( static_cast<UINT>( joints.size() ), &joints[0] ) );Concurrency::parallel_for_each( joints.begin(), joints.end(), [&]( const Joint& joint ){// Check Joint Trackedif( joint.TrackingState == TrackingState::TrackingState_NotTracked ){return;}// Draw Joint PositiondrawEllipse( colorMat, joint, 5, colors[count] );// Draw Left Hand Stateif( joint.JointType == JointType::JointType_HandLeft ){HandState handState;TrackingConfidence handConfidence;ERROR_CHECK( body->get_HandLeftState( &handState ) );ERROR_CHECK( body->get_HandLeftConfidence( &handConfidence ) );drawHandState( colorMat, joint, handState, handConfidence );}// Draw Right Hand Stateif( joint.JointType == JointType::JointType_HandRight ){HandState handState;TrackingConfidence handConfidence;ERROR_CHECK( body->get_HandRightState( &handState ) );ERROR_CHECK( body->get_HandRightConfidence( &handConfidence ) );drawHandState( colorMat, joint, handState, handConfidence );}} );/*// Retrieve Joint Orientationsstd::array<JointOrientation, JointType::JointType_Count> orientations;ERROR_CHECK( body->GetJointOrientations( JointType::JointType_Count, &orientations[0] ) );*//*// Retrieve Amount of Body LeanPointF amount;ERROR_CHECK( body->get_Lean( &amount ) );*/} );
}// Draw Ellipse
inline void Kinect::drawEllipse( cv::Mat& image, const Joint& joint, const int radius, const cv::Vec3b& color, const int thickness )
{if( image.empty() ){return;}// Convert Coordinate System and Draw JointColorSpacePoint colorSpacePoint;ERROR_CHECK( coordinateMapper->MapCameraPointToColorSpace( joint.Position, &colorSpacePoint ) );const int x = static_cast<int>( colorSpacePoint.X + 0.5f );const int y = static_cast<int>( colorSpacePoint.Y + 0.5f );if( ( 0 <= x ) && ( x < image.cols ) && ( 0 <= y ) && ( y < image.rows ) ){cv::circle( image, cv::Point( x, y ), radius, static_cast<cv::Scalar>( color ), thickness, cv::LINE_AA );}
}// Draw Hand State
inline void Kinect::drawHandState( cv::Mat& image, const Joint& joint, HandState handState, TrackingConfidence handConfidence )
{if( image.empty() ){return;}// Check Tracking Confidenceif( handConfidence != TrackingConfidence::TrackingConfidence_High ){return;}// Draw Hand State const int radius = 75;const cv::Vec3b blue = cv::Vec3b( 128, 0, 0 ), green = cv::Vec3b( 0, 128, 0 ), red = cv::Vec3b( 0, 0, 128 );switch( handState ){// Opencase HandState::HandState_Open:drawEllipse( image, joint, radius, green, 5 );break;// Closecase HandState::HandState_Closed:drawEllipse( image, joint, radius, red, 5 );break;// Lassocase HandState::HandState_Lasso:drawEllipse( image, joint, radius, blue, 5 );break;default:break;}
}// Show Data
void Kinect::show()
{// Show BodyshowBody();
}// Show Body
inline void Kinect::showBody()
{if( colorMat.empty() ){return;}// Resize Imagecv::Mat resizeMat;const double scale = 0.5;cv::resize( colorMat, resizeMat, cv::Size(), scale, scale );// Show Imagecv::imshow( "Body", resizeMat );
}
//main函数
#include <iostream>
#include <sstream>#include "app.h"int main( int argc, char* argv[] )
{try{Kinect kinect;kinect.run();} catch( std::exception& ex ){std::cout << ex.what() << std::endl;}return 0;
}
//util.h文件
#ifndef __UTIL__
#define __UTIL__#include <sstream>
#include <stdexcept>// Error Check Macro
#define ERROR_CHECK( ret )                                        \if( FAILED( ret ) ){                                          \std::stringstream ss;                                     \ss << "failed " #ret " " << std::hex << ret << std::endl; \throw std::runtime_error( ss.str().c_str() );             \}// Safe Release
template<class T>
inline void SafeRelease( T*& rel )
{if( rel != NULL ){rel->Release();rel = NULL;}
}// C++ Style Line Types For OpenCV 2.x
#if ( CV_MAJOR_VERSION < 3 )
namespace cv{enum LineTypes{FILLED  = -1,LINE_4  = 4,LINE_8  = 8,LINE_AA = 16};
}
#endif#endif // __UTIL__

下面我们就以这两份开源代码作为基础的开发版本,演示如何开发智能运动计数和动作识别的代码
首先,我们需要训练一个极快速度的识别模型,用于识别手是否有握杆的行为,这里我们选用caffe版本的squeezeNet作为训练的模型,具体教程网上很多,我们这里就用猫狗分类的模型,具体的地址在这里
超轻量级模型地址
使用这个模型在鉴黄的图片上速度能够达到200fps以上。利用kinect2的手部信息,对于彩色图像进行一定范围的截图,自己采集一些握杆和不握杆的图片,数量大概在6000张左右,正负样本各3000张。整合完成后识别率大概是98%左右。
在这里插入图片描述
通过采集kinect2的手部骨骼关键点信息,同时利用手是否握杆来判定,就可以进行数据的处理了。
需要对于采集到数据进行深度值回归和综合滤波以后,我们把处理过的数据放在json文件中留用,再利用python代码将数据展示出来,如图所示
在这里插入图片描述
这里是我们采集到的20组深蹲的手部骨骼关键点的坐标信息
接下来就是如何计数的问题了,这里我们采用一阶导数和二阶导数相结合的方式,同时利用三次样条插值补足缺失的移动轨迹来进行计数。具体效果如图所示。
在这里插入图片描述
在这里插入图片描述
这样子我们就能对于运动动作进行捕捉了。具体效果可以参考eliteform的使用效果
视频点击
相关产品见舒华8902I速度与力量反馈系统
在这里插入图片描述


http://chatgpt.dhexx.cn/article/yIkRJWeJ.shtml

相关文章

基于Detectron2和LSTM的人体动作识别

人体动作识别通过分析视频来预测或分类视频中人物的各种动作。它被广泛应用于监测、体育、健身、防御等各个领域。 假设你想创建一个在线教授瑜伽的应用程序。它应该提供一个预先录制的瑜伽视频列表供用户观看。用户在应用程序上观看视频后&#xff0c;可以上传自己的个人练习…

短视频动作识别技术简述

1总体介绍 短视频在当前多媒体环境中占据着巨大流量&#xff0c;有效理解视频内容对于数据分发发挥着重要作用&#xff0c;动作识别是视频内容理解的一个重要方向。当前图像识别技术已趋于成熟&#xff0c;但动作识别仍未达到理想效果&#xff0c;相比于图像识别&#xff0c;动…

动作识别01:Understanding action recognition in still images

文章目录 摘要一、引言二、相关工作三、实验3.1 定义交互功能 四、结果总结 摘要 静止图像中的动作识别与姿态估计、目标识别、图像检索、视频动作识别和视频帧标记等计算机视觉任务密切相关。这个问题的重点是用单一的框架识别一个人的动作或行为。与视频中的动作识别不同——…

mediapipe 实现动作识别

环境 windows 10 64bitmediapipe 0.8.10.1 前言 本文使用 google 家的 mediapipe 机器学习框架&#xff0c;结合 opencv 和 numpy&#xff0c;实现了一个实时识别 站立、坐下、走动、挥手 共4个动作的简单系统。 mediapipe 能做的事情非常多&#xff0c;感兴趣的童鞋可以去研究…

行为动作识别

一、跌倒检测数据集 随着计算机学科与人工智能的发展和应用&#xff0c;视频分析技术迅速兴起并得到了广泛关注。视频分析中的一个核心就是人体行为识别&#xff0c;行为识别的准确性和快速性将直接影响视频分析系统后续工作的结果。因此&#xff0c;如何提高视频中人体行为识别…

基于骨骼的动作识别:PoseConv3D

Revisiting Skeleton-based Action Recognition解读 摘要1. 简介2. Related Work2.1 基于3D-CNN的rgb视频动作识别2.2 基于GCN的骨骼动作识别2.3 基于CNN的骨骼动作识别 3. Framework3.1 Pose Extraction3.2 From 2D Poses to 3D Heatmap Volumes3.3 基于骨骼的动作识别3D-CNN3…

视频动作识别调研(Action Recognition)

视频动作识别调研&#xff08;Action Recognition&#xff09; 本文首发于微信公众号“ StrongerTang”&#xff0c;可打开微信搜一搜&#xff0c;或扫描文末二维码&#xff0c;关注查看更多文章。 原文链接&#xff1a;( https://mp.weixin.qq.com/s?__bizMzg3NDEzOTAzMw&…

动作识别概况

文章目录 一、动作识别二、动作识别的难点三、动作识别现在常用的方法四、行为识别的两个方向五、常用数据集六、常用框架介绍 一、动作识别 主要目标是判断一段视频中人的行为的类别&#xff0c;所以也可以叫做 Human Action Recognition。 二、动作识别的难点 1.类内和类之…

动作/行为识别调研

动作识别调研 1. 简介1.1 基本概念1.2 难点 2. 人体动作识别系统2.1 传统方法2.1.1 iDT框架 2.2 深度学习方法2.2.1 Two-Stream双流架构2.2.2 3D卷积架构2.2.3 CNNLSTM架构2.2.4 GCN架构 相关文献 1. 简介 动作识别(Action Recognition)&#xff0c;就是从视频片段&#xff08…

2022广州大学计算机网络实验--使用网络协议分析器捕捉和分析协议数据包

广州大学学生实验报告 开课学院及实验室&#xff1a;计算机科学与工程实验室 2022年**月**日 学院 计算机科学与教育软件 年级、专业、班 ****** 姓名 **** 学号 *******39 实验课程名称 计算机网络实验 成绩 实验项目名称 使用网络协议分析器…

五个好用的网络协议分析工具(附下载地址)

Network Packet Analyzer&#xff0c;是一种网络分析程序&#xff0c;可以帮助网络管理员捕获、交互式浏览网络中传输的数据包和分析数据包信息等。这里给出了5个最好的网络数据包分析工具&#xff0c;具体如下&#xff1a; 1. Wireshark 相信大家都很熟悉&#xff0c;就不多…

网络协议安全分析

网络安全层次结构 物理层 在通信线路上保障不被搭线&#xff0c;不被偷听&#xff0c;尽可能检测出来。 数据链路层 a.点对点的链路上可以采用通信保密机进行加解密。 b.由第层硬件完成&#xff0c;对上层透明。 c.缺陷&#xff1a;无法适应多个路由器的网络&#xff0c;尤其I…

各网络协议分析

IP ip头 ![Image][IPstr] Wireshark ![Image][IPstr2] 名称值含义可选值占位IP版本0100IPV40110:IPV64bit头部长度010120bytes(5)可表示的最大值为1111(60bytes(15))4bit服务类型0x00默认转发(DF)8bit总长度52首部和数据之和最大为2^16-165535字节16bit标识0x239d它是一个…

网络协议分析(结合版)

初识协议 1.什么是协议&#xff1f; 数据从源地点传输到目的地点&#xff0c;网络上所有设备需要“讲”相同的“语言”。 描述网络通信中如何规范使用“语言” 的一组规则就是协议。 2.数据通信协议: 决定数据的格式和数据的传输的一组规则或者一组惯例 协议分层 ARP协议 …

计算机网络--使用网络协议分析器捕捉和分析协议数据包

实验目的 &#xff08;1&#xff09;、 熟悉ethereal的使用 &#xff08;2&#xff09;、 验证各种协议数据包格式 &#xff08;3&#xff09;、 学会捕捉并分析各种数据包。 实验环境 Window 10&#xff0c;ethereal&#xff0c;winpcap 实验内容 &#xff08;1&#xff…

网络协议分析-TCP协议分析

目录 一 . TCP协议的应用二 . TCP包结构三 . 实例化 一 . TCP协议的应用 二 . TCP包结构 源端口号&#xff08; 16 位&#xff09;&#xff1a;它&#xff08;连同源主机 IP 地址&#xff09;标识源主机的一个应用进程。 目的端口号&#xff08; 16 位&#xff09;&#xff1a…

计算机网络 实验三 使用网络协议分析器捕捉和分析协议数据包

学院 计算机学院 年级、专业、班 软件工程 姓名 涂山 学号 170****** 实验课程名称 计算机网络实验 成绩 实验项目名称 使用网络协议分析器捕捉和分析协议数据包 指导老师 &#xff08;1&#xff09;实验目的…

实例:使用网络分析仪进行电缆测试

本应用测试针对非标称50Ω的线缆&#xff0c;包括同轴、双绞线、差分高速数据线的测试&#xff0c;包括阻抗参数、S参数&#xff08;插损、驻波、Smith图等等&#xff09;&#xff0c;也可以绘制眼图。 根据电缆的性能&#xff0c;如频率范围、长度、是否差分&#xff0c;设置…

协议数据分析

实验目的 了解协议分析仪的使用方法和基本特点。 增强对网络协议的理解。 实验要求 要求在进行协议数据分析后&#xff0c;能够将网络数据与具体的网络操作相互映证&#xff0c;如实的记录实验结果&#xff0c;完成实验 实验环境 1&#xff0e;一台运行Windows 2000的计…

五个好用的网络协议分析工具

Network Packet Analyzer&#xff0c;是一种网络分析程序&#xff0c;可以帮助网络管理员捕获、交互式浏览网络中传输的数据包和分析数据包信息等。这里给出了5个最好的网络数据包分析工具&#xff0c;具体如下&#xff1a; 1. Wireshark 相信大家都很熟悉&#xff0c;就不多介…