All Projects → madelinegannon → Example Mediapipe Udp

madelinegannon / Example Mediapipe Udp

Connecting openFrameworks to Google MediaPipe Machine Learning Framework over UDP

Programming Languages

cpp
1120 projects

Projects that are alternatives of or similar to Example Mediapipe Udp

DM-GY-9103-Advanced-Creative-Coding
Class repository for Advanced Creative Coding
Stars: ✭ 28 (-87.1%)
Mutual labels:  creative-coding, openframeworks
Mosaic
Mosaic, an openFrameworks based Visual Patching Creative-Coding Platform
Stars: ✭ 250 (+15.21%)
Mutual labels:  creative-coding, openframeworks
Ofxstatusbar
Addon for openFrameworks to add icons and text to the statusbar of Mac OS X (needs support - see readme)
Stars: ✭ 11 (-94.93%)
Mutual labels:  creative-coding, openframeworks
recoded
Re-coded by the School for Poetic Computation—crowdsourced recreations of early digital works using new tools
Stars: ✭ 57 (-73.73%)
Mutual labels:  creative-coding, openframeworks
ofxCorkCsg
A constructive solid geometry (mesh boolean) addon for openFrameworks.
Stars: ✭ 43 (-80.18%)
Mutual labels:  creative-coding, openframeworks
Ofelia
A real-time cross-platform creative coding tool for multimedia development
Stars: ✭ 269 (+23.96%)
Mutual labels:  creative-coding, openframeworks
Openframeworks
openFrameworks is a community-developed cross platform toolkit for creative coding in C++.
Stars: ✭ 8,652 (+3887.1%)
Mutual labels:  creative-coding, openframeworks
Gam
command line management for Google Workspace
Stars: ✭ 2,558 (+1078.8%)
Mutual labels:  google
Ohsce
PHP HI-REL SOCKET TCP/UDP/ICMP/Serial .高可靠性PHP通信&控制框架SOCKET-TCP/UDP/ICMP/硬件Serial-RS232/RS422/RS485 AND MORE!
Stars: ✭ 206 (-5.07%)
Mutual labels:  udp
Login With
Stateless login-with microservice for OAuth
Stars: ✭ 2,301 (+960.37%)
Mutual labels:  google
Asio2
Header only c++ network library, based on asio,support tcp,udp,http,websocket,rpc,ssl,icmp,serial_port.
Stars: ✭ 202 (-6.91%)
Mutual labels:  udp
Google Foobar
My Google Foo Bar Challenges 🤓 🧮
Stars: ✭ 202 (-6.91%)
Mutual labels:  google
Dc Sdk
DC-SDK 是基于 Cesium 进行二次开发的2、3D一体 WebGis 应用框架,该框架优化了 Cesium 的使用方式和增添了一些额外功能,旨在为开发者快速构建 WebGis 应用。🌎
Stars: ✭ 206 (-5.07%)
Mutual labels:  google
Google Maps Services Js
Node.js client library for Google Maps API Web Services
Stars: ✭ 2,432 (+1020.74%)
Mutual labels:  google
Googleanalyticsr
Use the Google Analytics API from R
Stars: ✭ 213 (-1.84%)
Mutual labels:  google
Googliser
a fast BASH multiple-image downloader
Stars: ✭ 202 (-6.91%)
Mutual labels:  google
Shrine Materialdesign2
implementation of Material Design 2 Shrine project
Stars: ✭ 215 (-0.92%)
Mutual labels:  google
React Native Google Sign In
React Native Wrapper for Latest Google Sign-In OAuth SDK / API
Stars: ✭ 213 (-1.84%)
Mutual labels:  google
Benchmarknet
Benchmark for testing the reliable UDP networking solutions
Stars: ✭ 206 (-5.07%)
Mutual labels:  udp
Frpc Android
Android,安卓版frpc,一个快速反向代理,可帮助您将NAT或防火墙后面的本地服务器暴露给Internet。
Stars: ✭ 205 (-5.53%)
Mutual labels:  udp

MediaPipe to openFrameworks

Notes on how to connect Google's MediaPipe ML Framework to openFrameworks

MediaPipe is a cross-platform framework for building multimodal applied machine learning pipelines. I want to be able to use it in external applications.

This tutorial walks through how to stream MediaPipe data out over UDP, so any external app and receive and use the data.

Demo Gif

I show how to modify the mediapipe example mediapipe/examples/desktop/hand_tracking to add in a new node that recieves hand tracking data as input, broadcasts that data over UDP on port 8080, and then passes the tracking data on to the rest of the graph as output.

Tested on macOS Mojave (10.14.6) and openFrameworks 0.10.1


Beigin by installing MediaPipe on your system using google's instructions.

Then install and setup Google Protobufs for openFrameworks using my previous tutorial.

If you've never used Bazel before, the build system and organization of Mediapipe can be really confusing. I try to go through step-by-step below, but you can find more information in the MediaPipe Docs.


We're going to modify MediaPipe's desktop hand tracking example to stream out landmarks and bounding rectangles over UDP.

MediaPipe to openFrameworks

1. Update the Graph Definition to Include our new PassThrough Calculator

Modify mediapipe/graphs/hand_tracking/hand_tracking_desktop_live.pbtxt

# Add New Node
node {
  calculator: "MyPassThroughCalculator"
  input_stream: "LANDMARKS:hand_landmarks"
  input_stream: "NORM_RECT:hand_rect"
  input_stream: "DETECTIONS:palm_detections"
  output_stream: "LANDMARKS:hand_landmarks_out"
  output_stream: "NORM_RECT:hand_rect_out"
  output_stream: "DETECTIONS:palm_detections_out"
}

# Modify input_stream names of next node

# Subgraph that renders annotations and overlays them on top of the input
# images (see renderer_cpu.pbtxt).
node {
  calculator: "RendererSubgraph"
  input_stream: "IMAGE:input_video"
  input_stream: "LANDMARKS:hand_landmarks_out"
  input_stream: "NORM_RECT:hand_rect_out"
  input_stream: "DETECTIONS:palm_detections_out"
  output_stream: "IMAGE:output_video"
}

NOTE You can visualize the graph to test that inputs and outpus match up at https://viz.mediapipe.dev/

When you add in the custom MyPassThroughCalculator your graph should look like this: Updated Graph Structure

2. Making a Custom Calculator

Adding UDP, Detections, Landmarks, and Hand Rectangles to the PassThrough Calculator

  1. Copy the file src/mediapipe/my_pass_though_calculator.cc to your Mediapipe calculators directory mediapipe/calculators/core.

  2. The main differences between my_pass_though_calculator.cc and the original pass_though_calculator.cc are that it adds UDP streaming, and uses Landmark, Rect, and Detection protobufs in the ::mediapipe::Status Process() function. Next we need to modify the graph file to declare the Tag of the calculators input and stream.

3. Modifying Calculators BUILD file

  1. Add the following in mediapipe/calculators/core/BUILD to include my_pass_through_calculator dependencies:
cc_library(
    name = "my_pass_through_calculator",
    srcs = ["my_pass_through_calculator.cc"],
    visibility = [
        "//visibility:public",
    ],
    deps = [
        "//mediapipe/framework:calculator_framework",
        "//mediapipe/framework/port:status",
        "//mediapipe/framework/formats:landmark_cc_proto",
        "//mediapipe/framework/formats:rect_cc_proto",
        "//mediapipe/framework/formats:detection_cc_proto",
        "//mediapipe/framework/formats:wrapper_hand_tracking_cc_proto",
    ],
    alwayslink = 1,
)

4. Modify the Graphs BUILD file

  1. Lastly, you need to modify the mediapipe/graphs/hand_tracking/BUILD file to add the new calculator as a dependency:
cc_library(
    name = "desktop_offline_calculators",
    deps = [
        "//mediapipe/calculators/core:flow_limiter_calculator",
        "//mediapipe/calculators/core:gate_calculator",
        "//mediapipe/calculators/core:immediate_mux_calculator",
        "//mediapipe/calculators/core:packet_inner_join_calculator",
        "//mediapipe/calculators/core:previous_loopback_calculator",
        "//mediapipe/calculators/video:opencv_video_decoder_calculator",
        "//mediapipe/calculators/video:opencv_video_encoder_calculator",
        "//mediapipe/calculators/core:my_pass_through_calculator"
    ],
)

5. Add the wrapper proto

  1. Copy the wrapper_hand_tracker.proto in this repo's /mediapipe directory into mediapipe/framework/formats directory.

  2. Add it and its dependencies to mediapipe/framework/formats/BUILD:

mediapipe_proto_library(
    name = "wrapper_hand_tracking_proto",
    srcs = ["wrapper_hand_tracking.proto"],
    visibility = ["//visibility:public"],
    deps = [
      "//mediapipe/framework/formats:landmark_proto",
      "//mediapipe/framework/formats:detection_proto",
      "//mediapipe/framework/formats:rect_proto",
    ],
)

You should be able to build and run the mediapipe hand_tracking_desktop_live example now without any errors. In your mediapipe root directory, run:

bazel build -c opt --define MEDIAPIPE_DISABLE_GPU=1     mediapipe/examples/desktop/hand_tracking:hand_tracking_cpu
GLOG_logtostderr=1 bazel-bin/mediapipe/examples/desktop/hand_tracking/hand_tracking_cpu     --calculator_graph_config_file=mediapipe/graphs/hand_tracking/hand_tracking_desktop_live.pbtxt

Sending Multiple Protobuf Messages over UDP

There's no good way to send multiple messages (like a LandmarkList, Rect, and DetectionList) in proto2. Therefore, you have to wrap those messages into a new protobuf.

I called mine wrapper_hand_tracking.proto and added it and its dependencies to mediapipe/framework/formats/BUILD.

Here's a roadblock I hit:

  • MediaPipe uses protobuf-3.11.4 and is built with Bazel, but I'm using protobuf-3.6.1 for openFrameworks, and it builds with CMake.
  • So if I link the wrapper_hand_tracking.proto generated with Bazel to the openFrameworks project, there are compatibility issues with the protobuf static library I've already built and linked.

So the hacky workaround I found was to build wrapper_hand_tracking.proto with the MediaPipe build system, and then rebuild it with my system-wide protobuf installation. Here's what I did ... in the top-level /mediapipe directory:

  1. First build with the .proto with bazel.
    • Most of wrapper_hand_tracking.proto file is commented out, just leaving the import calls to link to dependent protos.
  2. Second, uncomment the .proto and rebuild with protoc.
    • For openFrameworks, I've altread built a separate static protobuf library for openFrameworks using my previous tutorial. I need to generate the .pb.h and .pb.cc files from wrapper_hand_tracking.proto using this library.
    • In wrapper_hand_tracking.proto, comment out the import calls at the top of the file, and uncomment the body of the proto (protoc doesn't link dependencies, so I just copied all the necessary protobufs into this one file).
    • Go into the mediapipes\framework\formats directory and run protoc --cpp_out=. wrapper_hand_tracking.proto
    • Move those wrapper_hand_tracking.pb.h and wrapper_hand_tracking.pb.cc files over to your openFrameworks src folder.
    • Drag and drop these two files into your openFrameworks project (be sure to check "Add to Project").
    • There shouldn't be any errors now when you add #include "wrapper_hand_tracking.pb.h" to ofApp.h

Running the Example

When you run the MediaPipe example hand_tracking_desktop_live, it broadcasts any hand landmarks and rectangles on port localhost:8080. The openFrameworks example example-protobuf-udp is listening for those protobufs on port 8080.

Run the MediaPipe Example

  1. From your MediaPipe root directory, run hand_tracking_desktop_live:
GLOG_logtostderr=1 bazel-bin/mediapipe/examples/desktop/hand_tracking/hand_tracking_cpu     --calculator_graph_config_file=mediapipe/graphs/hand_tracking/hand_tracking_desktop_live.pbtxt

You should see a video feed of yourself, with hand landmarks and bounding rectangle overlaid.

Run the openFrameworks Example

  1. Build example-protobuf-udp in openFramework's Project Generator

  2. Drag and drop the /libs directory into the Xcode Project Pane and select Add to Target.

  3. Drag and drop your newly generated wrapper_hand_tracking.pb.cc and wrapper_hand_tracking.pb.h files into the /src directory in the Project Pane and select Add to Target.

  4. Link the libprotobuf.a static library from /libs/protobuf/lib/osx in Project Settings > General > Linked Frameworks and Libraries.

  5. In Project Settings > Build Settings, add the following to Header Search Paths:

$(PROJECT_DIR)/libs/protobuf/include
$(PROJECT_DIR)/libs/protobuf/include/google
$(PROJECT_DIR)/libs/protobuf/include/google/compiler
$(PROJECT_DIR)/libs/protobuf/include/google/compiler/cpp
$(PROJECT_DIR)/libs/protobuf/include/google/io
$(PROJECT_DIR)/libs/protobuf/include/google/stubs
$(PROJECT_DIR)/libs/protobuf/include/google/util
  1. Hit ⌘-r to Run.

You should see the numbered landmarks and bounding rectangle on a white screen.

Press 'SPACE' to use your hand to swat around some particles.

Note: The example runs on the cpu, so it's a little slow. But the framerate improves a bit once a hand is detected.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].