WinUI(WASDK)使用MediaPipe检查人体姿态关键点

饭宝  金牌会员 | 2023-7-13 22:13:42 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 712|帖子 712|积分 2136

前言

之前有用这个MediaPipe.NET .NET包装库搞了手势识别,丰富了稚晖君的ElectronBot机器人的第三方上位机软件的功能,MediaPipe作为谷歌开源的机器视觉库,功能很丰富了,于是就开始整活了,来体验了一把人体姿态关键点检测。

所用框架介绍

1. WASDK

这个框架是微软最新的应用开发框架,我是用来开发程序的主体,做一些交互和功能的承载,本质上和wpf,uwp这类程序没什么太大的区别,区别就是一些工具链的不同。
2. MediaPipe

MediaPipe  offers open source cross-platform, customizable ML solutions for live and streaming media.
我主要使用MediaPipe进行人体姿态关键点坐标的提取,我的需求是将人体关键点坐标实时提取,并且同步到模型机器人的骨骼上,来实现同步的功能,但是这个博客只展示关键点的获取。
官方文档地址

推荐文档
MediaPipe 集成人脸识别,人体姿态评估,人手检测模型
代码讲解(干货篇)

1. 项目介绍

项目地址
项目结构如下图:

注意
由于MSIX打包的WASDK的路径访问为虚拟文件系统所以我们需要在项目里加入VFS目录,将引用的mediapipe的模块和dll放进去,不然会导致代码无法使用。
详情见如下文档:
打包的 VFS 位置
还有经过本人的测试,模型需要下载【Pose landmarker (Heavy)】的,不然检查不到坐标点。

特别注意的点,记得下载mediapipe的源码,将对应的模块依赖下载复制到对应的的目录,如果模型解压之后的名称和图片的不匹配记得修改文件名称之后复制到对应的目录,代码仓库就不上传模型文件了。

软件处理过程如下:
=>WinUI(WASDK)项目打开图片
=>OpencvSharp处理图片数据
=>转换成ImageFrame
=>MediaPipe处理返回人体姿态关键点坐标数据
=>软件通过win2d将坐标绘制到图片上
2.核心代码讲解

核心代码如下:
这段代码是将图片读取处理并且通过mediapipe获取坐标返回
  1.   private async void StartButton_Click(object sender, RoutedEventArgs e)
  2.     {
  3.         var matData = new OpenCvSharp.Mat(Package.Current.InstalledLocation.Path + $"\\Assets\\pose.jpg");
  4.         var mat2 = matData.CvtColor(OpenCvSharp.ColorConversionCodes.BGR2RGB);
  5.         var dataMeta = mat2.Data;
  6.         var length = mat2.Width * mat2.Height * mat2.Channels();
  7.         var data = new byte[length];
  8.         Marshal.Copy(dataMeta, data, 0, length);
  9.         var widthStep = (int)mat2.Step();
  10.         var imgframe = new ImageFrame(ImageFormat.Types.Format.Srgb, mat2.Width, mat2.Height, widthStep, data);
  11.         PoseOutput handsOutput = calculator.Compute(imgframe);
  12.         if (handsOutput.PoseLandmarks != null)
  13.         {
  14.             _poseOutput = handsOutput;
  15.             CanvasControl1.Invalidate();
  16.             var landmarks = handsOutput.PoseLandmarks.Landmark;
  17.             Console.WriteLine($"Got pose output with {landmarks.Count} landmarks");
  18.         }
  19.         else
  20.         {
  21.             Console.WriteLine("No pose landmarks");
  22.         }
  23.     }
复制代码
将结果绘制到图片上的代码如下,采用win2d绘制
  1.     private void CanvasControl_Draw(CanvasControl sender, CanvasDrawEventArgs args)
  2.     {
  3.         if (_image != null)
  4.         {
  5.             // Draw the image
  6.             args.DrawingSession.DrawImage(_image);
  7.         }
  8.         if (_poseOutput != null)
  9.         {
  10.             var poseLineList = _poseOutput.GetPoseLines(_image.Size.Width, _image.Size.Height);
  11.             foreach (var postLine in poseLineList)
  12.             {
  13.                 args.DrawingSession.DrawLine(postLine.StartVector2, postLine.EndVector2, Microsoft.UI.Colors.Green, 4);
  14.             }
  15.             foreach (var Landmark in _poseOutput?.PoseLandmarks?.Landmark)
  16.             {
  17.                 var x = (int)_image.Size.Width * Landmark.X;
  18.                 var y = (int)_image.Size.Height * Landmark.Y;
  19.                 // Draw a point at (100, 100)
  20.                 args.DrawingSession.DrawCircle(x, y, 2, Microsoft.UI.Colors.Red, 2);
  21.             }
  22.         }
  23.     }
复制代码
效果如下:

人体点对应关系如图:
  1. 0 - nose
  2. 1 - left eye (inner)
  3. 2 - left eye
  4. 3 - left eye (outer)
  5. 4 - right eye (inner)
  6. 5 - right eye
  7. 6 - right eye (outer)
  8. 7 - left ear
  9. 8 - right ear
  10. 9 - mouth (left)
  11. 10 - mouth (right)
  12. 11 - left shoulder
  13. 12 - right shoulder
  14. 13 - left elbow
  15. 14 - right elbow
  16. 15 - left wrist
  17. 16 - right wrist
  18. 17 - left pinky
  19. 18 - right pinky
  20. 19 - left index
  21. 20 - right index
  22. 21 - left thumb
  23. 22 - right thumb
  24. 23 - left hip
  25. 24 - right hip
  26. 25 - left knee
  27. 26 - right knee
  28. 27 - left ankle
  29. 28 - right ankle
  30. 29 - left heel
  31. 30 - right heel
  32. 31 - left foot index
  33. 32 - right foot index
复制代码
特别感谢的项目就是这个MediaPipe.NET了,没有它就没有我的这篇文章,更没有我的项目了。
个人感悟

又到了个人感悟环节,这次感觉舒服多了,因为看着wasdk框架的版本号越来越高,功能也越来越完善了。
总之是朝着好的方向发展了,希望别步了uwp的后尘,喜欢的话记得star一下了。
参考推荐文档如下

demo地址
WASDK文档地址
MediaPipe
MediaPipe.NET
ElectronBot
ElectronBot.DotNet

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

饭宝

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表