mediapipe0.8.9 通过holistic_tracking_cpu.pbtxt获取关键点,并通过关键点之间的向量的夹角来计算旋转角度计算右肩的旋转角度 c++
时间: 2024-02-18 08:03:22 浏览: 71
好的,您可以按照以下步骤来实现:
1. 首先,您需要使用MediaPipe Holistic模型来检测人体关键点。您可以使用OpenCV等库来加载图像并将其传递给Holistic模型进行推理。推理后,您将获得一个包含每个关键点位置的3D张量。
2. 然后,您需要使用这些关键点来计算右肩的旋转角度。具体来说,您需要使用右肩、右臂和右前臂的三个关键点来计算右肩的旋转角度。
3. 您可以使用向量的夹角来计算旋转角度。具体来说,您可以使用向量叉积和点积的组合公式来计算夹角。您可以使用以下代码来计算两个向量之间的夹角:
```
double angle = atan2(norm(cross(v1, v2)), dot(v1, v2));
```
其中,`v1`和`v2`是两个向量,`cross`和`dot`分别表示向量的叉积和点积运算,`norm`表示向量的模长。使用此公式,您可以计算出右肩旋转角度。
4. 最后,您可以将计算出的旋转角度转换为度数,并将其输出到控制台或保存到文件中。您可以使用以下代码将弧度转换为度数:
```
double angle_deg = angle * 180 / CV_PI;
```
需要注意的是,以上仅为简单的示例代码,您需要根据您的实际需求进行相应的修改和调整。
相关问题
mediapipe0.8.9 通过holistic_tracking_cpu.pbtxt获取关键点,并通过关键点之间的向量的夹角来计算旋转角度计算右肩的旋转角度
非常感谢您的提问,我会尽力为您解答。
对于MediaPipe中的Holistic模型,它可以通过`holistic_tracking_cpu.pbtxt`文件获取关键点。其中,右肩的关键点索引为2。关于如何计算右肩的旋转角度,可以通过以下步骤实现:
1. 获取关键点坐标
可以将Holistic模型输出的`pose_landmarks`中,关键点索引为2的坐标值提取出来,作为右肩的坐标。具体实现可以参考以下代码:
```python
import mediapipe as mp
mp_holistic = mp.solutions.holistic
holistic = mp_holistic.Holistic()
# 进行姿势估计和关键点跟踪
results = holistic.process(image)
# 获取右肩的坐标
right_shoulder_x = results.pose_landmarks.landmark[mp_holistic.PoseLandmark.RIGHT_SHOULDER].x
right_shoulder_y = results.pose_landmarks.landmark[mp_holistic.PoseLandmark.RIGHT_SHOULDER].y
right_shoulder_z = results.pose_landmarks.landmark[mp_holistic.PoseLandmark.RIGHT_SHOULDER].z
```
2. 计算向量夹角
计算右肩的旋转角度,可以通过计算右肩与人体正前方向量之间的夹角来实现。具体实现可以参考以下代码:
```python
import math
# 获取人体正前方向量
front_vector = [0, 0, -1]
# 获取右肩与关键点索引为1(颈部)的向量
shoulder_neck_vector = [
results.pose_landmarks.landmark[mp_holistic.PoseLandmark.RIGHT_SHOULDER].x - results.pose_landmarks.landmark[mp_holistic.PoseLandmark.NECK].x,
results.pose_landmarks.landmark[mp_holistic.PoseLandmark.RIGHT_SHOULDER].y - results.pose_landmarks.landmark[mp_holistic.PoseLandmark.NECK].y,
results.pose_landmarks.landmark[mp_holistic.PoseLandmark.RIGHT_SHOULDER].z - results.pose_landmarks.landmark[mp_holistic.PoseLandmark.NECK].z
]
# 计算右肩与人体正前方向量之间的夹角
cos_angle = (front_vector[0]*shoulder_neck_vector[0] + front_vector[1]*shoulder_neck_vector[1] + front_vector[2]*shoulder_neck_vector[2]) \
/ (math.sqrt(front_vector[0]**2 + front_vector[1]**2 + front_vector[2]**2) * math.sqrt(shoulder_neck_vector[0]**2 + shoulder_neck_vector[1]**2 + shoulder_neck_vector[2]**2))
angle = math.degrees(math.acos(cos_angle))
```
以上代码将计算出右肩与人体正前方向量之间的夹角,并将其转化为角度值。最终的旋转角度即为该角度值。
希望以上代码可以帮助您解决问题,如有任何疑问,请随时提出。
mediapipe0.8.9 通过holistic_tracking_cpu.pbtxt获取关键点,并计算索引11的旋转角度
您可以通过以下步骤使用mediapipe 0.8.9通过`holistic_tracking_cpu.pbtxt`获取关键点,并计算索引11的旋转角度:
1. 导入必要的头文件和命名空间:
```c++
#include <fstream>
#include <sstream>
#include <iostream>
#include <opencv2/opencv.hpp>
#include <mediapipe/framework/calculator_framework.h>
#include <mediapipe/framework/formats/image_frame.h>
#include <mediapipe/framework/formats/landmark.pb.h>
#include <mediapipe/framework/formats/rect.pb.h>
using namespace std;
using namespace cv;
using namespace mediapipe;
```
2. 定义图形文件和计算图:
```c++
// 定义图形文件和计算图
const char graph[] = R"(
input_stream: "input_video"
output_stream: "output_video"
node {
calculator: "HolisticTrackingCpu"
input_stream: "IMAGE:input_video"
output_stream: "LANDMARKS:landmarks"
output_stream: "POSE_LANDMARKS:pose_landmarks"
output_stream: "FACE_LANDMARKS:face_landmarks"
output_stream: "LEFT_HAND_LANDMARKS:left_hand_landmarks"
output_stream: "RIGHT_HAND_LANDMARKS:right_hand_landmarks"
}
node {
calculator: "Renderer"
input_stream: "IMAGE:input_video"
input_stream: "LANDMARKS:landmarks"
input_stream: "POSE_LANDMARKS:pose_landmarks"
input_stream: "FACE_LANDMARKS:face_landmarks"
input_stream: "LEFT_HAND_LANDMARKS:left_hand_landmarks"
input_stream: "RIGHT_HAND_LANDMARKS:right_hand_landmarks"
output_stream: "output_video"
}
)";
// 定义计算图函数
void RunMPPGraph() {
// 创建图形文件并将计算图加载到其中
CalculatorGraphConfig config = ParseTextProtoOrDie<CalculatorGraphConfig>(graph);
CalculatorGraph graph;
graph.Initialize(config);
// 获取输入和输出流
auto input_video = graph.GetInputStream("input_video").Value();
auto output_video = graph.GetOutputStream("output_video").Value();
auto landmarks_output = graph.GetOutputStream("landmarks").Value();
// 打开视频文件
VideoCapture capture("test_video.mp4");
// 按帧处理视频
Mat frame;
int frame_count = 0;
while (capture.read(frame)) {
// 将帧转换为mediapipe格式
auto input_frame = absl::make_unique<ImageFrame>(ImageFormat::SRGB, frame.cols, frame.rows, ImageFrame::kDefaultAlignmentBoundary);
cv::Mat input_frame_mat = mediapipe::formats::MatView(input_frame.get());
cv::cvtColor(frame, input_frame_mat, cv::COLOR_BGR2RGB);
// 将帧发送到图形中进行处理
input_video->Send(std::move(input_frame));
input_video->Close();
// 等待处理结果
auto landmarks = absl::make_unique<std::vector<NormalizedLandmarkList>>();
while (landmarks_output->Available()) {
auto landmark_packet = landmarks_output->PopPacket();
auto& landmark_list = landmark_packet.Get<NormalizedLandmarkList>();
landmarks->emplace_back(landmark_list);
}
// 渲染处理结果并将其输出到视频文件
auto output_frame_packet = output_video->Consume();
if (!output_frame_packet.IsEmpty()) {
cv::Mat output_frame_mat = mediapipe::formats::MatView(&output_frame_packet.Get<ImageFrame>());
cv::cvtColor(output_frame_mat, frame, cv::COLOR_RGB2BGR);
// 计算索引11的旋转角度
if (!landmarks->empty()) {
const auto& landmark_list = landmarks->at(0);
if (landmark_list.landmark_size() > 11) {
const auto& point = landmark_list.landmark(11);
const auto& prev_point = landmark_list.landmark(10);
const float angleX = atan2(point.y() - prev_point.y(), point.z() - prev_point.z());
const float angleY = atan2(point.x() - prev_point.x(), point.z() - prev_point.z());
const float angleZ = atan2(point.y() - prev_point.y(), point.x() - prev_point.x());
// 在控制台输出旋转角度
std::cout << "Rotation angles: " << angleX << ", " << angleY << ", " << angleZ << std::endl;
}
}
// 显示视频帧
imshow("Output Video", frame);
waitKey(1);
}
++frame_count;
std::cout << "Frames processed: " << frame_count << std::endl;
}
// 关闭图形
graph.CloseAllPacketSources();
graph.WaitUntilDone();
}
```
3. 运行计算图:
```c++
int main() {
// 运行计算图
google::InitGoogleLogging("MediaPipe");
absl::SetFlag(&FLAGS_alsologtostderr, 1);
RunMPPGraph();
return 0;
}
```
在上面的示例代码中,我们首先定义了`holistic_tracking_cpu.pbtxt`所需的计算图。然后,我们开启视频文件并处理每个视频帧。在处理每个视频帧时,我们将帧转换为mediapipe格式,并将其发送到计算图中进行处理。然后,我们等待处理结果,并从中提取索引11的关键点坐标。最后,我们计算索引11的旋转角度,并在控制台输出结果。
请注意,上面的示例代码仅适用于mediapipe 0.8.9版本,并且假设您已经安装了mediapipe的所有依赖项。如果您使用的是其他版本的mediapipe,您需要相应地调整代码。
阅读全文