mediapipe获取人体3d姿态 c++

时间: 2023-08-03 22:04:31 浏览: 58
使用MediaPipe获取人体3D姿态需要进行以下步骤: 1. 下载和设置MediaPipe的C++ SDK。 2. 安装CUDA和cuDNN。这是为了支持GPU加速。 3. 下载并解压预训练的模型。 4. 编写C++代码来读取摄像头输入并运行MediaPipe的姿态估计模型。 下面是一个示例代码,可以读取实时摄像头输入并显示估计的3D姿态: ```cpp #include <iostream> #include <string> #include "mediapipe/framework/formats/image_frame.h" #include "mediapipe/framework/formats/image_frame_opencv.h" #include "mediapipe/framework/port/opencv_highgui_inc.h" #include "mediapipe/framework/port/opencv_imgproc_inc.h" #include "mediapipe/framework/port/status.h" #include "mediapipe/framework/port/ret_check.h" #include "mediapipe/framework/port/opencv_video_inc.h" #include "mediapipe/framework/tool/options_util.h" #include "mediapipe/framework/deps/file_path.h" #include "mediapipe/framework/deps/compatibility.h" #include "mediapipe/framework/calculator_framework.h" #include "mediapipe/framework/formats/landmark.pb.h" #include "mediapipe/framework/formats/landmark_list.pb.h" #include "mediapipe/framework/formats/rect.pb.h" namespace mediapipe { constexpr char kInputStream[] = "input_video"; constexpr char kOutputStream[] = "output_video"; constexpr char kLandmarksStream[] = "pose_landmarks"; class PoseTrackingCalculator : public CalculatorBase { public: static ::mediapipe::Status GetContract(CalculatorContract* cc) { RET_CHECK(cc->Inputs().HasTag(kInputStream)); RET_CHECK(cc->Outputs().HasTag(kOutputStream)); cc->Inputs().Tag(kInputStream).Set<ImageFrame>(); cc->Outputs().Tag(kOutputStream).Set<ImageFrame>(); cc->Outputs().Tag(kLandmarksStream).Set<std::vector<NormalizedLandmark>>(); return ::mediapipe::OkStatus(); } ::mediapipe::Status Open(CalculatorContext* cc) override { cc->SetOffset(TimestampDiff(0)); return ::mediapipe::OkStatus(); } ::mediapipe::Status Process(CalculatorContext* cc) override { const auto& input_frame = cc->Inputs().Tag(kInputStream).Get<ImageFrame>(); auto output_frame = absl::make_unique<ImageFrame>( ImageFormat::SRGB, input_frame.Width(), input_frame.Height(), ImageFrame::kDefaultAlignmentBoundary); cv::Mat input_mat = formats::MatView(&input_frame); cv::Mat output_mat = formats::MatView(output_frame.get()); // Create an instance of the pose detection calculator. mediapipe::PoseDetectionCalculatorOptions pose_detection_options; pose_detection_options.set_static_image_mode(false); pose_detection_options.set_model_complexity(1); pose_detection_options.set_smooth_landmarks(true); pose_detection_options.set_enable_segmentation(false); pose_detection_options.set_smooth_landmarks(true); CalculatorGraphConfig::Node pose_detection_node_config; pose_detection_node_config.set_calculator("PoseDetectionCalculator"); pose_detection_node_config.add_input_side_packet("image_size_side_packet"); pose_detection_node_config.add_input_side_packet("model_complexity_side_packet"); pose_detection_node_config.add_input_side_packet("static_image_mode_side_packet"); pose_detection_node_config.add_input_side_packet("smooth_landmarks_side_packet"); pose_detection_node_config.add_input_side_packet("enable_segmentation_side_packet"); pose_detection_node_config.add_input_side_packet("input_image_side_packet"); pose_detection_node_config.add_output_tag(kLandmarksStream); pose_detection_node_config.mutable_options()->PackFrom(pose_detection_options); CalculatorGraph graph; ASSIGN_OR_RETURN(auto pose_detection_node, graph.AddNode(pose_detection_node_config)); // Run the pose detection calculator. MP_RETURN_IF_ERROR(graph.StartRun({})); MP_RETURN_IF_ERROR(graph.AddPacketToInputStream( "image_size_side_packet", MakePacket<std::pair<int, int>>(std::make_pair(input_mat.cols, input_mat.rows)))); MP_RETURN_IF_ERROR(graph.AddPacketToInputStream("model_complexity_side_packet", MakePacket<int>(1))); MP_RETURN_IF_ERROR(graph.AddPacketToInputStream("static_image_mode_side_packet", MakePacket<bool>(false))); MP_RETURN_IF_ERROR(graph.AddPacketToInputStream("smooth_landmarks_side_packet", MakePacket<bool>(true))); MP_RETURN_IF_ERROR(graph.AddPacketToInputStream("enable_segmentation_side_packet", MakePacket<bool>(false))); MP_RETURN_IF_ERROR(graph.AddPacketToInputStream("input_image_side_packet", mediapipe::Adopt(input_frame.release()).At(Timestamp(0)))); MP_RETURN_IF_ERROR(graph.WaitUntilIdle()); mediapipe::Packet landmarks_packet; if (graph.GetOutputLandmarkListPacket(kLandmarksStream).ValidateAsType<std::vector<NormalizedLandmark>>().ok()) { landmarks_packet = graph.GetOutputLandmarkListPacket(kLandmarksStream); } MP_RETURN_IF_ERROR(graph.CloseAllPacketSources()); MP_RETURN_IF_ERROR(graph.WaitUntilDone()); // Draw the landmarks on the output frame. auto landmarks = landmarks_packet.Get<std::vector<NormalizedLandmark>>(); for (const auto& landmark : landmarks) { const int landmark_x = landmark.x() * input_mat.cols; const int landmark_y = landmark.y() * input_mat.rows; cv::circle(output_mat, cv::Point(landmark_x, landmark_y), 3, cv::Scalar(0, 255, 0), -1); } cc->Outputs().Tag(kOutputStream).Add(output_frame.release(), cc->InputTimestamp()); cc->Outputs().Tag(kLandmarksStream).Add(landmarks_packet, cc->InputTimestamp()); return ::mediapipe::OkStatus(); } }; REGISTER_CALCULATOR(PoseTrackingCalculator); } // namespace mediapipe int main(int argc, char** argv) { absl::ParseCommandLine(argc, argv); mediapipe::CalculatorGraphConfig config = mediapipe::ParseTextProtoOrDie<mediapipe::CalculatorGraphConfig>(R"pb( input_stream: "input_video" output_stream: "output_video" output_stream: "pose_landmarks" node { calculator: "PoseTrackingCalculator" input_stream: "input_video" output_stream: "output_video" output_stream: "pose_landmarks" } )pb"); mediapipe::CalculatorGraph graph; MP_RETURN_IF_ERROR(graph.Initialize(config)); MP_RETURN_IF_ERROR(graph.StartRun({})); cv::VideoCapture capture(0); CHECK(capture.isOpened()); while (capture.isOpened()) { cv::Mat frame; capture >> frame; if (frame.empty()) break; // Convert the OpenCV Mat to a MediaPipe ImageFrame. auto input_frame = absl::make_unique<mediapipe::ImageFrame>( mediapipe::ImageFormat::SRGB, frame.cols, frame.rows, mediapipe::ImageFrame::kDefaultAlignmentBoundary); cv::Mat input_mat = mediapipe::formats::MatView(input_frame.get()); frame.copyTo(input_mat); // Run the MediaPipe graph to estimate the pose and display the results. mediapipe::Packet packet = mediapipe::Adopt(input_frame.release()).At(mediapipe::Timestamp(0)); MP_RETURN_IF_ERROR(graph.AddPacketToInputStream(mediapipe::kInputStream, packet)); MP_RETURN_IF_ERROR(graph.WaitUntilIdle()); auto output_frame = graph.GetOutputStreamPacket(mediapipe::kOutputStream).Get<mediapipe::ImageFrame>(); auto landmarks_packet = graph.GetOutputStreamPacket(mediapipe::kLandmarksStream); auto landmarks = landmarks_packet.Get<std::vector<mediapipe::NormalizedLandmark>>(); for (const auto& landmark : landmarks) { const int landmark_x = landmark.x() * frame.cols; const int landmark_y = landmark.y() * frame.rows; cv::circle(frame, cv::Point(landmark_x, landmark_y), 3, cv::Scalar(0, 255, 0), -1); } cv::imshow("Pose Tracking", mediapipe::formats::MatView(&output_frame)); if (cv::waitKey(5) == 27) break; } MP_RETURN_IF_ERROR(graph.CloseAllPacketSources()); return graph.WaitUntilDone().ok() ? EXIT_SUCCESS : EXIT_FAILURE; } ``` 请注意,此示例代码仅显示了如何使用MediaPipe获取人体3D姿态。如果需要更多功能(例如记录姿态数据或将其传输到其他设备),则需要进行更多的自定义编程。

相关推荐

最新推荐

recommend-type

c++获取sqlite3数据库表中所有字段的方法小结

本文给大家分享c++获取sqlite3数据库表中所有字段的三种常用方法,本文针对每一种方法给大家详细介绍,需要的的朋友通过本文一起学习吧
recommend-type

C++使用MFC获取PC硬件配置信息

主要为大家详细介绍了C++使用MFC获取PC硬件配置信息,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
recommend-type

c++获取进程信息列表和进程所调用的dll列表

主要介绍了c++获取进程信息列表和进程所调用的dll列表,大家参考使用吧
recommend-type

C++面试八股文深度总结

根据自己备战22届秋招(斩获华为、荣耀、联发科、海康威视等offer)总结的相关知识,其中包括C++基础知识、操作系统、计算机网络、数据库等知识。希望对读者有帮助,助其在找工作的路上少走弯路,收获自己心仪的...
recommend-type

C++获取类的成员函数的函数指针详解及实例代码

主要介绍了C++获取类的成员函数的函数指针详解及实例代码的相关资料,需要的朋友可以参考下
recommend-type

zigbee-cluster-library-specification

最新的zigbee-cluster-library-specification说明文档。
recommend-type

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire
recommend-type

实现实时数据湖架构:Kafka与Hive集成

![实现实时数据湖架构:Kafka与Hive集成](https://img-blog.csdnimg.cn/img_convert/10eb2e6972b3b6086286fc64c0b3ee41.jpeg) # 1. 实时数据湖架构概述** 实时数据湖是一种现代数据管理架构,它允许企业以低延迟的方式收集、存储和处理大量数据。与传统数据仓库不同,实时数据湖不依赖于预先定义的模式,而是采用灵活的架构,可以处理各种数据类型和格式。这种架构为企业提供了以下优势: - **实时洞察:**实时数据湖允许企业访问最新的数据,从而做出更明智的决策。 - **数据民主化:**实时数据湖使各种利益相关者都可
recommend-type

用 Python 画一个可以动的爱心

好的,我可以帮助您使用Python来绘制一个动态的爱心。您可以使用turtle库来实现。以下是实现代码: ```python import turtle import math # 设置画布和画笔 canvas = turtle.Screen() canvas.bgcolor("black") pencil = turtle.Turtle() pencil.speed(0) pencil.color("red", "pink") pencil.pensize(3) # 定义爱心函数 def draw_love(heart_size, x_offset=0, y_offset=0):
recommend-type

JSBSim Reference Manual

JSBSim参考手册,其中包含JSBSim简介,JSBSim配置文件xml的编写语法,编程手册以及一些应用实例等。其中有部分内容还没有写完,估计有生之年很难看到完整版了,但是内容还是很有参考价值的。