Project import generated by Copybara.
PiperOrigin-RevId: 254856010
This commit is contained in:
parent
fcb23fd99d
commit
2aaf4693db
2
.bazelrc
2
.bazelrc
|
@ -12,6 +12,8 @@ build --copt='-Wno-comment'
|
||||||
build --copt='-Wno-return-type'
|
build --copt='-Wno-return-type'
|
||||||
build --copt='-Wno-unused-local-typedefs'
|
build --copt='-Wno-unused-local-typedefs'
|
||||||
build --copt='-Wno-ignored-attributes'
|
build --copt='-Wno-ignored-attributes'
|
||||||
|
# Temporarily set the incompatiblity flag for Bazel 0.27.0 and above
|
||||||
|
build --incompatible_disable_deprecated_attr_params=false
|
||||||
|
|
||||||
# Sets the default Apple platform to macOS.
|
# Sets the default Apple platform to macOS.
|
||||||
build --apple_platform_type=macos
|
build --apple_platform_type=macos
|
||||||
|
|
21
README.md
21
README.md
|
@ -1,9 +1,7 @@
|
||||||
![MediaPipe](mediapipe/docs/images/mediapipe_small.png?raw=true "MediaPipe logo")
|
![MediaPipe](mediapipe/docs/images/mediapipe_small.png?raw=true "MediaPipe logo")
|
||||||
=======================================================================
|
=======================================================================
|
||||||
|
|
||||||
#### We will be [presenting at CVPR 2019](https://sites.google.com/corp/view/perception-cv4arvr/mediapipe) on June 17~20 in Long Beach, CA. Come join us!
|
[MediaPipe](http://mediapipe.dev) is a framework for building multimodal (eg. video, audio, any time series data) applied ML pipelines. With MediaPipe, a perception pipeline can be built as a graph of modular components, including, for instance, inference models (e.g., TensorFlow, TFLite) and media processing functions. http://mediapipe.dev
|
||||||
|
|
||||||
[MediaPipe](http://g.co/mediapipe) is a framework for building multimodal (eg. video, audio, any time series data) applied ML pipelines. With MediaPipe, a perception pipeline can be built as a graph of modular components, including, for instance, inference models (e.g., TensorFlow, TFLite) and media processing functions.
|
|
||||||
|
|
||||||
![Real-time Face Detection](mediapipe/docs/images/realtime_face_detection.gif)
|
![Real-time Face Detection](mediapipe/docs/images/realtime_face_detection.gif)
|
||||||
|
|
||||||
|
@ -14,13 +12,24 @@ Follow these [instructions](mediapipe/docs/install.md).
|
||||||
See mobile and desktop [examples](mediapipe/docs/examples.md).
|
See mobile and desktop [examples](mediapipe/docs/examples.md).
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
[MediaPipe Read-the-Docs](https://mediapipe.readthedocs.io/).
|
[MediaPipe Read-the-Docs](https://mediapipe.readthedocs.io/) or [docs.mediapipe.dev](https://docs.mediapipe.dev)
|
||||||
|
|
||||||
|
Check out the [Examples page] for tutorials on how to use MediaPipe. [Concepts page](https://mediapipe.readthedocs.io/en/latest/concepts.html) for basic definitions
|
||||||
|
|
||||||
## Visualizing MediaPipe graphs
|
## Visualizing MediaPipe graphs
|
||||||
A web-based visualizer is hosted on [MediaPipe Visualizer](https://mediapipe-viz.appspot.com/). Please also see instructions [here](mediapipe/docs/visualizer.md).
|
A web-based visualizer is hosted on [viz.mediapipe.dev](https://viz.mediapipe.dev/). Please also see instructions [here](mediapipe/docs/visualizer.md).
|
||||||
|
|
||||||
|
## Community forum
|
||||||
|
* [discuss](https://groups.google.com/forum/#!forum/mediapipe) - General community discussion around MediaPipe
|
||||||
|
|
||||||
## Publications
|
## Publications
|
||||||
* [MediaPipe: A Framework for Building Perception Pipelines](https://tiny.cc/mediapipe_paper) (draft)
|
* [MediaPipe: A Framework for Building Perception Pipelines](https://arxiv.org/abs/1906.08172)
|
||||||
|
|
||||||
|
## Events
|
||||||
|
[Open sourced at CVPR 2019](https://sites.google.com/corp/view/perception-cv4arvr/mediapipe) on June 17~20 in Long Beach, CA
|
||||||
|
|
||||||
|
## Alpha Disclaimer
|
||||||
|
MediaPipe is currently in alpha for v0.5. We are still making breaking API changes and expect to get to stable API by v1.0.
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
We welcome contributions. Please follow these [guidelines](./CONTRIBUTING.md).
|
We welcome contributions. Please follow these [guidelines](./CONTRIBUTING.md).
|
||||||
|
|
|
@ -246,6 +246,23 @@ cc_library(
|
||||||
alwayslink = 1,
|
alwayslink = 1,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
cc_library(
|
||||||
|
name = "image_cropping_calculator",
|
||||||
|
srcs = ["image_cropping_calculator.cc"],
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
deps = [
|
||||||
|
"//mediapipe/framework:calculator_framework",
|
||||||
|
"//mediapipe/framework/formats:image_frame",
|
||||||
|
"//mediapipe/framework/formats:image_frame_opencv",
|
||||||
|
"//mediapipe/framework/formats:rect_cc_proto",
|
||||||
|
"//mediapipe/framework/port:opencv_core",
|
||||||
|
"//mediapipe/framework/port:opencv_imgproc",
|
||||||
|
"//mediapipe/framework/port:ret_check",
|
||||||
|
"//mediapipe/framework/port:status",
|
||||||
|
],
|
||||||
|
alwayslink = 1,
|
||||||
|
)
|
||||||
|
|
||||||
cc_library(
|
cc_library(
|
||||||
name = "luminance_calculator",
|
name = "luminance_calculator",
|
||||||
srcs = ["luminance_calculator.cc"],
|
srcs = ["luminance_calculator.cc"],
|
||||||
|
|
150
mediapipe/calculators/image/image_cropping_calculator.cc
Normal file
150
mediapipe/calculators/image/image_cropping_calculator.cc
Normal file
|
@ -0,0 +1,150 @@
|
||||||
|
// Copyright 2019 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.
|
||||||
|
|
||||||
|
#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/rect.pb.h"
|
||||||
|
#include "mediapipe/framework/port/opencv_core_inc.h"
|
||||||
|
#include "mediapipe/framework/port/opencv_imgproc_inc.h"
|
||||||
|
#include "mediapipe/framework/port/ret_check.h"
|
||||||
|
#include "mediapipe/framework/port/status.h"
|
||||||
|
|
||||||
|
namespace mediapipe {
|
||||||
|
|
||||||
|
// Crops the input texture to the given rectangle region. The rectangle can
|
||||||
|
// be at arbitrary location on the image with rotation. If there's rotation, the
|
||||||
|
// output texture will have the size of the input rectangle. The rotation should
|
||||||
|
// be in radian, see rect.proto for detail.
|
||||||
|
// Currently it only works for CPU.
|
||||||
|
//
|
||||||
|
// Input:
|
||||||
|
// IMAGE: ImageFrame representing the input image.
|
||||||
|
// One of the following two tags:
|
||||||
|
// RECT - A Rect proto specifying the width/height and location of the
|
||||||
|
// cropping rectangle.
|
||||||
|
// NORM_RECT - A NormalizedRect proto specifying the width/height and location
|
||||||
|
// of the cropping rectangle in normalized coordinates.
|
||||||
|
//
|
||||||
|
// Output:
|
||||||
|
// IMAGE - Cropped frames.
|
||||||
|
class ImageCroppingCalculator : public CalculatorBase {
|
||||||
|
public:
|
||||||
|
ImageCroppingCalculator() = default;
|
||||||
|
~ImageCroppingCalculator() override = default;
|
||||||
|
|
||||||
|
static ::mediapipe::Status GetContract(CalculatorContract* cc);
|
||||||
|
::mediapipe::Status Process(CalculatorContext* cc) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
::mediapipe::Status RenderCpu(CalculatorContext* cc);
|
||||||
|
::mediapipe::Status RenderGpu(CalculatorContext* cc);
|
||||||
|
|
||||||
|
// TODO: Merge with GlCroppingCalculator to have GPU support.
|
||||||
|
bool use_gpu_{};
|
||||||
|
};
|
||||||
|
REGISTER_CALCULATOR(ImageCroppingCalculator);
|
||||||
|
|
||||||
|
::mediapipe::Status ImageCroppingCalculator::GetContract(
|
||||||
|
CalculatorContract* cc) {
|
||||||
|
RET_CHECK(cc->Inputs().HasTag("IMAGE"));
|
||||||
|
RET_CHECK(cc->Outputs().HasTag("IMAGE"));
|
||||||
|
|
||||||
|
cc->Inputs().Tag("IMAGE").Set<ImageFrame>();
|
||||||
|
|
||||||
|
if (cc->Inputs().HasTag("RECT")) {
|
||||||
|
cc->Inputs().Tag("RECT").Set<Rect>();
|
||||||
|
}
|
||||||
|
if (cc->Inputs().HasTag("NORM_RECT")) {
|
||||||
|
cc->Inputs().Tag("NORM_RECT").Set<NormalizedRect>();
|
||||||
|
}
|
||||||
|
|
||||||
|
cc->Outputs().Tag("IMAGE").Set<ImageFrame>();
|
||||||
|
|
||||||
|
return ::mediapipe::OkStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
::mediapipe::Status ImageCroppingCalculator::Process(CalculatorContext* cc) {
|
||||||
|
if (use_gpu_) {
|
||||||
|
RETURN_IF_ERROR(RenderGpu(cc));
|
||||||
|
} else {
|
||||||
|
RETURN_IF_ERROR(RenderCpu(cc));
|
||||||
|
}
|
||||||
|
return ::mediapipe::OkStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
::mediapipe::Status ImageCroppingCalculator::RenderCpu(CalculatorContext* cc) {
|
||||||
|
const auto& input_img = cc->Inputs().Tag("IMAGE").Get<ImageFrame>();
|
||||||
|
cv::Mat input_mat = formats::MatView(&input_img);
|
||||||
|
|
||||||
|
float rect_center_x = input_img.Width() / 2.0f;
|
||||||
|
float rect_center_y = input_img.Height() / 2.0f;
|
||||||
|
float rotation = 0.0f;
|
||||||
|
int target_width = input_img.Width();
|
||||||
|
int target_height = input_img.Height();
|
||||||
|
if (cc->Inputs().HasTag("RECT")) {
|
||||||
|
const auto& rect = cc->Inputs().Tag("RECT").Get<Rect>();
|
||||||
|
if (rect.width() > 0 && rect.height() > 0 && rect.x_center() >= 0 &&
|
||||||
|
rect.y_center() >= 0) {
|
||||||
|
rotation = rect.rotation();
|
||||||
|
rect_center_x = rect.x_center();
|
||||||
|
rect_center_y = rect.y_center();
|
||||||
|
target_width = rect.width();
|
||||||
|
target_height = rect.height();
|
||||||
|
}
|
||||||
|
} else if (cc->Inputs().HasTag("NORM_RECT")) {
|
||||||
|
const auto& rect = cc->Inputs().Tag("NORM_RECT").Get<NormalizedRect>();
|
||||||
|
if (rect.width() > 0.0 && rect.height() > 0.0 && rect.x_center() >= 0.0 &&
|
||||||
|
rect.y_center() >= 0.0) {
|
||||||
|
rotation = rect.rotation();
|
||||||
|
rect_center_x = std::round(rect.x_center() * input_img.Width());
|
||||||
|
rect_center_y = std::round(rect.y_center() * input_img.Height());
|
||||||
|
target_width = std::round(rect.width() * input_img.Width());
|
||||||
|
target_height = std::round(rect.height() * input_img.Height());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::Mat rotated_mat;
|
||||||
|
if (std::abs(rotation) > 1e-5) {
|
||||||
|
// TODO: Use open source common math library.
|
||||||
|
const float pi = 3.1415926f;
|
||||||
|
rotation = rotation * 180.0 / pi;
|
||||||
|
|
||||||
|
// First rotation the image.
|
||||||
|
cv::Point2f src_center(rect_center_x, rect_center_y);
|
||||||
|
cv::Mat rotation_mat = cv::getRotationMatrix2D(src_center, rotation, 1.0);
|
||||||
|
cv::warpAffine(input_mat, rotated_mat, rotation_mat, input_mat.size());
|
||||||
|
} else {
|
||||||
|
input_mat.copyTo(rotated_mat);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then crop the requested area.
|
||||||
|
const cv::Rect cropping_rect(rect_center_x - target_width / 2,
|
||||||
|
rect_center_y - target_height / 2, target_width,
|
||||||
|
target_height);
|
||||||
|
cv::Mat cropped_image = cv::Mat(rotated_mat, cropping_rect);
|
||||||
|
|
||||||
|
std::unique_ptr<ImageFrame> output_frame(new ImageFrame(
|
||||||
|
input_img.Format(), cropped_image.cols, cropped_image.rows));
|
||||||
|
cv::Mat output_mat = formats::MatView(output_frame.get());
|
||||||
|
cropped_image.copyTo(output_mat);
|
||||||
|
cc->Outputs().Tag("IMAGE").Add(output_frame.release(), cc->InputTimestamp());
|
||||||
|
return ::mediapipe::OkStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
::mediapipe::Status ImageCroppingCalculator::RenderGpu(CalculatorContext* cc) {
|
||||||
|
return ::mediapipe::UnimplementedError("GPU support is not implemented yet.");
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mediapipe
|
|
@ -300,6 +300,37 @@ REGISTER_CALCULATOR(ImageTransformationCalculator);
|
||||||
int input_width = cc->Inputs().Tag("IMAGE").Get<ImageFrame>().Width();
|
int input_width = cc->Inputs().Tag("IMAGE").Get<ImageFrame>().Width();
|
||||||
int input_height = cc->Inputs().Tag("IMAGE").Get<ImageFrame>().Height();
|
int input_height = cc->Inputs().Tag("IMAGE").Get<ImageFrame>().Height();
|
||||||
|
|
||||||
|
const auto& input_img = cc->Inputs().Tag("IMAGE").Get<ImageFrame>();
|
||||||
|
cv::Mat input_mat = formats::MatView(&input_img);
|
||||||
|
cv::Mat scaled_mat;
|
||||||
|
|
||||||
|
if (scale_mode_ == mediapipe::ScaleMode_Mode_STRETCH) {
|
||||||
|
cv::resize(input_mat, scaled_mat, cv::Size(output_width_, output_height_));
|
||||||
|
} else {
|
||||||
|
const float scale =
|
||||||
|
std::min(static_cast<float>(output_width_) / input_width,
|
||||||
|
static_cast<float>(output_height_) / input_height);
|
||||||
|
const int target_width = std::round(input_width * scale);
|
||||||
|
const int target_height = std::round(input_height * scale);
|
||||||
|
|
||||||
|
if (scale_mode_ == mediapipe::ScaleMode_Mode_FIT) {
|
||||||
|
cv::Mat intermediate_mat;
|
||||||
|
cv::resize(input_mat, intermediate_mat,
|
||||||
|
cv::Size(target_width, target_height));
|
||||||
|
const int top = (output_height_ - target_height) / 2;
|
||||||
|
const int bottom = output_height_ - target_height - top;
|
||||||
|
const int left = (output_width_ - target_width) / 2;
|
||||||
|
const int right = output_width_ - target_width - left;
|
||||||
|
cv::copyMakeBorder(intermediate_mat, scaled_mat, top, bottom, left, right,
|
||||||
|
options_.constant_padding() ? cv::BORDER_CONSTANT
|
||||||
|
: cv::BORDER_REPLICATE);
|
||||||
|
} else {
|
||||||
|
cv::resize(input_mat, scaled_mat, cv::Size(target_width, target_height));
|
||||||
|
output_width_ = target_width;
|
||||||
|
output_height_ = target_height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int output_width;
|
int output_width;
|
||||||
int output_height;
|
int output_height;
|
||||||
ComputeOutputDimensions(input_width, input_height, &output_width,
|
ComputeOutputDimensions(input_width, input_height, &output_width,
|
||||||
|
@ -318,26 +349,15 @@ REGISTER_CALCULATOR(ImageTransformationCalculator);
|
||||||
cc->InputSidePackets().Tag("ROTATION_DEGREES").Get<int>());
|
cc->InputSidePackets().Tag("ROTATION_DEGREES").Get<int>());
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& input_img = cc->Inputs().Tag("IMAGE").Get<ImageFrame>();
|
|
||||||
std::unique_ptr<ImageFrame> output_frame(
|
|
||||||
new ImageFrame(input_img.Format(), output_width, output_height));
|
|
||||||
cv::Mat input_mat = formats::MatView(&input_img);
|
|
||||||
cv::Mat output_mat = formats::MatView(output_frame.get());
|
|
||||||
|
|
||||||
cv::Mat scaled_mat;
|
|
||||||
if (scale_mode_ != mediapipe::ScaleMode_Mode_STRETCH) {
|
|
||||||
// TODO finish CPU version features.
|
|
||||||
return ::mediapipe::UnimplementedError(
|
|
||||||
"Only STRETCH scale mode currently supported.");
|
|
||||||
}
|
|
||||||
cv::resize(input_mat, scaled_mat, cv::Size(output_width_, output_height_));
|
|
||||||
|
|
||||||
cv::Mat rotated_mat;
|
cv::Mat rotated_mat;
|
||||||
const int angle = RotationModeToDegrees(rotation_);
|
const int angle = RotationModeToDegrees(rotation_);
|
||||||
cv::Point2f src_center(scaled_mat.cols / 2.0, scaled_mat.rows / 2.0);
|
cv::Point2f src_center(scaled_mat.cols / 2.0, scaled_mat.rows / 2.0);
|
||||||
cv::Mat rotation_mat = cv::getRotationMatrix2D(src_center, angle, 1.0);
|
cv::Mat rotation_mat = cv::getRotationMatrix2D(src_center, angle, 1.0);
|
||||||
cv::warpAffine(scaled_mat, rotated_mat, rotation_mat, scaled_mat.size());
|
cv::warpAffine(scaled_mat, rotated_mat, rotation_mat, scaled_mat.size());
|
||||||
|
|
||||||
|
std::unique_ptr<ImageFrame> output_frame(
|
||||||
|
new ImageFrame(input_img.Format(), output_width, output_height));
|
||||||
|
cv::Mat output_mat = formats::MatView(output_frame.get());
|
||||||
rotated_mat.copyTo(output_mat);
|
rotated_mat.copyTo(output_mat);
|
||||||
cc->Outputs().Tag("IMAGE").Add(output_frame.release(), cc->InputTimestamp());
|
cc->Outputs().Tag("IMAGE").Add(output_frame.release(), cc->InputTimestamp());
|
||||||
|
|
||||||
|
|
|
@ -46,4 +46,8 @@ message ImageTransformationCalculatorOptions {
|
||||||
optional bool flip_horizontally = 5 [default = false];
|
optional bool flip_horizontally = 5 [default = false];
|
||||||
// Scale mode.
|
// Scale mode.
|
||||||
optional ScaleMode.Mode scale_mode = 6;
|
optional ScaleMode.Mode scale_mode = 6;
|
||||||
|
// Padding type. This option is only used when the scale mode is FIT.
|
||||||
|
// Default is to use BORDER_CONSTANT. If set to false, it will use
|
||||||
|
// BORDER_REPLICATE instead.
|
||||||
|
optional bool constant_padding = 7 [default = true];
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,6 +84,11 @@ class DetectionLetterboxRemovalCalculator : public CalculatorBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
::mediapipe::Status Process(CalculatorContext* cc) override {
|
::mediapipe::Status Process(CalculatorContext* cc) override {
|
||||||
|
// Only process if there's input detections.
|
||||||
|
if (cc->Inputs().Tag(kDetectionsTag).IsEmpty()) {
|
||||||
|
return ::mediapipe::OkStatus();
|
||||||
|
}
|
||||||
|
|
||||||
const auto& input_detections =
|
const auto& input_detections =
|
||||||
cc->Inputs().Tag(kDetectionsTag).Get<std::vector<Detection>>();
|
cc->Inputs().Tag(kDetectionsTag).Get<std::vector<Detection>>();
|
||||||
const auto& letterbox_padding =
|
const auto& letterbox_padding =
|
||||||
|
|
|
@ -323,6 +323,9 @@ class NonMaxSuppressionCalculator : public CalculatorBase {
|
||||||
}
|
}
|
||||||
auto weighted_detection = detection;
|
auto weighted_detection = detection;
|
||||||
if (!candidates.empty()) {
|
if (!candidates.empty()) {
|
||||||
|
const int num_keypoints =
|
||||||
|
detection.location_data().relative_keypoints_size();
|
||||||
|
std::vector<float> keypoints(num_keypoints * 2);
|
||||||
float w_xmin = 0.0f;
|
float w_xmin = 0.0f;
|
||||||
float w_ymin = 0.0f;
|
float w_ymin = 0.0f;
|
||||||
float w_xmax = 0.0f;
|
float w_xmax = 0.0f;
|
||||||
|
@ -330,13 +333,20 @@ class NonMaxSuppressionCalculator : public CalculatorBase {
|
||||||
float total_score = 0.0f;
|
float total_score = 0.0f;
|
||||||
for (const auto& candidate : candidates) {
|
for (const auto& candidate : candidates) {
|
||||||
total_score += candidate.second;
|
total_score += candidate.second;
|
||||||
const auto& bbox = detections[candidate.first]
|
const auto& location_data =
|
||||||
.location_data()
|
detections[candidate.first].location_data();
|
||||||
.relative_bounding_box();
|
const auto& bbox = location_data.relative_bounding_box();
|
||||||
w_xmin += bbox.xmin() * candidate.second;
|
w_xmin += bbox.xmin() * candidate.second;
|
||||||
w_ymin += bbox.ymin() * candidate.second;
|
w_ymin += bbox.ymin() * candidate.second;
|
||||||
w_xmax += (bbox.xmin() + bbox.width()) * candidate.second;
|
w_xmax += (bbox.xmin() + bbox.width()) * candidate.second;
|
||||||
w_ymax += (bbox.ymin() + bbox.height()) * candidate.second;
|
w_ymax += (bbox.ymin() + bbox.height()) * candidate.second;
|
||||||
|
|
||||||
|
for (int i = 0; i < num_keypoints; ++i) {
|
||||||
|
keypoints[i * 2] +=
|
||||||
|
location_data.relative_keypoints(i).x() * candidate.second;
|
||||||
|
keypoints[i * 2 + 1] +=
|
||||||
|
location_data.relative_keypoints(i).y() * candidate.second;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
auto* weighted_location = weighted_detection.mutable_location_data()
|
auto* weighted_location = weighted_detection.mutable_location_data()
|
||||||
->mutable_relative_bounding_box();
|
->mutable_relative_bounding_box();
|
||||||
|
@ -346,6 +356,12 @@ class NonMaxSuppressionCalculator : public CalculatorBase {
|
||||||
weighted_location->xmin());
|
weighted_location->xmin());
|
||||||
weighted_location->set_height((w_ymax / total_score) -
|
weighted_location->set_height((w_ymax / total_score) -
|
||||||
weighted_location->ymin());
|
weighted_location->ymin());
|
||||||
|
for (int i = 0; i < num_keypoints; ++i) {
|
||||||
|
auto* keypoint = weighted_detection.mutable_location_data()
|
||||||
|
->mutable_relative_keypoints(i);
|
||||||
|
keypoint->set_x(keypoints[i * 2] / total_score);
|
||||||
|
keypoint->set_y(keypoints[i * 2 + 1] / total_score);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
remained_indexed_scores = std::move(remained);
|
remained_indexed_scores = std::move(remained);
|
||||||
output_detections->push_back(weighted_detection);
|
output_detections->push_back(weighted_detection);
|
||||||
|
|
|
@ -29,7 +29,7 @@ adb install bazel-bin/mediapipe/examples/android/src/java/com/google/mediapipe/a
|
||||||
![face_detection_android_gpu_graph](images/mobile/face_detection_android_gpu.png){width="400"}
|
![face_detection_android_gpu_graph](images/mobile/face_detection_android_gpu.png){width="400"}
|
||||||
|
|
||||||
To visualize the graph as shown above, copy the text specification of the graph
|
To visualize the graph as shown above, copy the text specification of the graph
|
||||||
below and paste it into [MediaPipe Visualizer](https://mediapipe-viz.appspot.com/).
|
below and paste it into [MediaPipe Visualizer](https://viz.mediapipe.dev/).
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# MediaPipe graph that performs object detection with TensorFlow Lite on GPU.
|
# MediaPipe graph that performs object detection with TensorFlow Lite on GPU.
|
||||||
|
|
|
@ -29,7 +29,7 @@ adb install bazel-bin/mediapipe/examples/android/src/java/com/google/mediapipe/a
|
||||||
![hair_segmentation_android_gpu_graph](images/mobile/hair_segmentation_android_gpu.png){width="600"}
|
![hair_segmentation_android_gpu_graph](images/mobile/hair_segmentation_android_gpu.png){width="600"}
|
||||||
|
|
||||||
To visualize the graph as shown above, copy the text specification of the graph
|
To visualize the graph as shown above, copy the text specification of the graph
|
||||||
below and paste it into [MediaPipe Visualizer](https://mediapipe-viz.appspot.com/).
|
below and paste it into [MediaPipe Visualizer](https://viz.mediapipe.dev/).
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# MediaPipe graph that performs hair segmentation with TensorFlow Lite on GPU.
|
# MediaPipe graph that performs hair segmentation with TensorFlow Lite on GPU.
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
```
|
```
|
||||||
|
|
||||||
You can visualize this graph using
|
You can visualize this graph using
|
||||||
[MediaPipe Visualizer](https://mediapipe-viz.appspot.com) by pasting the
|
[MediaPipe Visualizer](https://viz.mediapipe.dev) by pasting the
|
||||||
CalculatorGraphConfig content below into the visualizer. See
|
CalculatorGraphConfig content below into the visualizer. See
|
||||||
[here](./visualizer.md) for help on the visualizer.
|
[here](./visualizer.md) for help on the visualizer.
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,10 @@ APIs for MediaPipe
|
||||||
* Graph Execution API in Java (Android)
|
* Graph Execution API in Java (Android)
|
||||||
* (Coming Soon) Graph Execution API in Objective-C (iOS)
|
* (Coming Soon) Graph Execution API in Objective-C (iOS)
|
||||||
|
|
||||||
|
Alpha Disclaimer
|
||||||
|
==================
|
||||||
|
MediaPipe is currently in alpha for v0.5. We are still making breaking API changes and expect to get to stable API by v1.0. We recommend that you target a specific version of MediaPipe, and periodically bump to the latest release. That way you have control over when a breaking change affects you.
|
||||||
|
|
||||||
User Documentation
|
User Documentation
|
||||||
==================
|
==================
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ Required libraries
|
||||||
|
|
||||||
* Android SDK release 28.0.3 and above
|
* Android SDK release 28.0.3 and above
|
||||||
|
|
||||||
* Android NDK r18b and above
|
* Android NDK r17c and above
|
||||||
|
|
||||||
### Installing on Debian and Ubuntu
|
### Installing on Debian and Ubuntu
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ adb install bazel-bin/mediapipe/examples/android/src/java/com/google/mediapipe/a
|
||||||
![object_detection_android_cpu_graph](images/mobile/object_detection_android_cpu.png){width="400"}
|
![object_detection_android_cpu_graph](images/mobile/object_detection_android_cpu.png){width="400"}
|
||||||
|
|
||||||
To visualize the graph as shown above, copy the text specification of the graph
|
To visualize the graph as shown above, copy the text specification of the graph
|
||||||
below and paste it into [MediaPipe Visualizer](https://mediapipe-viz.appspot.com/).
|
below and paste it into [MediaPipe Visualizer](https://viz.mediapipe.dev/).
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# MediaPipe graph that performs object detection with TensorFlow Lite on CPU.
|
# MediaPipe graph that performs object detection with TensorFlow Lite on CPU.
|
||||||
|
|
|
@ -29,7 +29,7 @@ adb install bazel-bin/mediapipe/examples/android/src/java/com/google/mediapipe/a
|
||||||
![object_detection_android_gpu_graph](images/mobile/object_detection_android_gpu.png){width="400"}
|
![object_detection_android_gpu_graph](images/mobile/object_detection_android_gpu.png){width="400"}
|
||||||
|
|
||||||
To visualize the graph as shown above, copy the text specification of the graph
|
To visualize the graph as shown above, copy the text specification of the graph
|
||||||
below and paste it into [MediaPipe Visualizer](https://mediapipe-viz.appspot.com/).
|
below and paste it into [MediaPipe Visualizer](https://viz.mediapipe.dev/).
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# MediaPipe graph that performs object detection with TensorFlow Lite on GPU.
|
# MediaPipe graph that performs object detection with TensorFlow Lite on GPU.
|
||||||
|
|
|
@ -8,7 +8,14 @@ interested in running the same TensorfFlow Lite model on Android, please see the
|
||||||
[Object Detection on GPU on Android](object_detection_android_gpu.md) and
|
[Object Detection on GPU on Android](object_detection_android_gpu.md) and
|
||||||
[Object Detection on CPU on Android](object_detection_android_cpu.md) examples.
|
[Object Detection on CPU on Android](object_detection_android_cpu.md) examples.
|
||||||
|
|
||||||
### TensorFlow Model
|
We show the object detection demo with both TensorFlow model and TensorFlow Lite model:
|
||||||
|
|
||||||
|
- [TensorFlow Object Detection Demo](#tensorflow-object-detection-demo)
|
||||||
|
- [TensorFlow Lite Object Detection Demo](#tensorflow-lite-object-detection-demo)
|
||||||
|
|
||||||
|
Note: If MediaPipe depends on OpenCV 2, please see the [known issues with OpenCV 2](#known-issues-with-opencv-2) section.
|
||||||
|
|
||||||
|
### TensorFlow Object Detection Demo
|
||||||
|
|
||||||
To build and run the TensorFlow example on desktop, run:
|
To build and run the TensorFlow example on desktop, run:
|
||||||
|
|
||||||
|
@ -40,7 +47,7 @@ $ bazel-bin/mediapipe/examples/desktop/object_detection/object_detection_tensorf
|
||||||
|
|
||||||
To visualize the graph as shown above, copy the text specification of the graph
|
To visualize the graph as shown above, copy the text specification of the graph
|
||||||
below and paste it into
|
below and paste it into
|
||||||
[MediaPipe Visualizer](https://mediapipe-viz.appspot.com).
|
[MediaPipe Visualizer](https://viz.mediapipe.dev).
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# MediaPipe graph that performs object detection on desktop with TensorFlow
|
# MediaPipe graph that performs object detection on desktop with TensorFlow
|
||||||
|
@ -176,7 +183,7 @@ node {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### TensorFlow Lite Model
|
### TensorFlow Lite Object Detection Demo
|
||||||
|
|
||||||
To build and run the TensorFlow Lite example on desktop, run:
|
To build and run the TensorFlow Lite example on desktop, run:
|
||||||
|
|
||||||
|
@ -204,7 +211,7 @@ $ bazel-bin/mediapipe/examples/desktop/object_detection/object_detection_tflite
|
||||||
|
|
||||||
To visualize the graph as shown above, copy the text specification of the graph
|
To visualize the graph as shown above, copy the text specification of the graph
|
||||||
below and paste it into
|
below and paste it into
|
||||||
[MediaPipe Visualizer](https://mediapipe-viz.appspot.com).
|
[MediaPipe Visualizer](https://viz.mediapipe.dev).
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# MediaPipe graph that performs object detection on desktop with TensorFlow Lite
|
# MediaPipe graph that performs object detection on desktop with TensorFlow Lite
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
To help users understand the structure of their calculator graphs and to
|
To help users understand the structure of their calculator graphs and to
|
||||||
understand the overall behavior of their machine learning inference pipelines,
|
understand the overall behavior of their machine learning inference pipelines,
|
||||||
we have built the [MediaPipe Visualizer](https://mediapipe-viz.appspot.com/) that is available online.
|
we have built the [MediaPipe Visualizer](https://viz.mediapipe.dev/) that is available online.
|
||||||
|
|
||||||
* A graph view allows users to see a connected calculator graph as expressed
|
* A graph view allows users to see a connected calculator graph as expressed
|
||||||
through a graph configuration that is pasted into the graph editor or
|
through a graph configuration that is pasted into the graph editor or
|
||||||
|
|
|
@ -33,7 +33,7 @@ def _canonicalize_proto_path_oss(all_protos, genfile_path):
|
||||||
"""
|
"""
|
||||||
proto_paths = []
|
proto_paths = []
|
||||||
proto_file_names = []
|
proto_file_names = []
|
||||||
for s in all_protos:
|
for s in all_protos.to_list():
|
||||||
if s.path.startswith(genfile_path):
|
if s.path.startswith(genfile_path):
|
||||||
repo_name, _, file_name = s.path[len(genfile_path + "/external/"):].partition("/")
|
repo_name, _, file_name = s.path[len(genfile_path + "/external/"):].partition("/")
|
||||||
proto_paths.append(genfile_path + "/external/" + repo_name)
|
proto_paths.append(genfile_path + "/external/" + repo_name)
|
||||||
|
@ -60,7 +60,7 @@ def _encode_binary_proto_impl(ctx):
|
||||||
# order of gendir before ., is needed for the proto compiler to resolve
|
# order of gendir before ., is needed for the proto compiler to resolve
|
||||||
# import statements that reference proto files produced by a genrule.
|
# import statements that reference proto files produced by a genrule.
|
||||||
ctx.actions.run_shell(
|
ctx.actions.run_shell(
|
||||||
inputs = list(all_protos) + [textpb, ctx.executable._proto_compiler],
|
tools = all_protos.to_list() + [textpb, ctx.executable._proto_compiler],
|
||||||
outputs = [binarypb],
|
outputs = [binarypb],
|
||||||
command = " ".join(
|
command = " ".join(
|
||||||
[
|
[
|
||||||
|
@ -110,7 +110,7 @@ def _generate_proto_descriptor_set_impl(ctx):
|
||||||
# order of gendir before ., is needed for the proto compiler to resolve
|
# order of gendir before ., is needed for the proto compiler to resolve
|
||||||
# import statements that reference proto files produced by a genrule.
|
# import statements that reference proto files produced by a genrule.
|
||||||
ctx.actions.run(
|
ctx.actions.run(
|
||||||
inputs = list(all_protos) + [ctx.executable._proto_compiler],
|
inputs = all_protos.to_list() + [ctx.executable._proto_compiler],
|
||||||
outputs = [descriptor],
|
outputs = [descriptor],
|
||||||
executable = ctx.executable._proto_compiler,
|
executable = ctx.executable._proto_compiler,
|
||||||
arguments = [
|
arguments = [
|
||||||
|
@ -119,7 +119,7 @@ def _generate_proto_descriptor_set_impl(ctx):
|
||||||
"--proto_path=" + ctx.genfiles_dir.path,
|
"--proto_path=" + ctx.genfiles_dir.path,
|
||||||
"--proto_path=.",
|
"--proto_path=.",
|
||||||
] +
|
] +
|
||||||
[s.path for s in all_protos],
|
[s.path for s in all_protos.to_list()],
|
||||||
mnemonic = "GenerateProtoDescriptor",
|
mnemonic = "GenerateProtoDescriptor",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
3
mediapipe/framework/testdata/BUILD
vendored
3
mediapipe/framework/testdata/BUILD
vendored
|
@ -24,7 +24,6 @@ load("//mediapipe/framework/port:build_config.bzl", "mediapipe_cc_proto_library"
|
||||||
proto_library(
|
proto_library(
|
||||||
name = "sky_light_calculator_proto",
|
name = "sky_light_calculator_proto",
|
||||||
srcs = ["sky_light_calculator.proto"],
|
srcs = ["sky_light_calculator.proto"],
|
||||||
visibility = ["//mediapipe:__subpackages__"],
|
|
||||||
deps = ["//mediapipe/framework:calculator_proto"],
|
deps = ["//mediapipe/framework:calculator_proto"],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -39,7 +38,6 @@ mediapipe_cc_proto_library(
|
||||||
proto_library(
|
proto_library(
|
||||||
name = "night_light_calculator_proto",
|
name = "night_light_calculator_proto",
|
||||||
srcs = ["night_light_calculator.proto"],
|
srcs = ["night_light_calculator.proto"],
|
||||||
visibility = ["//mediapipe:__subpackages__"],
|
|
||||||
deps = ["//mediapipe/framework:calculator_proto"],
|
deps = ["//mediapipe/framework:calculator_proto"],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -54,7 +52,6 @@ mediapipe_cc_proto_library(
|
||||||
proto_library(
|
proto_library(
|
||||||
name = "zoo_mutator_proto",
|
name = "zoo_mutator_proto",
|
||||||
srcs = ["zoo_mutator.proto"],
|
srcs = ["zoo_mutator.proto"],
|
||||||
visibility = ["//mediapipe:__subpackages__"],
|
|
||||||
deps = ["@protobuf_archive//:any_proto"],
|
deps = ["@protobuf_archive//:any_proto"],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -94,7 +94,7 @@ def _transitive_protos_aspect_impl(target, ctx):
|
||||||
|
|
||||||
proto_libs = []
|
proto_libs = []
|
||||||
if ctx.rule.kind == "proto_library":
|
if ctx.rule.kind == "proto_library":
|
||||||
proto_libs = [f for f in target.files if f.extension == "a"]
|
proto_libs = [f for f in target.files.to_list() if f.extension == "a"]
|
||||||
|
|
||||||
# Searching through the hdrs attribute is necessary because of
|
# Searching through the hdrs attribute is necessary because of
|
||||||
# portable_proto_library. In portable mode, that macro
|
# portable_proto_library. In portable mode, that macro
|
||||||
|
|
|
@ -77,7 +77,8 @@ bool GlTextureBuffer::CreateInternal(const void* data) {
|
||||||
// TODO: maybe we do not actually have to wait for the
|
// TODO: maybe we do not actually have to wait for the
|
||||||
// consumer sync here. Check docs.
|
// consumer sync here. Check docs.
|
||||||
sync_token->WaitOnGpu();
|
sync_token->WaitOnGpu();
|
||||||
if (glIsTexture(name_to_delete)) glDeleteTextures(1, &name_to_delete);
|
DCHECK(glIsTexture(name_to_delete));
|
||||||
|
glDeleteTextures(1, &name_to_delete);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user