From ed1275b673a1b534874bfe1a974ba8b8e5ae96b0 Mon Sep 17 00:00:00 2001 From: Maksym Walczak Date: Mon, 3 Jan 2022 15:42:27 +0100 Subject: [PATCH 01/24] Add pose tracking subproject --- mediapipe/pose_tracking_dll/BUILD | 59 ++++++ mediapipe/pose_tracking_dll/README.md | 30 +++ mediapipe/pose_tracking_dll/pose_tracking.cpp | 179 ++++++++++++++++++ mediapipe/pose_tracking_dll/pose_tracking.h | 99 ++++++++++ .../pose_tracking_dll/windows_dll_library.bzl | 62 ++++++ 5 files changed, 429 insertions(+) create mode 100644 mediapipe/pose_tracking_dll/BUILD create mode 100644 mediapipe/pose_tracking_dll/README.md create mode 100644 mediapipe/pose_tracking_dll/pose_tracking.cpp create mode 100644 mediapipe/pose_tracking_dll/pose_tracking.h create mode 100644 mediapipe/pose_tracking_dll/windows_dll_library.bzl diff --git a/mediapipe/pose_tracking_dll/BUILD b/mediapipe/pose_tracking_dll/BUILD new file mode 100644 index 000000000..98b5f9dc9 --- /dev/null +++ b/mediapipe/pose_tracking_dll/BUILD @@ -0,0 +1,59 @@ +# Copyright 2020 The MediaPipe Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +load("windows_dll_library.bzl", "windows_dll_library") +licenses(["notice"]) + +package(default_visibility = ["//mediapipe/examples:__subpackages__"]) + +# Define the shared library +windows_dll_library( + name = "pose_tracking_lib", + srcs = ["pose_tracking.cpp"], + hdrs = ["pose_tracking.h"], + # Define COMPILING_DLL to export symbols during compiling the DLL. + copts = ["-DCOMPILING_DLL"], + deps = [ + "//mediapipe/framework:calculator_framework", + "//mediapipe/framework/formats:image_frame", + "//mediapipe/framework/formats:image_frame_opencv", + "//mediapipe/framework/formats:landmark_cc_proto", + "//mediapipe/framework/formats:rect_cc_proto", + "//mediapipe/framework/port:file_helpers", + "//mediapipe/framework/port:opencv_highgui", + "//mediapipe/framework/port:opencv_imgproc", + "//mediapipe/framework/port:opencv_video", + "//mediapipe/framework/port:parse_text_proto", + "//mediapipe/framework/port:status", + "@com_google_absl//absl/flags:flag", + "@com_google_absl//absl/flags:parse", + + "//mediapipe/calculators/core:constant_side_packet_calculator", + "//mediapipe/calculators/core:packet_presence_calculator", + "//mediapipe/calculators/core:flow_limiter_calculator", + "//mediapipe/calculators/tflite:tflite_model_calculator", + "//mediapipe/calculators/util:local_file_contents_calculator", + "//mediapipe/graphs/pose_tracking:pose_tracking_cpu_deps", + ] +) + +# **Implicitly link to face_mesh_lib.dll** +cc_binary( + name = "pose_tracking_cpu", + deps = [ + "//mediapipe/examples/desktop:demo_run_graph_main", + "//mediapipe/graphs/pose_tracking:pose_tracking_cpu_deps", + ":pose_tracking_lib" + ], +) diff --git a/mediapipe/pose_tracking_dll/README.md b/mediapipe/pose_tracking_dll/README.md new file mode 100644 index 000000000..a183c4f2b --- /dev/null +++ b/mediapipe/pose_tracking_dll/README.md @@ -0,0 +1,30 @@ +## Description +The pose_tracking_dll module allows for building a dll library that can be used with any C++ project. All the dependencies such as tensorflow are built statically into the dll. + +Currently, the following features are supported: +- Segmenting the person(s) of interest +- Segmenting the skeleton(s) +- Accessing the 3D coordinates of each node of the skeleton by name (using enum) + +## Prerequisites +Follow the guidelines on the official Mediapipe website: https://google.github.io/mediapipe/getting_started/install.html#installing-on-windows + +IMPORTANT: The tutorial does not specify which version of Bazel to install. Install Bazel version 3.7.2 + +## How to build +Assuming you're in the root of the repository: + +cd mediapipe + +bazel build -c opt --define MEDIAPIPE_DISABLE_GPU=1 pose_tracking_dll:pose_tracking_cpu + +The results will be stored in bazel-bin\mediapipe\pose_tracking_dll folder. + +## How to use +Go to bazel-bin\mediapipe\pose_tracking_dll + +Link pose_tracking_cpu.lib and pose_tracking_lib.dll.if.lib statically in your project. + +Make sure the opencv_world3410.dll and pose_tracking_lib.dll are accessible in your working directory. + +Use mediapipe\pose_tracking_dll\pose_tracking.h header file to access the methods of the library. diff --git a/mediapipe/pose_tracking_dll/pose_tracking.cpp b/mediapipe/pose_tracking_dll/pose_tracking.cpp new file mode 100644 index 000000000..65f9f619f --- /dev/null +++ b/mediapipe/pose_tracking_dll/pose_tracking.cpp @@ -0,0 +1,179 @@ +#include +#include + +#include "pose_tracking.h" + +#include "absl/flags/flag.h" +#include "absl/flags/parse.h" +#include "mediapipe/framework/formats/landmark.pb.h" +#include "mediapipe/framework/calculator_framework.h" +#include "mediapipe/framework/formats/image_frame.h" +#include "mediapipe/framework/formats/image_frame_opencv.h" +#include "mediapipe/framework/port/file_helpers.h" +#include "mediapipe/framework/port/opencv_highgui_inc.h" +#include "mediapipe/framework/port/opencv_imgproc_inc.h" +#include "mediapipe/framework/port/opencv_video_inc.h" +#include "mediapipe/framework/port/parse_text_proto.h" +#include "mediapipe/framework/port/status.h" + +class PoseTrackingImpl { +public: + PoseTrackingImpl(const std::string& calculatorGraphConfigFile) { + auto status = initialize(calculatorGraphConfigFile); + if (!status.ok()) { + LOG(WARNING) << "Warning: " << status; + } + } + + absl::Status initialize(const std::string& calculatorGraphConfigFile) { + std::string graphContents; + MP_RETURN_IF_ERROR(mediapipe::file::GetContents( + calculatorGraphConfigFile, + &graphContents)); + + mediapipe::CalculatorGraphConfig config = + mediapipe::ParseTextProtoOrDie( + graphContents); + + MP_RETURN_IF_ERROR(graph.Initialize(config)); + ASSIGN_OR_RETURN(mediapipe::OutputStreamPoller poller, + graph.AddOutputStreamPoller(kOutputSegmentationStream)); + + ASSIGN_OR_RETURN(mediapipe::OutputStreamPoller landmarksPoller, + graph.AddOutputStreamPoller(kOutpuLandmarksStream)); + + ASSIGN_OR_RETURN(mediapipe::OutputStreamPoller posePresencePoller, + graph.AddOutputStreamPoller(kOutpuPosePresenceStream)); + + + maskPollerPtr = std::make_unique(std::move(poller)); + + landmarksPollerPtr = std::make_unique( + std::move(landmarksPoller)); + + posePresencePollerPtr = std::make_unique( + std::move(posePresencePoller)); + + MP_RETURN_IF_ERROR(graph.StartRun({})); + } + + bool processFrame(const cv::Mat& inputRGB8Bit) { + // Wrap Mat into an ImageFrame. + auto inputFrame = absl::make_unique( + mediapipe::ImageFormat::SRGB, inputRGB8Bit.cols, inputRGB8Bit.rows, + mediapipe::ImageFrame::kDefaultAlignmentBoundary); + cv::Mat inputFrameMat = mediapipe::formats::MatView(inputFrame.get()); + inputRGB8Bit.copyTo(inputFrameMat); + + // Send image packet into the graph. + size_t frameTimestampUs = + (double)cv::getTickCount() / (double)cv::getTickFrequency() * 1e6; + auto status = graph.AddPacketToInputStream( + kInputStream, mediapipe::Adopt(inputFrame.release()) + .At(mediapipe::Timestamp(frameTimestampUs))); + + if (!status.ok()) { + LOG(WARNING) << "Graph execution failed: " << status; + return false; + } + + mediapipe::Packet posePresencePacket; + if (!posePresencePollerPtr || !posePresencePollerPtr->Next(&posePresencePacket)) return false; + auto landmarksDetected = posePresencePacket.Get(); + + if (!landmarksDetected) { + return false; + } + + // Get the graph result packet, or stop if that fails. + mediapipe::Packet maskPacket; + if (!maskPollerPtr || !maskPollerPtr->Next(&maskPacket)) return false; + auto& outputFrame = maskPacket.Get(); + + // Get pose landmarks. + if (!landmarksPollerPtr || + !landmarksPollerPtr->Next(&poseLandmarksPacket)) { + return false; + } + + // Convert back to opencv for display or saving. + auto mask = mediapipe::formats::MatView(&outputFrame); + segmentedMask = mask.clone(); + + absl::Status landmarksStatus = detectLandmarksWithStatus(poseLandmarks); + + return landmarksStatus.ok(); + } + + absl::Status detectLandmarksWithStatus( + nimagna::cv_wrapper::Point3f* poseLandmarks) { + + if (poseLandmarksPacket.IsEmpty()) { + return absl::CancelledError("Pose landmarks packet is empty."); + } + + auto retrievedLandmarks = + poseLandmarksPacket + .Get<::mediapipe::NormalizedLandmarkList>(); + + // Convert landmarks to cv::Point3f**. + const auto landmarksCount = retrievedLandmarks.landmark_size(); + + for (int j = 0; j < landmarksCount; ++j) { + const auto& landmark = retrievedLandmarks.landmark(j); + poseLandmarks[j].x = landmark.x(); + poseLandmarks[j].y = landmark.y(); + poseLandmarks[j].z = landmark.z(); + } + + return absl::OkStatus(); + } + + nimagna::cv_wrapper::Point3f* lastDetectedLandmarks() { + return poseLandmarks; + } + + cv::Mat lastSegmentedFrame() { + return segmentedMask; + } + + static constexpr size_t kLandmarksCount = 33u; + +private: + mediapipe::Packet poseLandmarksPacket; + cv::Mat segmentedMask; + nimagna::cv_wrapper::Point3f poseLandmarks[kLandmarksCount]; + std::unique_ptr posePresencePollerPtr; + std::unique_ptr maskPollerPtr; + std::unique_ptr landmarksPollerPtr; + mediapipe::CalculatorGraph graph; + const char* kInputStream = "input_video"; + const char* kOutputSegmentationStream = "segmentation_mask"; + const char* kOutpuLandmarksStream = "pose_landmarks"; + const char* kOutpuPosePresenceStream = "pose_presence"; +}; + +namespace nimagna { + PoseTracking::PoseTracking(const char* calculatorGraphConfigFile) { + myInstance = new PoseTrackingImpl(calculatorGraphConfigFile); + } + + bool PoseTracking::processFrame(const cv_wrapper::Mat& inputRGB8Bit) { + auto* instance = static_cast(myInstance); + const auto frame = cv::Mat(inputRGB8Bit.rows, inputRGB8Bit.cols, CV_8UC3, inputRGB8Bit.data); + return instance->processFrame(frame); + } + + cv_wrapper::Point3f* PoseTracking::lastDetectedLandmarks() { + auto* instance = static_cast(myInstance); + return instance->lastDetectedLandmarks(); + } + + cv_wrapper::Mat PoseTracking::lastSegmentedFrame() { + auto* instance = static_cast(myInstance); + const cv::Mat result = instance->lastSegmentedFrame(); + + return cv_wrapper::Mat(result.rows, result.cols, result.data); + } + +} diff --git a/mediapipe/pose_tracking_dll/pose_tracking.h b/mediapipe/pose_tracking_dll/pose_tracking.h new file mode 100644 index 000000000..34161506c --- /dev/null +++ b/mediapipe/pose_tracking_dll/pose_tracking.h @@ -0,0 +1,99 @@ +#ifndef POSE_TRACKING_LIBRARY_H +#define POSE_TRACKING_LIBRARY_H + +#ifdef COMPILING_DLL +#define DLLEXPORT __declspec(dllexport) +#else +#define DLLEXPORT __declspec(dllimport) +#endif + +namespace nimagna { + namespace cv_wrapper { + struct Point2f { + float x = 0; + float y = 0; + + Point2f() = default; + Point2f(float x, float y) : x(x), y(y) {} + }; + struct Point3f { + float x = 0; + float y = 0; + float z = 0; + + Point3f() = default; + Point3f(float x, float y, float z) : x(x), y(y), z(z) {} + }; + + struct Rect { + int x = 0; + int y = 0; + int width = 0; + int height = 0; + + Rect() = default; + Rect(int x, int y, int width, int height) : x(x), y(y), width(width), height(height) {} + }; + + struct Mat { + int rows = 0; + int cols = 0; + unsigned char* data = 0; + + Mat(int rows, int cols, unsigned char* data) : rows(rows), cols(cols), data(data) {} + }; + } + + class DLLEXPORT PoseTracking { + public: + static constexpr size_t landmarksCount = 33u; + enum LandmarkNames { + NOSE = 0, + LEFT_EYE_INNER, + LEFT_EYE, + LEFT_EYE_OUTER, + RIGHT_EYE_INNER, + RIGHT_EYE, + RIGHT_EYE_OUTER, + LEFT_EAR, + RIGHT_EAR, + MOUTH_LEFT, + MOUTH_RIGHT, + LEFT_SHOULDER, + RIGHT_SHOULDER, + LEFT_ELBOW, + RIGHT_ELBOW, + LEFT_WRIST, + RIGHT_WRIST, + LEFT_PINKY, + RIGHT_PINKY, + LEFT_INDEX, + RIGHT_INDEX, + LEFT_THUMB, + RIGHT_THUMB, + LEFT_HIP, + RIGHT_HIP, + LEFT_KNEE, + RIGHT_KNEE, + LEFT_ANKLE, + RIGHT_ANKLE, + LEFT_HEEL, + RIGHT_HEEL, + LEFT_FOOT_INDEX, + RIGHT_FOOT_INDEX, + COUNT = landmarksCount + }; + + PoseTracking(const char* calculatorGraphConfigFile); + ~PoseTracking() { delete myInstance; } + + bool processFrame(const cv_wrapper::Mat& inputRGB8Bit); + cv_wrapper::Mat lastSegmentedFrame(); + cv_wrapper::Point3f* lastDetectedLandmarks(); + + private: + void* myInstance; + }; +} + +#endif \ No newline at end of file diff --git a/mediapipe/pose_tracking_dll/windows_dll_library.bzl b/mediapipe/pose_tracking_dll/windows_dll_library.bzl new file mode 100644 index 000000000..69c243d60 --- /dev/null +++ b/mediapipe/pose_tracking_dll/windows_dll_library.bzl @@ -0,0 +1,62 @@ +""" +This is a simple windows_dll_library rule for builing a DLL Windows +that can be depended on by other cc rules. +Example useage: + windows_dll_library( + name = "hellolib", + srcs = [ + "hello-library.cpp", + ], + hdrs = ["hello-library.h"], + # Define COMPILING_DLL to export symbols during compiling the DLL. + copts = ["/DCOMPILING_DLL"], + ) +""" + +load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_import", "cc_library") + +def windows_dll_library( + name, + srcs = [], + deps = [], + hdrs = [], + visibility = None, + **kwargs): + """A simple windows_dll_library rule for builing a DLL Windows.""" + dll_name = name + ".dll" + import_lib_name = name + "_import_lib" + import_target_name = name + "_dll_import" + + # Build the shared library + cc_binary( + name = dll_name, + srcs = srcs + hdrs, + deps = deps, + linkshared = 1, + **kwargs + ) + + # Get the import library for the dll + native.filegroup( + name = import_lib_name, + srcs = [":" + dll_name], + output_group = "interface_library", + ) + + # Because we cannot directly depend on cc_binary from other cc rules in deps attribute, + # we use cc_import as a bridge to depend on the dll. + cc_import( + name = import_target_name, + interface_library = ":" + import_lib_name, + shared_library = ":" + dll_name, + ) + + # Create a new cc_library to also include the headers needed for the shared library + cc_library( + name = name, + hdrs = hdrs, + visibility = visibility, + deps = deps + [ + ":" + import_target_name, + ], + ) \ No newline at end of file From 561da620df4fb44d24f4f2b0a44d9d93e8a64628 Mon Sep 17 00:00:00 2001 From: MaksymAtNimagna <88328636+MaksymAtNimagna@users.noreply.github.com> Date: Tue, 4 Jan 2022 11:43:21 +0100 Subject: [PATCH 02/24] Update mediapipe/pose_tracking_dll/README.md Co-authored-by: Xavier Valls --- mediapipe/pose_tracking_dll/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediapipe/pose_tracking_dll/README.md b/mediapipe/pose_tracking_dll/README.md index a183c4f2b..9fed2b27f 100644 --- a/mediapipe/pose_tracking_dll/README.md +++ b/mediapipe/pose_tracking_dll/README.md @@ -4,7 +4,7 @@ The pose_tracking_dll module allows for building a dll library that can be used Currently, the following features are supported: - Segmenting the person(s) of interest - Segmenting the skeleton(s) -- Accessing the 3D coordinates of each node of the skeleton by name (using enum) +- Accessing the 3D coordinates of each node of the skeleton ## Prerequisites Follow the guidelines on the official Mediapipe website: https://google.github.io/mediapipe/getting_started/install.html#installing-on-windows From 3e9b56010eea2d7ac2c3e6224eb0b61a0dc0d993 Mon Sep 17 00:00:00 2001 From: MaksymAtNimagna <88328636+MaksymAtNimagna@users.noreply.github.com> Date: Tue, 4 Jan 2022 11:43:34 +0100 Subject: [PATCH 03/24] Update mediapipe/pose_tracking_dll/pose_tracking.h Co-authored-by: Xavier Valls --- mediapipe/pose_tracking_dll/pose_tracking.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediapipe/pose_tracking_dll/pose_tracking.h b/mediapipe/pose_tracking_dll/pose_tracking.h index 34161506c..5583cb6de 100644 --- a/mediapipe/pose_tracking_dll/pose_tracking.h +++ b/mediapipe/pose_tracking_dll/pose_tracking.h @@ -96,4 +96,4 @@ namespace nimagna { }; } -#endif \ No newline at end of file +#endif From 95483fa64aeb0843fa877dde85933305a562d4b2 Mon Sep 17 00:00:00 2001 From: MaksymAtNimagna <88328636+MaksymAtNimagna@users.noreply.github.com> Date: Tue, 4 Jan 2022 11:45:17 +0100 Subject: [PATCH 04/24] Update mediapipe/pose_tracking_dll/windows_dll_library.bzl Co-authored-by: Xavier Valls --- mediapipe/pose_tracking_dll/windows_dll_library.bzl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediapipe/pose_tracking_dll/windows_dll_library.bzl b/mediapipe/pose_tracking_dll/windows_dll_library.bzl index 69c243d60..ef7371af8 100644 --- a/mediapipe/pose_tracking_dll/windows_dll_library.bzl +++ b/mediapipe/pose_tracking_dll/windows_dll_library.bzl @@ -59,4 +59,4 @@ def windows_dll_library( deps = deps + [ ":" + import_target_name, ], - ) \ No newline at end of file + ) From 8b3cd11c39257829b8edb8eff45a85008de612cb Mon Sep 17 00:00:00 2001 From: MaksymAtNimagna <88328636+MaksymAtNimagna@users.noreply.github.com> Date: Tue, 4 Jan 2022 11:45:31 +0100 Subject: [PATCH 05/24] Update mediapipe/pose_tracking_dll/BUILD Co-authored-by: Xavier Valls --- mediapipe/pose_tracking_dll/BUILD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediapipe/pose_tracking_dll/BUILD b/mediapipe/pose_tracking_dll/BUILD index 98b5f9dc9..9e2df0b7d 100644 --- a/mediapipe/pose_tracking_dll/BUILD +++ b/mediapipe/pose_tracking_dll/BUILD @@ -22,7 +22,7 @@ windows_dll_library( name = "pose_tracking_lib", srcs = ["pose_tracking.cpp"], hdrs = ["pose_tracking.h"], - # Define COMPILING_DLL to export symbols during compiling the DLL. + # Define COMPILING_DLL to export symbols during the DLL compilation. copts = ["-DCOMPILING_DLL"], deps = [ "//mediapipe/framework:calculator_framework", From d5581dabb338c6963e888bb316c0ee2178c713f4 Mon Sep 17 00:00:00 2001 From: MaksymAtNimagna <88328636+MaksymAtNimagna@users.noreply.github.com> Date: Tue, 4 Jan 2022 11:46:27 +0100 Subject: [PATCH 06/24] Update mediapipe/pose_tracking_dll/README.md Co-authored-by: Xavier Valls --- mediapipe/pose_tracking_dll/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediapipe/pose_tracking_dll/README.md b/mediapipe/pose_tracking_dll/README.md index 9fed2b27f..12e330393 100644 --- a/mediapipe/pose_tracking_dll/README.md +++ b/mediapipe/pose_tracking_dll/README.md @@ -1,5 +1,5 @@ ## Description -The pose_tracking_dll module allows for building a dll library that can be used with any C++ project. All the dependencies such as tensorflow are built statically into the dll. +The pose_tracking_dll module allows for building a Mediapipe-based pose tracking DLL library that can be used with any C++ project. All the dependencies such as tensorflow are built statically into the dll. Currently, the following features are supported: - Segmenting the person(s) of interest From d0cce9d97d8730ad7f3b316bb0bff3d9563595fd Mon Sep 17 00:00:00 2001 From: Maksym Walczak Date: Tue, 4 Jan 2022 11:54:01 +0100 Subject: [PATCH 07/24] Modify readme --- mediapipe/pose_tracking_dll/README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mediapipe/pose_tracking_dll/README.md b/mediapipe/pose_tracking_dll/README.md index 12e330393..b47ce0294 100644 --- a/mediapipe/pose_tracking_dll/README.md +++ b/mediapipe/pose_tracking_dll/README.md @@ -14,9 +14,11 @@ IMPORTANT: The tutorial does not specify which version of Bazel to install. Inst ## How to build Assuming you're in the root of the repository: -cd mediapipe +`cd mediapipe` -bazel build -c opt --define MEDIAPIPE_DISABLE_GPU=1 pose_tracking_dll:pose_tracking_cpu +`bazel build -c opt --define MEDIAPIPE_DISABLE_GPU=1 pose_tracking_dll:pose_tracking_cpu` + +Alternatively `dbg` can be used in place of `opt` to build the library with debug symbols in Visual Studio pdb format. The results will be stored in bazel-bin\mediapipe\pose_tracking_dll folder. From a55e33824b437289a040f37369ea86fe02bcea64 Mon Sep 17 00:00:00 2001 From: Maksym Walczak Date: Tue, 4 Jan 2022 11:55:37 +0100 Subject: [PATCH 08/24] Use Cpp style cast --- mediapipe/pose_tracking_dll/pose_tracking.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediapipe/pose_tracking_dll/pose_tracking.cpp b/mediapipe/pose_tracking_dll/pose_tracking.cpp index 65f9f619f..369542eb9 100644 --- a/mediapipe/pose_tracking_dll/pose_tracking.cpp +++ b/mediapipe/pose_tracking_dll/pose_tracking.cpp @@ -67,7 +67,7 @@ public: // Send image packet into the graph. size_t frameTimestampUs = - (double)cv::getTickCount() / (double)cv::getTickFrequency() * 1e6; + static_cast(cv::getTickCount()) / static_cast(cv::getTickFrequency()) * 1e6; auto status = graph.AddPacketToInputStream( kInputStream, mediapipe::Adopt(inputFrame.release()) .At(mediapipe::Timestamp(frameTimestampUs))); From 281199e27888ce2e6ed15b8ad3bd7e54244bb553 Mon Sep 17 00:00:00 2001 From: Maksym Walczak Date: Tue, 4 Jan 2022 12:09:48 +0100 Subject: [PATCH 09/24] Avoid void* for the sake of forward declaration --- mediapipe/pose_tracking_dll/pose_tracking.cpp | 11 ++++------- mediapipe/pose_tracking_dll/pose_tracking.h | 6 ++++-- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/mediapipe/pose_tracking_dll/pose_tracking.cpp b/mediapipe/pose_tracking_dll/pose_tracking.cpp index 369542eb9..abb56c9e8 100644 --- a/mediapipe/pose_tracking_dll/pose_tracking.cpp +++ b/mediapipe/pose_tracking_dll/pose_tracking.cpp @@ -155,23 +155,20 @@ private: namespace nimagna { PoseTracking::PoseTracking(const char* calculatorGraphConfigFile) { - myInstance = new PoseTrackingImpl(calculatorGraphConfigFile); + mImplementation = new PoseTrackingImpl(calculatorGraphConfigFile); } bool PoseTracking::processFrame(const cv_wrapper::Mat& inputRGB8Bit) { - auto* instance = static_cast(myInstance); const auto frame = cv::Mat(inputRGB8Bit.rows, inputRGB8Bit.cols, CV_8UC3, inputRGB8Bit.data); - return instance->processFrame(frame); + return mImplementation->processFrame(frame); } cv_wrapper::Point3f* PoseTracking::lastDetectedLandmarks() { - auto* instance = static_cast(myInstance); - return instance->lastDetectedLandmarks(); + return mImplementation->lastDetectedLandmarks(); } cv_wrapper::Mat PoseTracking::lastSegmentedFrame() { - auto* instance = static_cast(myInstance); - const cv::Mat result = instance->lastSegmentedFrame(); + const cv::Mat result = mImplementation->lastSegmentedFrame(); return cv_wrapper::Mat(result.rows, result.cols, result.data); } diff --git a/mediapipe/pose_tracking_dll/pose_tracking.h b/mediapipe/pose_tracking_dll/pose_tracking.h index 5583cb6de..05c017b78 100644 --- a/mediapipe/pose_tracking_dll/pose_tracking.h +++ b/mediapipe/pose_tracking_dll/pose_tracking.h @@ -7,6 +7,8 @@ #define DLLEXPORT __declspec(dllimport) #endif +class PoseTrackingImpl; + namespace nimagna { namespace cv_wrapper { struct Point2f { @@ -85,14 +87,14 @@ namespace nimagna { }; PoseTracking(const char* calculatorGraphConfigFile); - ~PoseTracking() { delete myInstance; } + ~PoseTracking() { delete mImplementation; } bool processFrame(const cv_wrapper::Mat& inputRGB8Bit); cv_wrapper::Mat lastSegmentedFrame(); cv_wrapper::Point3f* lastDetectedLandmarks(); private: - void* myInstance; + PoseTrackingImpl* mImplementation; }; } From 092e1ad899aba0f37a4723568a820d50c1a4af92 Mon Sep 17 00:00:00 2001 From: Maksym Walczak Date: Tue, 4 Jan 2022 13:52:01 +0100 Subject: [PATCH 10/24] Avoid void* for the sake of forward declaration --- mediapipe/pose_tracking_dll/pose_tracking.cpp | 243 +++++++++--------- mediapipe/pose_tracking_dll/pose_tracking.h | 154 +++++------ 2 files changed, 192 insertions(+), 205 deletions(-) diff --git a/mediapipe/pose_tracking_dll/pose_tracking.cpp b/mediapipe/pose_tracking_dll/pose_tracking.cpp index abb56c9e8..a928bf708 100644 --- a/mediapipe/pose_tracking_dll/pose_tracking.cpp +++ b/mediapipe/pose_tracking_dll/pose_tracking.cpp @@ -1,14 +1,14 @@ +#include "pose_tracking.h" + #include #include -#include "pose_tracking.h" - #include "absl/flags/flag.h" #include "absl/flags/parse.h" -#include "mediapipe/framework/formats/landmark.pb.h" #include "mediapipe/framework/calculator_framework.h" #include "mediapipe/framework/formats/image_frame.h" #include "mediapipe/framework/formats/image_frame_opencv.h" +#include "mediapipe/framework/formats/landmark.pb.h" #include "mediapipe/framework/port/file_helpers.h" #include "mediapipe/framework/port/opencv_highgui_inc.h" #include "mediapipe/framework/port/opencv_imgproc_inc.h" @@ -17,160 +17,147 @@ #include "mediapipe/framework/port/status.h" class PoseTrackingImpl { -public: - PoseTrackingImpl(const std::string& calculatorGraphConfigFile) { - auto status = initialize(calculatorGraphConfigFile); - if (!status.ok()) { - LOG(WARNING) << "Warning: " << status; - } - } + public: + PoseTrackingImpl(const std::string& calculatorGraphConfigFile) { + auto status = initialize(calculatorGraphConfigFile); + if (!status.ok()) { + LOG(WARNING) << "Warning: " << status; + } + } - absl::Status initialize(const std::string& calculatorGraphConfigFile) { - std::string graphContents; - MP_RETURN_IF_ERROR(mediapipe::file::GetContents( - calculatorGraphConfigFile, - &graphContents)); + absl::Status initialize(const std::string& calculatorGraphConfigFile) { + std::string graphContents; + MP_RETURN_IF_ERROR(mediapipe::file::GetContents(calculatorGraphConfigFile, &graphContents)); - mediapipe::CalculatorGraphConfig config = - mediapipe::ParseTextProtoOrDie( - graphContents); - - MP_RETURN_IF_ERROR(graph.Initialize(config)); - ASSIGN_OR_RETURN(mediapipe::OutputStreamPoller poller, - graph.AddOutputStreamPoller(kOutputSegmentationStream)); + mediapipe::CalculatorGraphConfig config = + mediapipe::ParseTextProtoOrDie(graphContents); - ASSIGN_OR_RETURN(mediapipe::OutputStreamPoller landmarksPoller, - graph.AddOutputStreamPoller(kOutpuLandmarksStream)); + MP_RETURN_IF_ERROR(graph.Initialize(config)); + ASSIGN_OR_RETURN(mediapipe::OutputStreamPoller poller, + graph.AddOutputStreamPoller(kOutputSegmentationStream)); - ASSIGN_OR_RETURN(mediapipe::OutputStreamPoller posePresencePoller, - graph.AddOutputStreamPoller(kOutpuPosePresenceStream)); + ASSIGN_OR_RETURN(mediapipe::OutputStreamPoller landmarksPoller, + graph.AddOutputStreamPoller(kOutpuLandmarksStream)); + ASSIGN_OR_RETURN(mediapipe::OutputStreamPoller posePresencePoller, + graph.AddOutputStreamPoller(kOutpuPosePresenceStream)); - maskPollerPtr = std::make_unique(std::move(poller)); + maskPollerPtr = std::make_unique(std::move(poller)); - landmarksPollerPtr = std::make_unique( - std::move(landmarksPoller)); + landmarksPollerPtr = + std::make_unique(std::move(landmarksPoller)); - posePresencePollerPtr = std::make_unique( - std::move(posePresencePoller)); + posePresencePollerPtr = + std::make_unique(std::move(posePresencePoller)); - MP_RETURN_IF_ERROR(graph.StartRun({})); - } + MP_RETURN_IF_ERROR(graph.StartRun({})); + } - bool processFrame(const cv::Mat& inputRGB8Bit) { - // Wrap Mat into an ImageFrame. - auto inputFrame = absl::make_unique( - mediapipe::ImageFormat::SRGB, inputRGB8Bit.cols, inputRGB8Bit.rows, - mediapipe::ImageFrame::kDefaultAlignmentBoundary); - cv::Mat inputFrameMat = mediapipe::formats::MatView(inputFrame.get()); - inputRGB8Bit.copyTo(inputFrameMat); + bool processFrame(const cv::Mat& inputRGB8Bit) { + // Wrap Mat into an ImageFrame. + auto inputFrame = absl::make_unique( + mediapipe::ImageFormat::SRGB, inputRGB8Bit.cols, inputRGB8Bit.rows, + mediapipe::ImageFrame::kDefaultAlignmentBoundary); + cv::Mat inputFrameMat = mediapipe::formats::MatView(inputFrame.get()); + inputRGB8Bit.copyTo(inputFrameMat); - // Send image packet into the graph. - size_t frameTimestampUs = - static_cast(cv::getTickCount()) / static_cast(cv::getTickFrequency()) * 1e6; - auto status = graph.AddPacketToInputStream( - kInputStream, mediapipe::Adopt(inputFrame.release()) - .At(mediapipe::Timestamp(frameTimestampUs))); + // Send image packet into the graph. + size_t frameTimestampUs = + static_cast(cv::getTickCount()) / static_cast(cv::getTickFrequency()) * 1e6; + auto status = graph.AddPacketToInputStream( + kInputStream, + mediapipe::Adopt(inputFrame.release()).At(mediapipe::Timestamp(frameTimestampUs))); - if (!status.ok()) { - LOG(WARNING) << "Graph execution failed: " << status; - return false; - } + if (!status.ok()) { + LOG(WARNING) << "Graph execution failed: " << status; + return false; + } - mediapipe::Packet posePresencePacket; - if (!posePresencePollerPtr || !posePresencePollerPtr->Next(&posePresencePacket)) return false; - auto landmarksDetected = posePresencePacket.Get(); + mediapipe::Packet posePresencePacket; + if (!posePresencePollerPtr || !posePresencePollerPtr->Next(&posePresencePacket)) return false; + auto landmarksDetected = posePresencePacket.Get(); - if (!landmarksDetected) { - return false; - } + if (!landmarksDetected) { + return false; + } - // Get the graph result packet, or stop if that fails. - mediapipe::Packet maskPacket; - if (!maskPollerPtr || !maskPollerPtr->Next(&maskPacket)) return false; - auto& outputFrame = maskPacket.Get(); + // Get the graph result packet, or stop if that fails. + mediapipe::Packet maskPacket; + if (!maskPollerPtr || !maskPollerPtr->Next(&maskPacket)) return false; + auto& outputFrame = maskPacket.Get(); - // Get pose landmarks. - if (!landmarksPollerPtr || - !landmarksPollerPtr->Next(&poseLandmarksPacket)) { - return false; - } + // Get pose landmarks. + if (!landmarksPollerPtr || !landmarksPollerPtr->Next(&poseLandmarksPacket)) { + return false; + } - // Convert back to opencv for display or saving. - auto mask = mediapipe::formats::MatView(&outputFrame); - segmentedMask = mask.clone(); + // Convert back to opencv for display or saving. + auto mask = mediapipe::formats::MatView(&outputFrame); + segmentedMask = mask.clone(); - absl::Status landmarksStatus = detectLandmarksWithStatus(poseLandmarks); + absl::Status landmarksStatus = detectLandmarksWithStatus(poseLandmarks); - return landmarksStatus.ok(); - } + return landmarksStatus.ok(); + } - absl::Status detectLandmarksWithStatus( - nimagna::cv_wrapper::Point3f* poseLandmarks) { + absl::Status detectLandmarksWithStatus(nimagna::cv_wrapper::Point3f* poseLandmarks) { + if (poseLandmarksPacket.IsEmpty()) { + return absl::CancelledError("Pose landmarks packet is empty."); + } - if (poseLandmarksPacket.IsEmpty()) { - return absl::CancelledError("Pose landmarks packet is empty."); - } + auto retrievedLandmarks = poseLandmarksPacket.Get<::mediapipe::NormalizedLandmarkList>(); - auto retrievedLandmarks = - poseLandmarksPacket - .Get<::mediapipe::NormalizedLandmarkList>(); + // Convert landmarks to cv::Point3f**. + const auto landmarksCount = retrievedLandmarks.landmark_size(); - // Convert landmarks to cv::Point3f**. - const auto landmarksCount = retrievedLandmarks.landmark_size(); + for (int j = 0; j < landmarksCount; ++j) { + const auto& landmark = retrievedLandmarks.landmark(j); + poseLandmarks[j].x = landmark.x(); + poseLandmarks[j].y = landmark.y(); + poseLandmarks[j].z = landmark.z(); + } - for (int j = 0; j < landmarksCount; ++j) { - const auto& landmark = retrievedLandmarks.landmark(j); - poseLandmarks[j].x = landmark.x(); - poseLandmarks[j].y = landmark.y(); - poseLandmarks[j].z = landmark.z(); - } + return absl::OkStatus(); + } - return absl::OkStatus(); - } + nimagna::cv_wrapper::Point3f* lastDetectedLandmarks() { return poseLandmarks; } - nimagna::cv_wrapper::Point3f* lastDetectedLandmarks() { - return poseLandmarks; - } + cv::Mat lastSegmentedFrame() { return segmentedMask; } - cv::Mat lastSegmentedFrame() { - return segmentedMask; - } + static constexpr size_t kLandmarksCount = 33u; - static constexpr size_t kLandmarksCount = 33u; - -private: - mediapipe::Packet poseLandmarksPacket; - cv::Mat segmentedMask; - nimagna::cv_wrapper::Point3f poseLandmarks[kLandmarksCount]; - std::unique_ptr posePresencePollerPtr; - std::unique_ptr maskPollerPtr; - std::unique_ptr landmarksPollerPtr; - mediapipe::CalculatorGraph graph; - const char* kInputStream = "input_video"; - const char* kOutputSegmentationStream = "segmentation_mask"; - const char* kOutpuLandmarksStream = "pose_landmarks"; - const char* kOutpuPosePresenceStream = "pose_presence"; + private: + mediapipe::Packet poseLandmarksPacket; + cv::Mat segmentedMask; + nimagna::cv_wrapper::Point3f poseLandmarks[kLandmarksCount]; + std::unique_ptr posePresencePollerPtr; + std::unique_ptr maskPollerPtr; + std::unique_ptr landmarksPollerPtr; + mediapipe::CalculatorGraph graph; + const char* kInputStream = "input_video"; + const char* kOutputSegmentationStream = "segmentation_mask"; + const char* kOutpuLandmarksStream = "pose_landmarks"; + const char* kOutpuPosePresenceStream = "pose_presence"; }; namespace nimagna { - PoseTracking::PoseTracking(const char* calculatorGraphConfigFile) { - mImplementation = new PoseTrackingImpl(calculatorGraphConfigFile); - } - - bool PoseTracking::processFrame(const cv_wrapper::Mat& inputRGB8Bit) { - const auto frame = cv::Mat(inputRGB8Bit.rows, inputRGB8Bit.cols, CV_8UC3, inputRGB8Bit.data); - return mImplementation->processFrame(frame); - } - - cv_wrapper::Point3f* PoseTracking::lastDetectedLandmarks() { - return mImplementation->lastDetectedLandmarks(); - } - - cv_wrapper::Mat PoseTracking::lastSegmentedFrame() { - const cv::Mat result = mImplementation->lastSegmentedFrame(); - - return cv_wrapper::Mat(result.rows, result.cols, result.data); - } - +PoseTracking::PoseTracking(const char* calculatorGraphConfigFile) { + mImplementation = new PoseTrackingImpl(calculatorGraphConfigFile); } + +bool PoseTracking::processFrame(const cv_wrapper::Mat& inputRGB8Bit) { + const auto frame = cv::Mat(inputRGB8Bit.rows, inputRGB8Bit.cols, CV_8UC3, inputRGB8Bit.data); + return mImplementation->processFrame(frame); +} + +cv_wrapper::Point3f* PoseTracking::lastDetectedLandmarks() { + return mImplementation->lastDetectedLandmarks(); +} + +cv_wrapper::Mat PoseTracking::lastSegmentedFrame() { + const cv::Mat result = mImplementation->lastSegmentedFrame(); + + return cv_wrapper::Mat(result.rows, result.cols, result.data); +} + +} // namespace nimagna diff --git a/mediapipe/pose_tracking_dll/pose_tracking.h b/mediapipe/pose_tracking_dll/pose_tracking.h index 05c017b78..b521aef9e 100644 --- a/mediapipe/pose_tracking_dll/pose_tracking.h +++ b/mediapipe/pose_tracking_dll/pose_tracking.h @@ -10,92 +10,92 @@ class PoseTrackingImpl; namespace nimagna { - namespace cv_wrapper { - struct Point2f { - float x = 0; - float y = 0; +namespace cv_wrapper { +struct Point2f { + float x = 0; + float y = 0; - Point2f() = default; - Point2f(float x, float y) : x(x), y(y) {} - }; - struct Point3f { - float x = 0; - float y = 0; - float z = 0; + Point2f() = default; + Point2f(float x, float y) : x(x), y(y) {} +}; +struct Point3f { + float x = 0; + float y = 0; + float z = 0; - Point3f() = default; - Point3f(float x, float y, float z) : x(x), y(y), z(z) {} - }; + Point3f() = default; + Point3f(float x, float y, float z) : x(x), y(y), z(z) {} +}; - struct Rect { - int x = 0; - int y = 0; - int width = 0; - int height = 0; +struct Rect { + int x = 0; + int y = 0; + int width = 0; + int height = 0; - Rect() = default; - Rect(int x, int y, int width, int height) : x(x), y(y), width(width), height(height) {} - }; + Rect() = default; + Rect(int x, int y, int width, int height) : x(x), y(y), width(width), height(height) {} +}; - struct Mat { - int rows = 0; - int cols = 0; - unsigned char* data = 0; +struct Mat { + int rows = 0; + int cols = 0; + unsigned char* data = 0; - Mat(int rows, int cols, unsigned char* data) : rows(rows), cols(cols), data(data) {} - }; - } + Mat(int rows, int cols, unsigned char* data) : rows(rows), cols(cols), data(data) {} +}; +} // namespace cv_wrapper - class DLLEXPORT PoseTracking { - public: - static constexpr size_t landmarksCount = 33u; - enum LandmarkNames { - NOSE = 0, - LEFT_EYE_INNER, - LEFT_EYE, - LEFT_EYE_OUTER, - RIGHT_EYE_INNER, - RIGHT_EYE, - RIGHT_EYE_OUTER, - LEFT_EAR, - RIGHT_EAR, - MOUTH_LEFT, - MOUTH_RIGHT, - LEFT_SHOULDER, - RIGHT_SHOULDER, - LEFT_ELBOW, - RIGHT_ELBOW, - LEFT_WRIST, - RIGHT_WRIST, - LEFT_PINKY, - RIGHT_PINKY, - LEFT_INDEX, - RIGHT_INDEX, - LEFT_THUMB, - RIGHT_THUMB, - LEFT_HIP, - RIGHT_HIP, - LEFT_KNEE, - RIGHT_KNEE, - LEFT_ANKLE, - RIGHT_ANKLE, - LEFT_HEEL, - RIGHT_HEEL, - LEFT_FOOT_INDEX, - RIGHT_FOOT_INDEX, - COUNT = landmarksCount - }; +class DLLEXPORT PoseTracking { + public: + static constexpr size_t landmarksCount = 33u; + enum LandmarkNames { + NOSE = 0, + LEFT_EYE_INNER, + LEFT_EYE, + LEFT_EYE_OUTER, + RIGHT_EYE_INNER, + RIGHT_EYE, + RIGHT_EYE_OUTER, + LEFT_EAR, + RIGHT_EAR, + MOUTH_LEFT, + MOUTH_RIGHT, + LEFT_SHOULDER, + RIGHT_SHOULDER, + LEFT_ELBOW, + RIGHT_ELBOW, + LEFT_WRIST, + RIGHT_WRIST, + LEFT_PINKY, + RIGHT_PINKY, + LEFT_INDEX, + RIGHT_INDEX, + LEFT_THUMB, + RIGHT_THUMB, + LEFT_HIP, + RIGHT_HIP, + LEFT_KNEE, + RIGHT_KNEE, + LEFT_ANKLE, + RIGHT_ANKLE, + LEFT_HEEL, + RIGHT_HEEL, + LEFT_FOOT_INDEX, + RIGHT_FOOT_INDEX, + COUNT = landmarksCount + }; - PoseTracking(const char* calculatorGraphConfigFile); - ~PoseTracking() { delete mImplementation; } + PoseTracking(const char* calculatorGraphConfigFile); + ~PoseTracking() { delete mImplementation; } - bool processFrame(const cv_wrapper::Mat& inputRGB8Bit); - cv_wrapper::Mat lastSegmentedFrame(); - cv_wrapper::Point3f* lastDetectedLandmarks(); + bool processFrame(const cv_wrapper::Mat& inputRGB8Bit); + cv_wrapper::Mat lastSegmentedFrame(); + cv_wrapper::Point3f* lastDetectedLandmarks(); - private: - PoseTrackingImpl* mImplementation; - }; -} + private: + PoseTrackingImpl* mImplementation; +}; +} // namespace nimagna #endif From 365eb9a1ab71c7328df3969856976b4d97583f26 Mon Sep 17 00:00:00 2001 From: Maksym Walczak Date: Wed, 5 Jan 2022 11:35:04 +0100 Subject: [PATCH 11/24] Fix formatting in readme --- mediapipe/pose_tracking_dll/README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mediapipe/pose_tracking_dll/README.md b/mediapipe/pose_tracking_dll/README.md index b47ce0294..6307e4fe8 100644 --- a/mediapipe/pose_tracking_dll/README.md +++ b/mediapipe/pose_tracking_dll/README.md @@ -14,9 +14,10 @@ IMPORTANT: The tutorial does not specify which version of Bazel to install. Inst ## How to build Assuming you're in the root of the repository: -`cd mediapipe` - -`bazel build -c opt --define MEDIAPIPE_DISABLE_GPU=1 pose_tracking_dll:pose_tracking_cpu` +``` +cd mediapipe +bazel build -c opt --define MEDIAPIPE_DISABLE_GPU=1 pose_tracking_dll:pose_tracking_cpu +``` Alternatively `dbg` can be used in place of `opt` to build the library with debug symbols in Visual Studio pdb format. From 50a6d5cbe9d66a0293781d56443e062cace9e110 Mon Sep 17 00:00:00 2001 From: MaksymAtNimagna <88328636+MaksymAtNimagna@users.noreply.github.com> Date: Wed, 5 Jan 2022 11:42:27 +0100 Subject: [PATCH 12/24] Update mediapipe/pose_tracking_dll/README.md Co-authored-by: Xavier Valls --- mediapipe/pose_tracking_dll/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediapipe/pose_tracking_dll/README.md b/mediapipe/pose_tracking_dll/README.md index 6307e4fe8..6165f1b47 100644 --- a/mediapipe/pose_tracking_dll/README.md +++ b/mediapipe/pose_tracking_dll/README.md @@ -21,7 +21,7 @@ bazel build -c opt --define MEDIAPIPE_DISABLE_GPU=1 pose_tracking_dll:pose_track Alternatively `dbg` can be used in place of `opt` to build the library with debug symbols in Visual Studio pdb format. -The results will be stored in bazel-bin\mediapipe\pose_tracking_dll folder. +The results will be stored in the bazel-bin\mediapipe\pose_tracking_dll folder. ## How to use Go to bazel-bin\mediapipe\pose_tracking_dll From 71998bc650c4003f0238b5c7f223b9319dd8cf0c Mon Sep 17 00:00:00 2001 From: MaksymAtNimagna <88328636+MaksymAtNimagna@users.noreply.github.com> Date: Wed, 5 Jan 2022 11:42:33 +0100 Subject: [PATCH 13/24] Update mediapipe/pose_tracking_dll/README.md Co-authored-by: Xavier Valls --- mediapipe/pose_tracking_dll/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediapipe/pose_tracking_dll/README.md b/mediapipe/pose_tracking_dll/README.md index 6165f1b47..6e4f483c7 100644 --- a/mediapipe/pose_tracking_dll/README.md +++ b/mediapipe/pose_tracking_dll/README.md @@ -30,4 +30,4 @@ Link pose_tracking_cpu.lib and pose_tracking_lib.dll.if.lib statically in your p Make sure the opencv_world3410.dll and pose_tracking_lib.dll are accessible in your working directory. -Use mediapipe\pose_tracking_dll\pose_tracking.h header file to access the methods of the library. +Use the mediapipe\pose_tracking_dll\pose_tracking.h header file to access the methods of the library. From 38f4da8a11662fefdfffdb310f23039a903fa519 Mon Sep 17 00:00:00 2001 From: Xavier Valls Date: Thu, 6 Jan 2022 11:42:21 +0100 Subject: [PATCH 14/24] Update installation step in README.md --- mediapipe/pose_tracking_dll/README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/mediapipe/pose_tracking_dll/README.md b/mediapipe/pose_tracking_dll/README.md index 6e4f483c7..fb4b731ac 100644 --- a/mediapipe/pose_tracking_dll/README.md +++ b/mediapipe/pose_tracking_dll/README.md @@ -9,14 +9,17 @@ Currently, the following features are supported: ## Prerequisites Follow the guidelines on the official Mediapipe website: https://google.github.io/mediapipe/getting_started/install.html#installing-on-windows -IMPORTANT: The tutorial does not specify which version of Bazel to install. Install Bazel version 3.7.2 +IMPORTANT: The tutorial does not specify which version of Bazel to install. Install Bazel version 3.7.2. The OpenCV version used by default in mediapipe is 3.4.10. + +If you are using a different OpenCV version, adapt the `OPENCV_VERSION` variable in the file `mediapipe/external/opencv_.BUILD` to the one installed in the system (https://github.com/google/mediapipe/issues/1926#issuecomment-825874197). + ## How to build Assuming you're in the root of the repository: ``` cd mediapipe -bazel build -c opt --define MEDIAPIPE_DISABLE_GPU=1 pose_tracking_dll:pose_tracking_cpu +bazel build -c opt --define MEDIAPIPE_DISABLE_GPU=1 --action_env PYTHON_BIN_PATH= pose_tracking_dll:pose_tracking_cpu ``` Alternatively `dbg` can be used in place of `opt` to build the library with debug symbols in Visual Studio pdb format. From 4c002dc3d8d4a758b68c16050616dbf8984ed10c Mon Sep 17 00:00:00 2001 From: Christoph Niederberger <83065859+christoph-nimagna@users.noreply.github.com> Date: Tue, 11 Jan 2022 12:04:12 +0100 Subject: [PATCH 15/24] Update readme: detailed installation instructions --- mediapipe/pose_tracking_dll/README.md | 78 ++++++++++++++++++++++----- 1 file changed, 65 insertions(+), 13 deletions(-) diff --git a/mediapipe/pose_tracking_dll/README.md b/mediapipe/pose_tracking_dll/README.md index fb4b731ac..0946f8c98 100644 --- a/mediapipe/pose_tracking_dll/README.md +++ b/mediapipe/pose_tracking_dll/README.md @@ -7,30 +7,82 @@ Currently, the following features are supported: - Accessing the 3D coordinates of each node of the skeleton ## Prerequisites -Follow the guidelines on the official Mediapipe website: https://google.github.io/mediapipe/getting_started/install.html#installing-on-windows -IMPORTANT: The tutorial does not specify which version of Bazel to install. Install Bazel version 3.7.2. The OpenCV version used by default in mediapipe is 3.4.10. +Install Mediapipe development environment as follows. + +**Note**: This guide assumes the Nimagna development environment. Otherwise, please follow the guidelines on the official Mediapipe website: https://google.github.io/mediapipe/getting_started/install.html#installing-on-windows with the important change that Bazel version 3.7.2 is required and the helpful sidemark that OpenCV version used by default in mediapipe is 3.4.10. + +### Install MSYS2 + +- Install MSYS2 from https://www.msys2.org/ +- Edit the %PATH% environment variable: If MSYS2 is installed to `C:\msys64`, add `C:\msys64\usr\bin` to your %PATH% environment variable. + +### Install necessary packages + +- Run `pacman -S git patch unzip` and confirm installation + +### Install Python 3.9 + +- Download Python 3.9.9 Windows executable https://www.python.org/downloads/release/python-399/ and install. Note that Python 3.10 does not work. +- Allow the installer to edit the %PATH% environment variable. +- The Python installation path is referred to as `PYTHONDIR` in the following steps. Usually, this is `C:\Users\...\AppData\Local\Programs\Python\Python39` when installing only for the current user. +- Run `pip install numpy` in a new command line. + +### Install Visual C++ Build Tools 2019 and WinSDK + +- Download and install VC build tools from https://visualstudio.microsoft.com/visual-cpp-build-tools/ with the following settings: + ![image](https://user-images.githubusercontent.com/83065859/148920359-fc5830c2-3eb1-47d4-ba33-8b1ba783b728.png) + +- Redistributables and WinSDK 10.0.19041.0 should be installed already. If not, install with Visual Studio or download the [WinSDK from the official Microsoft website](https://developer.microsoft.com/en-us/windows/downloads/sdk-archive/) and install. + +### Install Bazel 3.7.2 + +- Download `bazel-3.7.2-windows-x86_64.exe` from https://github.com/bazelbuild/bazel/releases/tag/3.7.2 and rename to `bazel.exe` +- Add the location of the downloaded Bazel executable to the %PATH% environment variable. +- Set additional Bazel environment variables as follows: + - `BAZEL_VS=C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools` + - `BAZEL_VC=C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC` + - `BAZEL_VC_FULL_VERSION=14.29.30133` - or the name of the folder you find in `C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC` + - `BAZEL_WINSDK_FULL_VERSION=10.0.19041.0` + +### Checkout Mediapipe + +- git clone https://github.com/NimagnaAG/mediapipe +- the repository root folder is referred to as `MEDIAPIPEDIR` in the following steps + +### Install OpenCV + +- Download OpenCV 3.4.10 from https://sourceforge.net/projects/opencvlibrary/files/3.4.10/opencv-3.4.10-vc14_vc15.exe/download +- Extract OpenCV from into a folder, e.g. `C:\Users\ChristophNiederberge\source\repos\opencv_3.4.10`. This folder is referred to as `OPENCVDIR` in the following steps. +- Edit the `MEDIAPIPEDIR\WORKSPACE` file: Around line 215, is the "windows_opencv" repository. Adapt the path to point to `OPENCVDIR\\build` (using double backslashes): + ``` + new_local_repository( + name = "windows_opencv", + build_file = "@//third_party:opencv_windows.BUILD", + path = "OPENCVDIR\\build", + ) + ``` + +#### OpenCV side note If you are using a different OpenCV version, adapt the `OPENCV_VERSION` variable in the file `mediapipe/external/opencv_.BUILD` to the one installed in the system (https://github.com/google/mediapipe/issues/1926#issuecomment-825874197). - ## How to build -Assuming you're in the root of the repository: +Assuming you're in `MEDIAPIPEDIR`, the root of the repository, run the following commands by replacing `PYTHONDIR` using forward slashes "/" in the path: ``` cd mediapipe -bazel build -c opt --define MEDIAPIPE_DISABLE_GPU=1 --action_env PYTHON_BIN_PATH= pose_tracking_dll:pose_tracking_cpu +bazel build -c opt --define MEDIAPIPE_DISABLE_GPU=1 --action_env PYTHON_BIN_PATH=PYTHONDIR/python.exe pose_tracking_dll:pose_tracking_cpu ``` -Alternatively `dbg` can be used in place of `opt` to build the library with debug symbols in Visual Studio pdb format. +The results will be stored in the `bazel-bin\mediapipe\pose_tracking_dll` folder. -The results will be stored in the bazel-bin\mediapipe\pose_tracking_dll folder. +**Build debug symbols** +- `dbg` can be used in place of `opt` to build the library with debug symbols in Visual Studio pdb format. ## How to use -Go to bazel-bin\mediapipe\pose_tracking_dll -Link pose_tracking_cpu.lib and pose_tracking_lib.dll.if.lib statically in your project. - -Make sure the opencv_world3410.dll and pose_tracking_lib.dll are accessible in your working directory. - -Use the mediapipe\pose_tracking_dll\pose_tracking.h header file to access the methods of the library. +- Go to bazel-bin\mediapipe\pose_tracking_dll +- Link `pose_tracking_cpu.lib` and `pose_tracking_lib.dll.if.lib` statically in your project. +- Make sure `opencv_world3410.dll` and `pose_tracking_lib.dll` are accessible in your working directory. +- Includeptyh `mediapipe\pose_tracking_dll\pose_tracking.h` header file to access the methods of the library. From e926f3ab37c6577d69208c29d28f87f095fa724d Mon Sep 17 00:00:00 2001 From: Christoph Niederberger <83065859+christoph-nimagna@users.noreply.github.com> Date: Tue, 11 Jan 2022 12:12:39 +0100 Subject: [PATCH 16/24] Update README.md --- mediapipe/pose_tracking_dll/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mediapipe/pose_tracking_dll/README.md b/mediapipe/pose_tracking_dll/README.md index 0946f8c98..8505ea0a8 100644 --- a/mediapipe/pose_tracking_dll/README.md +++ b/mediapipe/pose_tracking_dll/README.md @@ -63,9 +63,10 @@ Install Mediapipe development environment as follows. ) ``` -#### OpenCV side note +#### Installation/build issue handling -If you are using a different OpenCV version, adapt the `OPENCV_VERSION` variable in the file `mediapipe/external/opencv_.BUILD` to the one installed in the system (https://github.com/google/mediapipe/issues/1926#issuecomment-825874197). +- If you are using a **different OpenCV version**, adapt the `OPENCV_VERSION` variable in the file `mediapipe/external/opencv_.BUILD` to the one installed in the system (https://github.com/google/mediapipe/issues/1926#issuecomment-825874197). +- If bazel fails to download packages, run `bazel clean --expunge` and try again. ## How to build Assuming you're in `MEDIAPIPEDIR`, the root of the repository, run the following commands by replacing `PYTHONDIR` using forward slashes "/" in the path: From d46dd3c28d0a678558f12f0abd5fc5349abe11a7 Mon Sep 17 00:00:00 2001 From: Christoph Niederberger <83065859+christoph-nimagna@users.noreply.github.com> Date: Tue, 11 Jan 2022 15:57:40 +0100 Subject: [PATCH 17/24] Added a build issue solution --- mediapipe/pose_tracking_dll/README.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/mediapipe/pose_tracking_dll/README.md b/mediapipe/pose_tracking_dll/README.md index 8505ea0a8..c5b5482a3 100644 --- a/mediapipe/pose_tracking_dll/README.md +++ b/mediapipe/pose_tracking_dll/README.md @@ -63,10 +63,9 @@ Install Mediapipe development environment as follows. ) ``` -#### Installation/build issue handling +#### Installation issue handling - If you are using a **different OpenCV version**, adapt the `OPENCV_VERSION` variable in the file `mediapipe/external/opencv_.BUILD` to the one installed in the system (https://github.com/google/mediapipe/issues/1926#issuecomment-825874197). -- If bazel fails to download packages, run `bazel clean --expunge` and try again. ## How to build Assuming you're in `MEDIAPIPEDIR`, the root of the repository, run the following commands by replacing `PYTHONDIR` using forward slashes "/" in the path: @@ -78,9 +77,15 @@ bazel build -c opt --define MEDIAPIPE_DISABLE_GPU=1 --action_env PYTHON_BIN_PATH The results will be stored in the `bazel-bin\mediapipe\pose_tracking_dll` folder. -**Build debug symbols** +### Build debug symbols - `dbg` can be used in place of `opt` to build the library with debug symbols in Visual Studio pdb format. +### Build issue handling + +- If bazel fails to download packages, run `bazel clean --expunge` and try again. +- If bazel fails with an `fatal error C1083: Cannot open compiler generated file: '': Invalid argument`, your [path is too long](https://stackoverflow.com/questions/34074925/vs-2015-cannot-open-compiler-generated-file-invalid-argument). Actually, it is most probably the username... + - Adapt the call to `bazel --output_base=E:\nim_output build build -c opt --define MEDIAPIPE_DISABLE_GPU=1 --action_env PYTHON_BIN_PATH=PYTHONDIR/python.exe pose_tracking_dll:pose_tracking_cpu` where `E:\nim_output build` can be replaced with some short path where bazel will store the packages and perform the build. + ## How to use - Go to bazel-bin\mediapipe\pose_tracking_dll From 37ecba050b6faa9ae8d006c546058cd4f0c09548 Mon Sep 17 00:00:00 2001 From: Christoph Niederberger <83065859+christoph-nimagna@users.noreply.github.com> Date: Tue, 11 Jan 2022 16:15:29 +0100 Subject: [PATCH 18/24] Fixed typo --- mediapipe/pose_tracking_dll/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediapipe/pose_tracking_dll/README.md b/mediapipe/pose_tracking_dll/README.md index c5b5482a3..6d886edcf 100644 --- a/mediapipe/pose_tracking_dll/README.md +++ b/mediapipe/pose_tracking_dll/README.md @@ -84,7 +84,7 @@ The results will be stored in the `bazel-bin\mediapipe\pose_tracking_dll` folder - If bazel fails to download packages, run `bazel clean --expunge` and try again. - If bazel fails with an `fatal error C1083: Cannot open compiler generated file: '': Invalid argument`, your [path is too long](https://stackoverflow.com/questions/34074925/vs-2015-cannot-open-compiler-generated-file-invalid-argument). Actually, it is most probably the username... - - Adapt the call to `bazel --output_base=E:\nim_output build build -c opt --define MEDIAPIPE_DISABLE_GPU=1 --action_env PYTHON_BIN_PATH=PYTHONDIR/python.exe pose_tracking_dll:pose_tracking_cpu` where `E:\nim_output build` can be replaced with some short path where bazel will store the packages and perform the build. + - Adapt the call to `bazel --output_base=E:\nim_output build -c opt --define MEDIAPIPE_DISABLE_GPU=1 --action_env PYTHON_BIN_PATH=PYTHONDIR/python.exe pose_tracking_dll:pose_tracking_cpu` where `E:\nim_output build` can be replaced with some short path where bazel will store the packages and perform the build. ## How to use From 5361430648926e18a68928562f8244573b2efce5 Mon Sep 17 00:00:00 2001 From: Maksym Walczak Date: Thu, 13 Jan 2022 14:16:54 +0100 Subject: [PATCH 19/24] Add copyright note --- mediapipe/pose_tracking_dll/pose_tracking.cpp | 16 +++++++++++++++ mediapipe/pose_tracking_dll/pose_tracking.h | 20 +++++++++++++++++-- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/mediapipe/pose_tracking_dll/pose_tracking.cpp b/mediapipe/pose_tracking_dll/pose_tracking.cpp index a928bf708..218339716 100644 --- a/mediapipe/pose_tracking_dll/pose_tracking.cpp +++ b/mediapipe/pose_tracking_dll/pose_tracking.cpp @@ -1,3 +1,19 @@ +/** + Copyright 2022, Nimagna AG + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + #include "pose_tracking.h" #include diff --git a/mediapipe/pose_tracking_dll/pose_tracking.h b/mediapipe/pose_tracking_dll/pose_tracking.h index b521aef9e..5f6ff3285 100644 --- a/mediapipe/pose_tracking_dll/pose_tracking.h +++ b/mediapipe/pose_tracking_dll/pose_tracking.h @@ -1,3 +1,19 @@ +/** + Copyright 2022, Nimagna AG + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + #ifndef POSE_TRACKING_LIBRARY_H #define POSE_TRACKING_LIBRARY_H @@ -48,7 +64,7 @@ struct Mat { class DLLEXPORT PoseTracking { public: - static constexpr size_t landmarksCount = 33u; + static constexpr size_t kLandmarksCount = 33u; enum LandmarkNames { NOSE = 0, LEFT_EYE_INNER, @@ -83,7 +99,7 @@ class DLLEXPORT PoseTracking { RIGHT_HEEL, LEFT_FOOT_INDEX, RIGHT_FOOT_INDEX, - COUNT = landmarksCount + COUNT = kLandmarksCount }; PoseTracking(const char* calculatorGraphConfigFile); From 7d16f899a0b89839860f3c6ac84117dafb367dd6 Mon Sep 17 00:00:00 2001 From: Maksym Walczak Date: Thu, 20 Jan 2022 15:53:57 +0100 Subject: [PATCH 20/24] Fix the issue with increasing latency --- mediapipe/pose_tracking_dll/pose_tracking.cpp | 20 +++---------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/mediapipe/pose_tracking_dll/pose_tracking.cpp b/mediapipe/pose_tracking_dll/pose_tracking.cpp index 218339716..3db266076 100644 --- a/mediapipe/pose_tracking_dll/pose_tracking.cpp +++ b/mediapipe/pose_tracking_dll/pose_tracking.cpp @@ -50,21 +50,17 @@ class PoseTrackingImpl { MP_RETURN_IF_ERROR(graph.Initialize(config)); ASSIGN_OR_RETURN(mediapipe::OutputStreamPoller poller, - graph.AddOutputStreamPoller(kOutputSegmentationStream)); + graph.AddOutputStreamPoller(kOutputSegmentationStream, true)); ASSIGN_OR_RETURN(mediapipe::OutputStreamPoller landmarksPoller, - graph.AddOutputStreamPoller(kOutpuLandmarksStream)); + graph.AddOutputStreamPoller(kOutpuLandmarksStream, true)); - ASSIGN_OR_RETURN(mediapipe::OutputStreamPoller posePresencePoller, - graph.AddOutputStreamPoller(kOutpuPosePresenceStream)); maskPollerPtr = std::make_unique(std::move(poller)); landmarksPollerPtr = std::make_unique(std::move(landmarksPoller)); - posePresencePollerPtr = - std::make_unique(std::move(posePresencePoller)); MP_RETURN_IF_ERROR(graph.StartRun({})); } @@ -89,17 +85,9 @@ class PoseTrackingImpl { return false; } - mediapipe::Packet posePresencePacket; - if (!posePresencePollerPtr || !posePresencePollerPtr->Next(&posePresencePacket)) return false; - auto landmarksDetected = posePresencePacket.Get(); - - if (!landmarksDetected) { - return false; - } - // Get the graph result packet, or stop if that fails. mediapipe::Packet maskPacket; - if (!maskPollerPtr || !maskPollerPtr->Next(&maskPacket)) return false; + if (!maskPollerPtr || !maskPollerPtr->Next(&maskPacket) || maskPacket.IsEmpty()) return false; auto& outputFrame = maskPacket.Get(); // Get pose landmarks. @@ -146,14 +134,12 @@ class PoseTrackingImpl { mediapipe::Packet poseLandmarksPacket; cv::Mat segmentedMask; nimagna::cv_wrapper::Point3f poseLandmarks[kLandmarksCount]; - std::unique_ptr posePresencePollerPtr; std::unique_ptr maskPollerPtr; std::unique_ptr landmarksPollerPtr; mediapipe::CalculatorGraph graph; const char* kInputStream = "input_video"; const char* kOutputSegmentationStream = "segmentation_mask"; const char* kOutpuLandmarksStream = "pose_landmarks"; - const char* kOutpuPosePresenceStream = "pose_presence"; }; namespace nimagna { From 2a85afc40581b6bd60807cffa799399314da2c15 Mon Sep 17 00:00:00 2001 From: Maksym Walczak Date: Fri, 21 Jan 2022 16:34:02 +0100 Subject: [PATCH 21/24] Move the destructor definition out of the header (C4150) --- mediapipe/pose_tracking_dll/pose_tracking.cpp | 8 +++++--- mediapipe/pose_tracking_dll/pose_tracking.h | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/mediapipe/pose_tracking_dll/pose_tracking.cpp b/mediapipe/pose_tracking_dll/pose_tracking.cpp index 3db266076..70a598fee 100644 --- a/mediapipe/pose_tracking_dll/pose_tracking.cpp +++ b/mediapipe/pose_tracking_dll/pose_tracking.cpp @@ -36,9 +36,6 @@ class PoseTrackingImpl { public: PoseTrackingImpl(const std::string& calculatorGraphConfigFile) { auto status = initialize(calculatorGraphConfigFile); - if (!status.ok()) { - LOG(WARNING) << "Warning: " << status; - } } absl::Status initialize(const std::string& calculatorGraphConfigFile) { @@ -162,4 +159,9 @@ cv_wrapper::Mat PoseTracking::lastSegmentedFrame() { return cv_wrapper::Mat(result.rows, result.cols, result.data); } +PoseTracking::~PoseTracking() +{ + delete mImplementation; +} + } // namespace nimagna diff --git a/mediapipe/pose_tracking_dll/pose_tracking.h b/mediapipe/pose_tracking_dll/pose_tracking.h index 5f6ff3285..536547e06 100644 --- a/mediapipe/pose_tracking_dll/pose_tracking.h +++ b/mediapipe/pose_tracking_dll/pose_tracking.h @@ -103,7 +103,7 @@ class DLLEXPORT PoseTracking { }; PoseTracking(const char* calculatorGraphConfigFile); - ~PoseTracking() { delete mImplementation; } + ~PoseTracking(); bool processFrame(const cv_wrapper::Mat& inputRGB8Bit); cv_wrapper::Mat lastSegmentedFrame(); From 16d6078325d11e045b420626acf7a434437abc71 Mon Sep 17 00:00:00 2001 From: Maksym Walczak Date: Tue, 9 Aug 2022 14:27:36 +0200 Subject: [PATCH 22/24] Add the possibility to get landmark visibility --- mediapipe/pose_tracking_dll/README.md | 15 +++++++++++++++ mediapipe/pose_tracking_dll/pose_tracking.cpp | 9 ++++++++- mediapipe/pose_tracking_dll/pose_tracking.h | 1 + 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/mediapipe/pose_tracking_dll/README.md b/mediapipe/pose_tracking_dll/README.md index 6d886edcf..249c0ae15 100644 --- a/mediapipe/pose_tracking_dll/README.md +++ b/mediapipe/pose_tracking_dll/README.md @@ -77,6 +77,21 @@ bazel build -c opt --define MEDIAPIPE_DISABLE_GPU=1 --action_env PYTHON_BIN_PATH The results will be stored in the `bazel-bin\mediapipe\pose_tracking_dll` folder. +In the case the build stalls, pressing Ctrl+C might not be sufficient to stop the task. In that case, if you try to (resume the) build again, +the following message will be displayed: + +``` +Another command (pid=5300) is running. Waiting for it to complete on the server (server_pid=3684) +``` + +Unfortunately this process is hidden for some reason and can't be found in taskmgr. Fortunately, you can use the `taskkill` command to kill the process: + +``` +taskkill /F /PID 3684 +``` + +After that, you should be able to run the build command again. + ### Build debug symbols - `dbg` can be used in place of `opt` to build the library with debug symbols in Visual Studio pdb format. diff --git a/mediapipe/pose_tracking_dll/pose_tracking.cpp b/mediapipe/pose_tracking_dll/pose_tracking.cpp index 70a598fee..a87e0fedd 100644 --- a/mediapipe/pose_tracking_dll/pose_tracking.cpp +++ b/mediapipe/pose_tracking_dll/pose_tracking.cpp @@ -116,6 +116,7 @@ class PoseTrackingImpl { poseLandmarks[j].x = landmark.x(); poseLandmarks[j].y = landmark.y(); poseLandmarks[j].z = landmark.z(); + visibility[j] = landmark.visibility(); } return absl::OkStatus(); @@ -124,6 +125,7 @@ class PoseTrackingImpl { nimagna::cv_wrapper::Point3f* lastDetectedLandmarks() { return poseLandmarks; } cv::Mat lastSegmentedFrame() { return segmentedMask; } + float* landmarksVisibility() { return visibility; } static constexpr size_t kLandmarksCount = 33u; @@ -131,12 +133,13 @@ class PoseTrackingImpl { mediapipe::Packet poseLandmarksPacket; cv::Mat segmentedMask; nimagna::cv_wrapper::Point3f poseLandmarks[kLandmarksCount]; + float visibility[kLandmarksCount] = {0}; std::unique_ptr maskPollerPtr; std::unique_ptr landmarksPollerPtr; mediapipe::CalculatorGraph graph; const char* kInputStream = "input_video"; const char* kOutputSegmentationStream = "segmentation_mask"; - const char* kOutpuLandmarksStream = "pose_landmarks"; + const char* kOutpuLandmarksStream = "pose_world_landmarks"; }; namespace nimagna { @@ -153,6 +156,10 @@ cv_wrapper::Point3f* PoseTracking::lastDetectedLandmarks() { return mImplementation->lastDetectedLandmarks(); } +float* PoseTracking::lastLandmarksVisibility() { + return mImplementation->landmarksVisibility(); +} + cv_wrapper::Mat PoseTracking::lastSegmentedFrame() { const cv::Mat result = mImplementation->lastSegmentedFrame(); diff --git a/mediapipe/pose_tracking_dll/pose_tracking.h b/mediapipe/pose_tracking_dll/pose_tracking.h index 536547e06..78b93b0b5 100644 --- a/mediapipe/pose_tracking_dll/pose_tracking.h +++ b/mediapipe/pose_tracking_dll/pose_tracking.h @@ -108,6 +108,7 @@ class DLLEXPORT PoseTracking { bool processFrame(const cv_wrapper::Mat& inputRGB8Bit); cv_wrapper::Mat lastSegmentedFrame(); cv_wrapper::Point3f* lastDetectedLandmarks(); + float* lastLandmarksVisibility(); private: PoseTrackingImpl* mImplementation; From 17d38c9c5aa58bcc1a954a2c836f4a30a392d5af Mon Sep 17 00:00:00 2001 From: Maksym Walczak Date: Tue, 9 Aug 2022 15:29:58 +0200 Subject: [PATCH 23/24] Fix bug with world landmarks and print init status --- mediapipe/pose_tracking_dll/pose_tracking.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mediapipe/pose_tracking_dll/pose_tracking.cpp b/mediapipe/pose_tracking_dll/pose_tracking.cpp index a87e0fedd..9c4ed4c2d 100644 --- a/mediapipe/pose_tracking_dll/pose_tracking.cpp +++ b/mediapipe/pose_tracking_dll/pose_tracking.cpp @@ -36,6 +36,7 @@ class PoseTrackingImpl { public: PoseTrackingImpl(const std::string& calculatorGraphConfigFile) { auto status = initialize(calculatorGraphConfigFile); + LOG(WARNING) << "Initialized PoseTracking with status: " << status; } absl::Status initialize(const std::string& calculatorGraphConfigFile) { @@ -139,7 +140,7 @@ class PoseTrackingImpl { mediapipe::CalculatorGraph graph; const char* kInputStream = "input_video"; const char* kOutputSegmentationStream = "segmentation_mask"; - const char* kOutpuLandmarksStream = "pose_world_landmarks"; + const char* kOutpuLandmarksStream = "pose_landmarks"; }; namespace nimagna { From 0c292576f9c97c86f32ca4aebb630eea791f3464 Mon Sep 17 00:00:00 2001 From: Maksym Walczak Date: Thu, 11 Aug 2022 13:56:49 +0200 Subject: [PATCH 24/24] Group landmarks points together with visibility in a single structure --- mediapipe/pose_tracking_dll/pose_tracking.cpp | 9 ++------- mediapipe/pose_tracking_dll/pose_tracking.h | 14 ++++++++++---- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/mediapipe/pose_tracking_dll/pose_tracking.cpp b/mediapipe/pose_tracking_dll/pose_tracking.cpp index 9c4ed4c2d..33dbdb934 100644 --- a/mediapipe/pose_tracking_dll/pose_tracking.cpp +++ b/mediapipe/pose_tracking_dll/pose_tracking.cpp @@ -153,12 +153,8 @@ bool PoseTracking::processFrame(const cv_wrapper::Mat& inputRGB8Bit) { return mImplementation->processFrame(frame); } -cv_wrapper::Point3f* PoseTracking::lastDetectedLandmarks() { - return mImplementation->lastDetectedLandmarks(); -} - -float* PoseTracking::lastLandmarksVisibility() { - return mImplementation->landmarksVisibility(); +PoseTracking::PoseLandmarks PoseTracking::lastDetectedLandmarks() { + return {mImplementation->lastDetectedLandmarks(), mImplementation->landmarksVisibility()}; } cv_wrapper::Mat PoseTracking::lastSegmentedFrame() { @@ -171,5 +167,4 @@ PoseTracking::~PoseTracking() { delete mImplementation; } - } // namespace nimagna diff --git a/mediapipe/pose_tracking_dll/pose_tracking.h b/mediapipe/pose_tracking_dll/pose_tracking.h index 78b93b0b5..b40925185 100644 --- a/mediapipe/pose_tracking_dll/pose_tracking.h +++ b/mediapipe/pose_tracking_dll/pose_tracking.h @@ -62,9 +62,16 @@ struct Mat { }; } // namespace cv_wrapper + class DLLEXPORT PoseTracking { public: - static constexpr size_t kLandmarksCount = 33u; + struct PoseLandmarks { + PoseLandmarks(cv_wrapper::Point3f* points, float* visibility) : points(points), visibility(visibility) {} + static constexpr size_t kLandmarksCount = 33u; + const cv_wrapper::Point3f* points; + const float* visibility; + }; + enum LandmarkNames { NOSE = 0, LEFT_EYE_INNER, @@ -99,7 +106,7 @@ class DLLEXPORT PoseTracking { RIGHT_HEEL, LEFT_FOOT_INDEX, RIGHT_FOOT_INDEX, - COUNT = kLandmarksCount + COUNT = PoseLandmarks::kLandmarksCount }; PoseTracking(const char* calculatorGraphConfigFile); @@ -107,8 +114,7 @@ class DLLEXPORT PoseTracking { bool processFrame(const cv_wrapper::Mat& inputRGB8Bit); cv_wrapper::Mat lastSegmentedFrame(); - cv_wrapper::Point3f* lastDetectedLandmarks(); - float* lastLandmarksVisibility(); + PoseTracking::PoseLandmarks lastDetectedLandmarks(); private: PoseTrackingImpl* mImplementation;