128 lines
4.5 KiB
Plaintext
128 lines
4.5 KiB
Plaintext
# MediaPipe graph that performs multi-hand tracking on desktop with TensorFlow
|
|
# Lite on CPU.
|
|
# Used in the example in
|
|
# mediapipie/examples/desktop/hand_tracking:multi_hand_tracking_tflite.
|
|
|
|
# max_queue_size limits the number of packets enqueued on any input stream
|
|
# by throttling inputs to the graph. This makes the graph only process one
|
|
# frame per time.
|
|
max_queue_size: 1
|
|
|
|
# Decodes an input video file into images and a video header.
|
|
node {
|
|
calculator: "OpenCvVideoDecoderCalculator"
|
|
input_side_packet: "INPUT_FILE_PATH:input_video_path"
|
|
output_stream: "VIDEO:input_video"
|
|
output_stream: "VIDEO_PRESTREAM:input_video_header"
|
|
}
|
|
|
|
# Determines if an input vector of NormalizedRect has a size greater than or
|
|
# equal to the provided min_size.
|
|
node {
|
|
calculator: "NormalizedRectVectorHasMinSizeCalculator"
|
|
input_stream: "ITERABLE:prev_multi_hand_rects_from_landmarks"
|
|
output_stream: "prev_has_enough_hands"
|
|
node_options: {
|
|
[type.googleapis.com/mediapipe.CollectionHasMinSizeCalculatorOptions] {
|
|
# This value can be changed to support tracking arbitrary number of hands.
|
|
# Please also remember to modify max_vec_size in
|
|
# ClipVectorSizeCalculatorOptions in
|
|
# mediapipe/graphs/hand_tracking/subgraphs/multi_hand_detection_cpu.pbtxt
|
|
min_size: 2
|
|
}
|
|
}
|
|
}
|
|
|
|
# Drops the incoming image if the previous frame had at least N hands.
|
|
# Otherwise, passes the incoming image through to trigger a new round of hand
|
|
# detection in MultiHandDetectionSubgraph.
|
|
node {
|
|
calculator: "GateCalculator"
|
|
input_stream: "input_video"
|
|
input_stream: "DISALLOW:prev_has_enough_hands"
|
|
output_stream: "multi_hand_detection_input_video"
|
|
node_options: {
|
|
[type.googleapis.com/mediapipe.GateCalculatorOptions] {
|
|
empty_packets_as_allow: true
|
|
}
|
|
}
|
|
}
|
|
|
|
# Subgraph that detections hands (see multi_hand_detection_cpu.pbtxt).
|
|
node {
|
|
calculator: "MultiHandDetectionSubgraph"
|
|
input_stream: "multi_hand_detection_input_video"
|
|
output_stream: "DETECTIONS:multi_palm_detections"
|
|
output_stream: "NORM_RECTS:multi_palm_rects"
|
|
}
|
|
|
|
# Subgraph that localizes hand landmarks for multiple hands (see
|
|
# multi_hand_landmark.pbtxt).
|
|
node {
|
|
calculator: "MultiHandLandmarkSubgraph"
|
|
input_stream: "IMAGE:input_video"
|
|
input_stream: "NORM_RECTS:multi_hand_rects"
|
|
output_stream: "LANDMARKS:multi_hand_landmarks"
|
|
output_stream: "NORM_RECTS:multi_hand_rects_from_landmarks"
|
|
}
|
|
|
|
# Caches a hand rectangle fed back from MultiHandLandmarkSubgraph, and upon the
|
|
# arrival of the next input image sends out the cached rectangle with the
|
|
# timestamp replaced by that of the input image, essentially generating a packet
|
|
# that carries the previous hand rectangle. Note that upon the arrival of the
|
|
# very first input image, an empty packet is sent out to jump start the
|
|
# feedback loop.
|
|
node {
|
|
calculator: "PreviousLoopbackCalculator"
|
|
input_stream: "MAIN:input_video"
|
|
input_stream: "LOOP:multi_hand_rects_from_landmarks"
|
|
input_stream_info: {
|
|
tag_index: "LOOP"
|
|
back_edge: true
|
|
}
|
|
output_stream: "PREV_LOOP:prev_multi_hand_rects_from_landmarks"
|
|
}
|
|
|
|
# Performs association between NormalizedRect vector elements from previous
|
|
# frame and those from the current frame if MultiHandDetectionSubgraph runs.
|
|
# This calculator ensures that the output multi_hand_rects vector doesn't
|
|
# contain overlapping regions based on the specified min_similarity_threshold.
|
|
node {
|
|
calculator: "AssociationNormRectCalculator"
|
|
input_stream: "prev_multi_hand_rects_from_landmarks"
|
|
input_stream: "multi_palm_rects"
|
|
output_stream: "multi_hand_rects"
|
|
node_options: {
|
|
[type.googleapis.com/mediapipe.AssociationCalculatorOptions] {
|
|
min_similarity_threshold: 0.5
|
|
}
|
|
}
|
|
}
|
|
|
|
# Subgraph that renders annotations and overlays them on top of the input
|
|
# images (see multi_hand_renderer_cpu.pbtxt).
|
|
node {
|
|
calculator: "MultiHandRendererSubgraph"
|
|
input_stream: "IMAGE:input_video"
|
|
input_stream: "DETECTIONS:multi_palm_detections"
|
|
input_stream: "LANDMARKS:multi_hand_landmarks"
|
|
input_stream: "NORM_RECTS:0:multi_palm_rects"
|
|
input_stream: "NORM_RECTS:1:multi_hand_rects"
|
|
output_stream: "IMAGE:output_video"
|
|
}
|
|
|
|
# Encodes the annotated images into a video file, adopting properties specified
|
|
# in the input video header, e.g., video framerate.
|
|
node {
|
|
calculator: "OpenCvVideoEncoderCalculator"
|
|
input_stream: "VIDEO:output_video"
|
|
input_stream: "VIDEO_PRESTREAM:input_video_header"
|
|
input_side_packet: "OUTPUT_FILE_PATH:output_video_path"
|
|
node_options: {
|
|
[type.googleapis.com/mediapipe.OpenCvVideoEncoderCalculatorOptions]: {
|
|
codec: "avc1"
|
|
video_format: "mp4"
|
|
}
|
|
}
|
|
}
|