code optimizitation
This commit is contained in:
parent
208f43f7a5
commit
61da56f99f
|
@ -34,11 +34,8 @@ cc_library(
|
||||||
"//mediapipe/framework/port:logging",
|
"//mediapipe/framework/port:logging",
|
||||||
"//mediapipe/framework/port:opencv_core",
|
"//mediapipe/framework/port:opencv_core",
|
||||||
"//mediapipe/framework/port:opencv_imgproc",
|
"//mediapipe/framework/port:opencv_imgproc",
|
||||||
"//mediapipe/framework/port:opencv_highgui",
|
|
||||||
"//mediapipe/framework/port:status",
|
"//mediapipe/framework/port:status",
|
||||||
"//mediapipe/framework/port:vector",
|
"//mediapipe/framework/port:vector",
|
||||||
"//mediapipe/util:annotation_renderer",
|
|
||||||
"//mediapipe/util:render_data_cc_proto",
|
|
||||||
],
|
],
|
||||||
alwayslink = 1,
|
alwayslink = 1,
|
||||||
)
|
)
|
||||||
|
@ -87,11 +84,8 @@ cc_library(
|
||||||
"//mediapipe/framework/port:logging",
|
"//mediapipe/framework/port:logging",
|
||||||
"//mediapipe/framework/port:opencv_core",
|
"//mediapipe/framework/port:opencv_core",
|
||||||
"//mediapipe/framework/port:opencv_imgproc",
|
"//mediapipe/framework/port:opencv_imgproc",
|
||||||
"//mediapipe/framework/port:opencv_highgui",
|
|
||||||
"//mediapipe/framework/port:status",
|
"//mediapipe/framework/port:status",
|
||||||
"//mediapipe/framework/port:vector",
|
"//mediapipe/framework/port:vector",
|
||||||
"//mediapipe/util:annotation_renderer",
|
|
||||||
"//mediapipe/util:render_data_cc_proto",
|
|
||||||
],
|
],
|
||||||
alwayslink = 1,
|
alwayslink = 1,
|
||||||
)
|
)
|
||||||
|
@ -112,11 +106,8 @@ cc_library(
|
||||||
"//mediapipe/framework/port:logging",
|
"//mediapipe/framework/port:logging",
|
||||||
"//mediapipe/framework/port:opencv_core",
|
"//mediapipe/framework/port:opencv_core",
|
||||||
"//mediapipe/framework/port:opencv_imgproc",
|
"//mediapipe/framework/port:opencv_imgproc",
|
||||||
"//mediapipe/framework/port:opencv_highgui",
|
|
||||||
"//mediapipe/framework/port:status",
|
"//mediapipe/framework/port:status",
|
||||||
"//mediapipe/framework/port:vector",
|
"//mediapipe/framework/port:vector",
|
||||||
"//mediapipe/util:annotation_renderer",
|
|
||||||
"//mediapipe/util:render_data_cc_proto",
|
|
||||||
],
|
],
|
||||||
alwayslink = 1,
|
alwayslink = 1,
|
||||||
)
|
)
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
//#include <android/log.h>
|
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
@ -33,17 +32,13 @@
|
||||||
#include "mediapipe/framework/port/opencv_core_inc.h"
|
#include "mediapipe/framework/port/opencv_core_inc.h"
|
||||||
#include "mediapipe/framework/port/opencv_imgproc_inc.h"
|
#include "mediapipe/framework/port/opencv_imgproc_inc.h"
|
||||||
#include "mediapipe/framework/port/status.h"
|
#include "mediapipe/framework/port/status.h"
|
||||||
#include "mediapipe/util/annotation_renderer.h"
|
|
||||||
#include "mediapipe/util/render_data.pb.h"
|
|
||||||
#include "mediapipe/framework/port/logging.h"
|
#include "mediapipe/framework/port/logging.h"
|
||||||
#include "mediapipe/framework/port/vector.h"
|
#include "mediapipe/framework/port/vector.h"
|
||||||
#include "mediapipe/util/color.pb.h"
|
|
||||||
|
|
||||||
namespace mediapipe
|
namespace mediapipe
|
||||||
{
|
{
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
constexpr char kMaskTag[] = "MASK";
|
constexpr char kMaskTag[] = "MASK";
|
||||||
constexpr char kImageFrameTag[] = "IMAGE";
|
constexpr char kImageFrameTag[] = "IMAGE";
|
||||||
|
|
||||||
|
@ -54,12 +49,7 @@ namespace mediapipe
|
||||||
NUM_ATTRIBUTES
|
NUM_ATTRIBUTES
|
||||||
};
|
};
|
||||||
|
|
||||||
// Round up n to next multiple of m.
|
|
||||||
size_t RoundUp(size_t n, size_t m) { return ((n + m - 1) / m) * m; } // NOLINT
|
|
||||||
inline bool HasImageTag(mediapipe::CalculatorContext *cc) { return false; }
|
inline bool HasImageTag(mediapipe::CalculatorContext *cc) { return false; }
|
||||||
|
|
||||||
using Point = RenderAnnotation::Point;
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
class DrawLipstickCalculator : public CalculatorBase
|
class DrawLipstickCalculator : public CalculatorBase
|
||||||
|
@ -91,10 +81,6 @@ namespace mediapipe
|
||||||
// Indicates if image frame is available as input.
|
// Indicates if image frame is available as input.
|
||||||
bool image_frame_available_ = false;
|
bool image_frame_available_ = false;
|
||||||
std::unordered_map<std::string, cv::Mat> all_masks;
|
std::unordered_map<std::string, cv::Mat> all_masks;
|
||||||
int width_ = 0;
|
|
||||||
int height_ = 0;
|
|
||||||
int width_canvas_ = 0; // Size of overlay drawing texture canvas.
|
|
||||||
int height_canvas_ = 0;
|
|
||||||
};
|
};
|
||||||
REGISTER_CALCULATOR(DrawLipstickCalculator);
|
REGISTER_CALCULATOR(DrawLipstickCalculator);
|
||||||
|
|
||||||
|
@ -141,9 +127,6 @@ namespace mediapipe
|
||||||
{
|
{
|
||||||
image_frame_available_ = true;
|
image_frame_available_ = true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the output header based on the input header (if present).
|
// Set the output header based on the input header (if present).
|
||||||
const char *tag = kImageFrameTag;
|
const char *tag = kImageFrameTag;
|
||||||
|
@ -204,7 +187,6 @@ namespace mediapipe
|
||||||
CalculatorContext *cc, const ImageFormat::Format &target_format,
|
CalculatorContext *cc, const ImageFormat::Format &target_format,
|
||||||
uchar *data_image, std::unique_ptr<cv::Mat> &image_mat)
|
uchar *data_image, std::unique_ptr<cv::Mat> &image_mat)
|
||||||
{
|
{
|
||||||
|
|
||||||
cv::Mat mat_image_ = *image_mat.get();
|
cv::Mat mat_image_ = *image_mat.get();
|
||||||
|
|
||||||
auto output_frame = absl::make_unique<ImageFrame>(
|
auto output_frame = absl::make_unique<ImageFrame>(
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
//#include <android/log.h>
|
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
@ -32,11 +31,8 @@
|
||||||
#include "mediapipe/framework/port/opencv_core_inc.h"
|
#include "mediapipe/framework/port/opencv_core_inc.h"
|
||||||
#include "mediapipe/framework/port/opencv_imgproc_inc.h"
|
#include "mediapipe/framework/port/opencv_imgproc_inc.h"
|
||||||
#include "mediapipe/framework/port/status.h"
|
#include "mediapipe/framework/port/status.h"
|
||||||
#include "mediapipe/util/annotation_renderer.h"
|
|
||||||
#include "mediapipe/util/render_data.pb.h"
|
|
||||||
#include "mediapipe/framework/port/logging.h"
|
#include "mediapipe/framework/port/logging.h"
|
||||||
#include "mediapipe/framework/port/vector.h"
|
#include "mediapipe/framework/port/vector.h"
|
||||||
#include "mediapipe/util/color.pb.h"
|
|
||||||
|
|
||||||
namespace mediapipe
|
namespace mediapipe
|
||||||
{
|
{
|
||||||
|
@ -54,12 +50,7 @@ namespace mediapipe
|
||||||
NUM_ATTRIBUTES
|
NUM_ATTRIBUTES
|
||||||
};
|
};
|
||||||
|
|
||||||
// Round up n to next multiple of m.
|
|
||||||
size_t RoundUp(size_t n, size_t m) { return ((n + m - 1) / m) * m; } // NOLINT
|
|
||||||
inline bool HasImageTag(mediapipe::CalculatorContext *cc) { return false; }
|
inline bool HasImageTag(mediapipe::CalculatorContext *cc) { return false; }
|
||||||
|
|
||||||
using Point = RenderAnnotation::Point;
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
class SmoothFaceCalculator : public CalculatorBase
|
class SmoothFaceCalculator : public CalculatorBase
|
||||||
|
@ -82,23 +73,22 @@ namespace mediapipe
|
||||||
|
|
||||||
absl::Status RenderToCpu(
|
absl::Status RenderToCpu(
|
||||||
CalculatorContext *cc, const ImageFormat::Format &target_format,
|
CalculatorContext *cc, const ImageFormat::Format &target_format,
|
||||||
uchar *data_image, std::unique_ptr<cv::Mat> &image_mat);
|
uchar *data_image);
|
||||||
|
|
||||||
absl::Status SmoothFace(CalculatorContext *cc, std::unique_ptr<cv::Mat> &image_mat,
|
absl::Status SmoothFace(CalculatorContext *cc,
|
||||||
ImageFormat::Format *target_format,
|
ImageFormat::Format *target_format,
|
||||||
const std::unordered_map<std::string, cv::Mat> &mask_vec,
|
const std::unordered_map<std::string, cv::Mat> &mask_vec,
|
||||||
const std::tuple<double, double, double, double> &face_box);
|
const std::tuple<double, double, double, double> &face_box);
|
||||||
|
|
||||||
cv::Mat predict_forehead_mask(std::unique_ptr<cv::Mat> &image_mat,
|
cv::Mat predict_forehead_mask(const std::unordered_map<std::string, cv::Mat> &mask_vec, double face_box_min_y);
|
||||||
const std::unordered_map<std::string, cv::Mat> &mask_vec, double face_box_min_y);
|
|
||||||
|
|
||||||
// Indicates if image frame is available as input.
|
// Indicates if image frame is available as input.
|
||||||
bool image_frame_available_ = false;
|
bool image_frame_available_ = false;
|
||||||
std::unordered_map<std::string, cv::Mat> all_masks;
|
|
||||||
int width_ = 0;
|
int image_width_;
|
||||||
int height_ = 0;
|
int image_height_;
|
||||||
int width_canvas_ = 0; // Size of overlay drawing texture canvas.
|
cv::Mat mat_image_;
|
||||||
int height_canvas_ = 0;
|
std::unique_ptr<cv::Mat> image_mat;
|
||||||
};
|
};
|
||||||
REGISTER_CALCULATOR(SmoothFaceCalculator);
|
REGISTER_CALCULATOR(SmoothFaceCalculator);
|
||||||
|
|
||||||
|
@ -186,7 +176,6 @@ namespace mediapipe
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize render target, drawn with OpenCV.
|
// Initialize render target, drawn with OpenCV.
|
||||||
std::unique_ptr<cv::Mat> image_mat;
|
|
||||||
ImageFormat::Format target_format;
|
ImageFormat::Format target_format;
|
||||||
|
|
||||||
if (cc->Outputs().HasTag(kImageFrameTag))
|
if (cc->Outputs().HasTag(kImageFrameTag))
|
||||||
|
@ -194,6 +183,10 @@ namespace mediapipe
|
||||||
MP_RETURN_IF_ERROR(CreateRenderTargetCpu(cc, image_mat, &target_format));
|
MP_RETURN_IF_ERROR(CreateRenderTargetCpu(cc, image_mat, &target_format));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mat_image_ = *image_mat.get();
|
||||||
|
image_width_ = image_mat->cols;
|
||||||
|
image_height_ = image_mat->rows;
|
||||||
|
|
||||||
const std::vector<std::unordered_map<std::string, cv::Mat>> &mask_vec =
|
const std::vector<std::unordered_map<std::string, cv::Mat>> &mask_vec =
|
||||||
cc->Inputs().Tag(kMaskTag).Get<std::vector<std::unordered_map<std::string, cv::Mat>>>();
|
cc->Inputs().Tag(kMaskTag).Get<std::vector<std::unordered_map<std::string, cv::Mat>>>();
|
||||||
|
|
||||||
|
@ -203,12 +196,12 @@ namespace mediapipe
|
||||||
if (mask_vec.size() > 0 && face_box.size() > 0)
|
if (mask_vec.size() > 0 && face_box.size() > 0)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < mask_vec.size(); i++)
|
for (int i = 0; i < mask_vec.size(); i++)
|
||||||
MP_RETURN_IF_ERROR(SmoothFace(cc, image_mat, &target_format, mask_vec[i], face_box[i]));
|
MP_RETURN_IF_ERROR(SmoothFace(cc, &target_format, mask_vec[i], face_box[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy the rendered image to output.
|
// Copy the rendered image to output.
|
||||||
uchar *image_mat_ptr = image_mat->data;
|
uchar *image_mat_ptr = image_mat->data;
|
||||||
MP_RETURN_IF_ERROR(RenderToCpu(cc, target_format, image_mat_ptr, image_mat));
|
MP_RETURN_IF_ERROR(RenderToCpu(cc, target_format, image_mat_ptr));
|
||||||
|
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
@ -220,15 +213,12 @@ namespace mediapipe
|
||||||
|
|
||||||
absl::Status SmoothFaceCalculator::RenderToCpu(
|
absl::Status SmoothFaceCalculator::RenderToCpu(
|
||||||
CalculatorContext *cc, const ImageFormat::Format &target_format,
|
CalculatorContext *cc, const ImageFormat::Format &target_format,
|
||||||
uchar *data_image, std::unique_ptr<cv::Mat> &image_mat)
|
uchar *data_image)
|
||||||
{
|
{
|
||||||
|
|
||||||
cv::Mat mat_image__ = *image_mat.get();
|
|
||||||
|
|
||||||
auto output_frame = absl::make_unique<ImageFrame>(
|
auto output_frame = absl::make_unique<ImageFrame>(
|
||||||
target_format, mat_image__.cols, mat_image__.rows);
|
target_format, image_width_, image_height_);
|
||||||
|
|
||||||
output_frame->CopyPixelData(target_format, mat_image__.cols, mat_image__.rows, data_image,
|
output_frame->CopyPixelData(target_format, image_width_, image_height_, data_image,
|
||||||
ImageFrame::kDefaultAlignmentBoundary);
|
ImageFrame::kDefaultAlignmentBoundary);
|
||||||
|
|
||||||
if (cc->Outputs().HasTag(kImageFrameTag))
|
if (cc->Outputs().HasTag(kImageFrameTag))
|
||||||
|
@ -290,29 +280,23 @@ namespace mediapipe
|
||||||
{
|
{
|
||||||
image_mat = absl::make_unique<cv::Mat>(
|
image_mat = absl::make_unique<cv::Mat>(
|
||||||
150, 150, CV_8UC4,
|
150, 150, CV_8UC4,
|
||||||
cv::Scalar(255, 255,
|
cv::Scalar::all(255));
|
||||||
255));
|
|
||||||
*target_format = ImageFormat::SRGBA;
|
*target_format = ImageFormat::SRGBA;
|
||||||
}
|
}
|
||||||
|
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
cv::Mat SmoothFaceCalculator::predict_forehead_mask(std::unique_ptr<cv::Mat> &image_mat,
|
cv::Mat SmoothFaceCalculator::predict_forehead_mask(const std::unordered_map<std::string, cv::Mat> &mask_vec, double face_box_min_y)
|
||||||
const std::unordered_map<std::string, cv::Mat> &mask_vec, double face_box_min_y)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
cv::Mat mat_image__ = *image_mat.get();
|
|
||||||
int image_width_ = image_mat->cols;
|
|
||||||
int image_height_ = image_mat->rows;
|
|
||||||
|
|
||||||
cv::Mat part_forehead_mask = mask_vec.find("PART_FOREHEAD_B")->second.clone();
|
cv::Mat part_forehead_mask = mask_vec.find("PART_FOREHEAD_B")->second.clone();
|
||||||
part_forehead_mask.convertTo(part_forehead_mask, CV_32F, 1.0 / 255);
|
part_forehead_mask.convertTo(part_forehead_mask, CV_32F, 1.0 / 255);
|
||||||
part_forehead_mask.convertTo(part_forehead_mask, CV_8U);
|
part_forehead_mask.convertTo(part_forehead_mask, CV_8U);
|
||||||
|
|
||||||
cv::Mat image_sm, image_sm_hsv, skinMask;
|
cv::Mat image_sm, image_sm_hsv, skinMask;
|
||||||
|
|
||||||
cv::resize(mat_image__, image_sm, cv::Size(mat_image__.size().width, mat_image__.size().height));
|
cv::resize(mat_image_, image_sm, cv::Size(image_width_, image_height_));
|
||||||
cv::cvtColor(image_sm, image_sm_hsv, cv::COLOR_BGR2HSV);
|
cv::cvtColor(image_sm, image_sm_hsv, cv::COLOR_BGR2HSV);
|
||||||
|
|
||||||
std::vector<int> x, y;
|
std::vector<int> x, y;
|
||||||
|
@ -375,20 +359,14 @@ namespace mediapipe
|
||||||
}
|
}
|
||||||
|
|
||||||
absl::Status SmoothFaceCalculator::SmoothFace(CalculatorContext *cc,
|
absl::Status SmoothFaceCalculator::SmoothFace(CalculatorContext *cc,
|
||||||
std::unique_ptr<cv::Mat> &image_mat,
|
|
||||||
ImageFormat::Format *target_format,
|
ImageFormat::Format *target_format,
|
||||||
const std::unordered_map<std::string, cv::Mat> &mask_vec,
|
const std::unordered_map<std::string, cv::Mat> &mask_vec,
|
||||||
const std::tuple<double, double, double, double> &face_box)
|
const std::tuple<double, double, double, double> &face_box)
|
||||||
{
|
{
|
||||||
|
|
||||||
cv::Mat mat_image__ = *image_mat.get();
|
|
||||||
|
|
||||||
cv::Mat mouth_mask, mouth;
|
cv::Mat mouth_mask, mouth;
|
||||||
int image_width_ = image_mat->cols;
|
|
||||||
int image_height_ = image_mat->rows;
|
|
||||||
|
|
||||||
cv::Mat not_full_face = mask_vec.find("FACE_OVAL")->second.clone() +
|
cv::Mat not_full_face = mask_vec.find("FACE_OVAL")->second.clone() +
|
||||||
predict_forehead_mask(image_mat, mask_vec, std::get<1>(face_box)) -
|
predict_forehead_mask(mask_vec, std::get<1>(face_box)) -
|
||||||
mask_vec.find("LEFT_EYE")->second.clone() -
|
mask_vec.find("LEFT_EYE")->second.clone() -
|
||||||
mask_vec.find("RIGHT_EYE")->second.clone() -
|
mask_vec.find("RIGHT_EYE")->second.clone() -
|
||||||
mask_vec.find("LEFT_BROW")->second.clone() -
|
mask_vec.find("LEFT_BROW")->second.clone() -
|
||||||
|
@ -397,7 +375,7 @@ namespace mediapipe
|
||||||
|
|
||||||
cv::resize(not_full_face,
|
cv::resize(not_full_face,
|
||||||
not_full_face,
|
not_full_face,
|
||||||
mat_image__.size(), 0, 0,
|
mat_image_.size(), 0, 0,
|
||||||
cv::INTER_LINEAR);
|
cv::INTER_LINEAR);
|
||||||
|
|
||||||
std::vector<int> x, y;
|
std::vector<int> x, y;
|
||||||
|
@ -416,7 +394,7 @@ namespace mediapipe
|
||||||
cv::minMaxLoc(x, &min_x, &max_x);
|
cv::minMaxLoc(x, &min_x, &max_x);
|
||||||
cv::minMaxLoc(y, &min_y, &max_y);
|
cv::minMaxLoc(y, &min_y, &max_y);
|
||||||
|
|
||||||
cv::Mat patch_face = mat_image__(cv::Range(min_y, max_y), cv::Range(min_x, max_x));
|
cv::Mat patch_face = mat_image_(cv::Range(min_y, max_y), cv::Range(min_x, max_x));
|
||||||
cv::Mat patch_nff = not_full_face(cv::Range(min_y, max_y), cv::Range(min_x, max_x));
|
cv::Mat patch_nff = not_full_face(cv::Range(min_y, max_y), cv::Range(min_x, max_x));
|
||||||
cv::Mat patch_new, patch_wow;
|
cv::Mat patch_new, patch_wow;
|
||||||
cv::cvtColor(patch_face, patch_wow, cv::COLOR_RGBA2RGB);
|
cv::cvtColor(patch_face, patch_wow, cv::COLOR_RGBA2RGB);
|
||||||
|
|
|
@ -31,11 +31,8 @@
|
||||||
#include "mediapipe/framework/port/opencv_core_inc.h"
|
#include "mediapipe/framework/port/opencv_core_inc.h"
|
||||||
#include "mediapipe/framework/port/opencv_imgproc_inc.h"
|
#include "mediapipe/framework/port/opencv_imgproc_inc.h"
|
||||||
#include "mediapipe/framework/port/status.h"
|
#include "mediapipe/framework/port/status.h"
|
||||||
#include "mediapipe/util/annotation_renderer.h"
|
|
||||||
#include "mediapipe/util/render_data.pb.h"
|
|
||||||
#include "mediapipe/framework/port/logging.h"
|
#include "mediapipe/framework/port/logging.h"
|
||||||
#include "mediapipe/framework/port/vector.h"
|
#include "mediapipe/framework/port/vector.h"
|
||||||
#include "mediapipe/util/color.pb.h"
|
|
||||||
|
|
||||||
namespace mediapipe
|
namespace mediapipe
|
||||||
{
|
{
|
||||||
|
@ -52,12 +49,7 @@ namespace mediapipe
|
||||||
NUM_ATTRIBUTES
|
NUM_ATTRIBUTES
|
||||||
};
|
};
|
||||||
|
|
||||||
// Round up n to next multiple of m.
|
|
||||||
size_t RoundUp(size_t n, size_t m) { return ((n + m - 1) / m) * m; } // NOLINT
|
|
||||||
inline bool HasImageTag(mediapipe::CalculatorContext *cc) { return false; }
|
inline bool HasImageTag(mediapipe::CalculatorContext *cc) { return false; }
|
||||||
|
|
||||||
using Point = RenderAnnotation::Point;
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
class WhitenTeethCalculator : public CalculatorBase
|
class WhitenTeethCalculator : public CalculatorBase
|
||||||
|
@ -82,17 +74,15 @@ namespace mediapipe
|
||||||
CalculatorContext *cc, const ImageFormat::Format &target_format,
|
CalculatorContext *cc, const ImageFormat::Format &target_format,
|
||||||
uchar *data_image, std::unique_ptr<cv::Mat> &image_mat);
|
uchar *data_image, std::unique_ptr<cv::Mat> &image_mat);
|
||||||
|
|
||||||
absl::Status WhitenTeeth(CalculatorContext *cc, std::unique_ptr<cv::Mat> &image_mat,
|
absl::Status WhitenTeeth(CalculatorContext *cc, ImageFormat::Format *target_format,
|
||||||
ImageFormat::Format *target_format,
|
|
||||||
const std::unordered_map<std::string, cv::Mat> &mask_vec);
|
const std::unordered_map<std::string, cv::Mat> &mask_vec);
|
||||||
|
|
||||||
// Indicates if image frame is available as input.
|
// Indicates if image frame is available as input.
|
||||||
bool image_frame_available_ = false;
|
bool image_frame_available_ = false;
|
||||||
std::unordered_map<std::string, cv::Mat> all_masks;
|
std::unique_ptr<cv::Mat> image_mat;
|
||||||
int width_ = 0;
|
cv::Mat mat_image_;
|
||||||
int height_ = 0;
|
int image_width_;
|
||||||
int width_canvas_ = 0; // Size of overlay drawing texture canvas.
|
int image_height_;
|
||||||
int height_canvas_ = 0;
|
|
||||||
};
|
};
|
||||||
REGISTER_CALCULATOR(WhitenTeethCalculator);
|
REGISTER_CALCULATOR(WhitenTeethCalculator);
|
||||||
|
|
||||||
|
@ -170,20 +160,22 @@ namespace mediapipe
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize render target, drawn with OpenCV.
|
// Initialize render target, drawn with OpenCV.
|
||||||
std::unique_ptr<cv::Mat> image_mat;
|
|
||||||
ImageFormat::Format target_format;
|
ImageFormat::Format target_format;
|
||||||
|
|
||||||
if (cc->Outputs().HasTag(kImageFrameTag))
|
if (cc->Outputs().HasTag(kImageFrameTag))
|
||||||
{
|
{
|
||||||
MP_RETURN_IF_ERROR(CreateRenderTargetCpu(cc, image_mat, &target_format));
|
MP_RETURN_IF_ERROR(CreateRenderTargetCpu(cc, image_mat, &target_format));
|
||||||
}
|
}
|
||||||
|
mat_image_ = *image_mat.get();
|
||||||
|
image_width_ = image_mat->cols;
|
||||||
|
image_height_ = image_mat->rows;
|
||||||
|
|
||||||
const std::vector<std::unordered_map<std::string, cv::Mat>> &mask_vec =
|
const std::vector<std::unordered_map<std::string, cv::Mat>> &mask_vec =
|
||||||
cc->Inputs().Tag(kMaskTag).Get<std::vector<std::unordered_map<std::string, cv::Mat>>>();
|
cc->Inputs().Tag(kMaskTag).Get<std::vector<std::unordered_map<std::string, cv::Mat>>>();
|
||||||
if (mask_vec.size() > 0)
|
if (mask_vec.size() > 0)
|
||||||
{
|
{
|
||||||
for (auto mask : mask_vec)
|
for (auto mask : mask_vec)
|
||||||
MP_RETURN_IF_ERROR(WhitenTeeth(cc, image_mat, &target_format, mask));
|
MP_RETURN_IF_ERROR(WhitenTeeth(cc, &target_format, mask));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy the rendered image to output.
|
// Copy the rendered image to output.
|
||||||
|
@ -206,9 +198,9 @@ namespace mediapipe
|
||||||
cv::Mat mat_image_ = *image_mat.get();
|
cv::Mat mat_image_ = *image_mat.get();
|
||||||
|
|
||||||
auto output_frame = absl::make_unique<ImageFrame>(
|
auto output_frame = absl::make_unique<ImageFrame>(
|
||||||
target_format, mat_image_.cols, mat_image_.rows);
|
target_format, image_width_, image_height_);
|
||||||
|
|
||||||
output_frame->CopyPixelData(target_format, mat_image_.cols, mat_image_.rows, data_image,
|
output_frame->CopyPixelData(target_format, image_width_, image_height_, data_image,
|
||||||
ImageFrame::kDefaultAlignmentBoundary);
|
ImageFrame::kDefaultAlignmentBoundary);
|
||||||
|
|
||||||
if (cc->Outputs().HasTag(kImageFrameTag))
|
if (cc->Outputs().HasTag(kImageFrameTag))
|
||||||
|
@ -279,20 +271,15 @@ namespace mediapipe
|
||||||
}
|
}
|
||||||
|
|
||||||
absl::Status WhitenTeethCalculator::WhitenTeeth(CalculatorContext *cc,
|
absl::Status WhitenTeethCalculator::WhitenTeeth(CalculatorContext *cc,
|
||||||
std::unique_ptr<cv::Mat> &image_mat,
|
|
||||||
ImageFormat::Format *target_format,
|
ImageFormat::Format *target_format,
|
||||||
const std::unordered_map<std::string, cv::Mat> &mask_vec)
|
const std::unordered_map<std::string, cv::Mat> &mask_vec)
|
||||||
{
|
{
|
||||||
cv::Mat mat_image__ = *image_mat.get();
|
|
||||||
|
|
||||||
cv::Mat mouth_mask, mouth;
|
cv::Mat mouth_mask, mouth;
|
||||||
int image_width_ = image_mat->cols;
|
mouth_mask = cv::Mat::zeros(mat_image_.size(), CV_32F);
|
||||||
int image_height_ = image_mat->rows;
|
|
||||||
mouth_mask = cv::Mat::zeros(mat_image__.size(), CV_32F);
|
|
||||||
|
|
||||||
mouth_mask = mask_vec.find("MOUTH_INSIDE")->second.clone();
|
mouth_mask = mask_vec.find("MOUTH_INSIDE")->second.clone();
|
||||||
|
|
||||||
cv::resize(mouth_mask, mouth, mat_image__.size(), cv::INTER_LINEAR);
|
cv::resize(mouth_mask, mouth, mat_image_.size(), cv::INTER_LINEAR);
|
||||||
|
|
||||||
std::vector<int> x, y;
|
std::vector<int> x, y;
|
||||||
std::vector<cv::Point> location;
|
std::vector<cv::Point> location;
|
||||||
|
@ -323,7 +310,7 @@ namespace mediapipe
|
||||||
mouth_max_x = static_cast<int>(std::min(mouth_max_x + mw * 0.1, (double)image_width_));
|
mouth_max_x = static_cast<int>(std::min(mouth_max_x + mw * 0.1, (double)image_width_));
|
||||||
mouth_crop_mask = mouth(cv::Range(mouth_min_y, mouth_max_y), cv::Range(mouth_min_x, mouth_max_x));
|
mouth_crop_mask = mouth(cv::Range(mouth_min_y, mouth_max_y), cv::Range(mouth_min_x, mouth_max_x));
|
||||||
cv::Mat img_hsv, tmp_mask, img_hls;
|
cv::Mat img_hsv, tmp_mask, img_hls;
|
||||||
cv::cvtColor(mat_image__(cv::Range(mouth_min_y, mouth_max_y), cv::Range(mouth_min_x, mouth_max_x)), img_hsv,
|
cv::cvtColor(mat_image_(cv::Range(mouth_min_y, mouth_max_y), cv::Range(mouth_min_x, mouth_max_x)), img_hsv,
|
||||||
cv::COLOR_RGBA2RGB);
|
cv::COLOR_RGBA2RGB);
|
||||||
cv::cvtColor(img_hsv, img_hsv,
|
cv::cvtColor(img_hsv, img_hsv,
|
||||||
cv::COLOR_RGB2HSV);
|
cv::COLOR_RGB2HSV);
|
||||||
|
@ -357,7 +344,7 @@ namespace mediapipe
|
||||||
cv::cvtColor(img_hls, img_hls, cv::COLOR_HLS2RGB);
|
cv::cvtColor(img_hls, img_hls, cv::COLOR_HLS2RGB);
|
||||||
cv::cvtColor(img_hls, img_hls, cv::COLOR_RGB2RGBA);
|
cv::cvtColor(img_hls, img_hls, cv::COLOR_RGB2RGBA);
|
||||||
|
|
||||||
cv::Mat slice = mat_image__(cv::Range(mouth_min_y, mouth_max_y), cv::Range(mouth_min_x, mouth_max_x));
|
cv::Mat slice = mat_image_(cv::Range(mouth_min_y, mouth_max_y), cv::Range(mouth_min_x, mouth_max_x));
|
||||||
img_hls.copyTo(slice);
|
img_hls.copyTo(slice);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,9 +28,6 @@ cc_library(
|
||||||
"//mediapipe/framework:calculator_options_cc_proto",
|
"//mediapipe/framework:calculator_options_cc_proto",
|
||||||
"//mediapipe/framework/formats:landmark_cc_proto",
|
"//mediapipe/framework/formats:landmark_cc_proto",
|
||||||
"//mediapipe/framework/formats:location_data_cc_proto",
|
"//mediapipe/framework/formats:location_data_cc_proto",
|
||||||
"//mediapipe/framework/port:ret_check",
|
|
||||||
"//mediapipe/util:color_cc_proto",
|
|
||||||
"//mediapipe/util:render_data_cc_proto",
|
|
||||||
"@com_google_absl//absl/memory",
|
"@com_google_absl//absl/memory",
|
||||||
"@com_google_absl//absl/strings",
|
"@com_google_absl//absl/strings",
|
||||||
"//mediapipe/framework/formats:image_format_cc_proto",
|
"//mediapipe/framework/formats:image_format_cc_proto",
|
||||||
|
|
|
@ -17,28 +17,9 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <string>
|
|
||||||
#include <map>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "absl/memory/memory.h"
|
#include "absl/memory/memory.h"
|
||||||
#include "absl/strings/str_cat.h"
|
|
||||||
#include "absl/strings/str_join.h"
|
|
||||||
#include "mediapipe/framework/calculator_framework.h"
|
|
||||||
#include "mediapipe/framework/calculator_options.pb.h"
|
|
||||||
#include "mediapipe/framework/formats/image_format.pb.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/opencv_core_inc.h"
|
|
||||||
#include "mediapipe/framework/port/opencv_imgproc_inc.h"
|
|
||||||
#include "mediapipe/framework/formats/location_data.pb.h"
|
|
||||||
#include "mediapipe/framework/port/ret_check.h"
|
|
||||||
#include "mediapipe/util/color.pb.h"
|
|
||||||
#include "mediapipe/util/render_data.pb.h"
|
|
||||||
#include "absl/strings/str_cat.h"
|
|
||||||
#include "mediapipe/framework/port/logging.h"
|
#include "mediapipe/framework/port/logging.h"
|
||||||
#include "mediapipe/framework/port/status.h"
|
#include "mediapipe/framework/port/status.h"
|
||||||
#include "mediapipe/framework/port/vector.h"
|
#include "mediapipe/framework/port/vector.h"
|
||||||
|
@ -49,7 +30,6 @@ namespace mediapipe
|
||||||
{
|
{
|
||||||
constexpr char kLandmarksTag[] = "LANDMARKS";
|
constexpr char kLandmarksTag[] = "LANDMARKS";
|
||||||
constexpr char kNormLandmarksTag[] = "NORM_LANDMARKS";
|
constexpr char kNormLandmarksTag[] = "NORM_LANDMARKS";
|
||||||
constexpr char kLandmarkLabel[] = "KEYPOINT";
|
|
||||||
constexpr char kVectorTag[] = "VECTOR";
|
constexpr char kVectorTag[] = "VECTOR";
|
||||||
constexpr char kMaskTag[] = "MASK";
|
constexpr char kMaskTag[] = "MASK";
|
||||||
constexpr char kFaceBoxTag[] = "FACEBOX";
|
constexpr char kFaceBoxTag[] = "FACEBOX";
|
||||||
|
@ -111,6 +91,11 @@ namespace mediapipe
|
||||||
|
|
||||||
std::tuple<double, double, double, double> face_box;
|
std::tuple<double, double, double, double> face_box;
|
||||||
|
|
||||||
|
std::unique_ptr<cv::Mat> image_mat;
|
||||||
|
|
||||||
|
int image_width_;
|
||||||
|
int image_height_;
|
||||||
|
|
||||||
float scale_factor_ = 1.0;
|
float scale_factor_ = 1.0;
|
||||||
|
|
||||||
bool image_frame_available_ = false;
|
bool image_frame_available_ = false;
|
||||||
|
@ -161,9 +146,6 @@ namespace mediapipe
|
||||||
{
|
{
|
||||||
image_frame_available_ = true;
|
image_frame_available_ = true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
@ -190,15 +172,18 @@ namespace mediapipe
|
||||||
|
|
||||||
// Initialize render target, drawn with OpenCV.
|
// Initialize render target, drawn with OpenCV.
|
||||||
|
|
||||||
std::unique_ptr<cv::Mat> image_mat;
|
|
||||||
ImageFormat::Format target_format;
|
ImageFormat::Format target_format;
|
||||||
std::unordered_map<std::string, cv::Mat> all_masks;
|
std::unordered_map<std::string, cv::Mat> all_masks;
|
||||||
|
|
||||||
MP_RETURN_IF_ERROR(CreateRenderTargetCpu(cc, image_mat, &target_format));
|
MP_RETURN_IF_ERROR(CreateRenderTargetCpu(cc, image_mat, &target_format));
|
||||||
|
|
||||||
MP_RETURN_IF_ERROR(GetMasks(cc, all_masks, image_mat));
|
cv::Mat mat_image_ = *image_mat.get();
|
||||||
|
image_width_ = image_mat->cols;
|
||||||
|
image_height_ = image_mat->rows;
|
||||||
|
|
||||||
MP_RETURN_IF_ERROR(GetFaceBox(cc, image_mat));
|
MP_RETURN_IF_ERROR(GetMasks(cc, all_masks));
|
||||||
|
|
||||||
|
MP_RETURN_IF_ERROR(GetFaceBox(cc));
|
||||||
|
|
||||||
MP_RETURN_IF_ERROR(RenderToCpu(cc, all_masks));
|
MP_RETURN_IF_ERROR(RenderToCpu(cc, all_masks));
|
||||||
|
|
||||||
|
@ -289,12 +274,8 @@ namespace mediapipe
|
||||||
}
|
}
|
||||||
|
|
||||||
absl::Status LandmarksToMaskCalculator::GetMasks(CalculatorContext *cc,
|
absl::Status LandmarksToMaskCalculator::GetMasks(CalculatorContext *cc,
|
||||||
std::unordered_map<std::string, cv::Mat> &all_masks, std::unique_ptr<cv::Mat> &image_mat)
|
std::unordered_map<std::string, cv::Mat> &all_masks)
|
||||||
{
|
{
|
||||||
|
|
||||||
int image_width_ = image_mat->cols;
|
|
||||||
int image_height_ = image_mat->rows;
|
|
||||||
|
|
||||||
if (cc->Inputs().HasTag(kLandmarksTag))
|
if (cc->Inputs().HasTag(kLandmarksTag))
|
||||||
{
|
{
|
||||||
const LandmarkList &landmarks =
|
const LandmarkList &landmarks =
|
||||||
|
@ -326,10 +307,11 @@ namespace mediapipe
|
||||||
|
|
||||||
std::vector<std::vector<cv::Point>> point_vec;
|
std::vector<std::vector<cv::Point>> point_vec;
|
||||||
point_vec.push_back(point_array);
|
point_vec.push_back(point_array);
|
||||||
|
|
||||||
mask = cv::Mat::zeros(image_mat->size(), CV_32FC1);
|
mask = cv::Mat::zeros(image_mat->size(), CV_32FC1);
|
||||||
cv::fillPoly(mask, point_vec, cv::Scalar::all(255), cv::LINE_AA);
|
cv::fillPoly(mask, point_vec, cv::Scalar::all(255), cv::LINE_AA);
|
||||||
mask.convertTo(mask, CV_8U);
|
mask.convertTo(mask, CV_8U);
|
||||||
all_masks.insert(make_pair(key, mask));
|
all_masks.insert({key, mask});
|
||||||
point_vec.clear();
|
point_vec.clear();
|
||||||
point_array.clear();
|
point_array.clear();
|
||||||
}
|
}
|
||||||
|
@ -377,13 +359,8 @@ namespace mediapipe
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
absl::Status LandmarksToMaskCalculator::GetFaceBox(CalculatorContext *cc, std::unique_ptr<cv::Mat> &image_mat)
|
absl::Status LandmarksToMaskCalculator::GetFaceBox(CalculatorContext *cc)
|
||||||
{
|
{
|
||||||
cv::Mat mat_image_ = *image_mat.get();
|
|
||||||
|
|
||||||
int image_width_ = image_mat->cols;
|
|
||||||
int image_height_ = image_mat->rows;
|
|
||||||
|
|
||||||
std::vector<int> x_s, y_s;
|
std::vector<int> x_s, y_s;
|
||||||
double box_min_y, box_max_y, box_max_x, box_min_x;
|
double box_min_y, box_max_y, box_max_x, box_min_x;
|
||||||
if (cc->Inputs().HasTag(kLandmarksTag))
|
if (cc->Inputs().HasTag(kLandmarksTag))
|
||||||
|
|
|
@ -14,46 +14,33 @@
|
||||||
#ifndef MEDIAPIPE_CALCULATORS_UTIL_LANDMARKS_TO_MASK_CALCULATOR_H_
|
#ifndef MEDIAPIPE_CALCULATORS_UTIL_LANDMARKS_TO_MASK_CALCULATOR_H_
|
||||||
#define MEDIAPIPE_CALCULATORS_UTIL_LANDMARKS_TO_MASK_CALCULATOR_H_
|
#define MEDIAPIPE_CALCULATORS_UTIL_LANDMARKS_TO_MASK_CALCULATOR_H_
|
||||||
|
|
||||||
#include "absl/memory/memory.h"
|
|
||||||
#include "absl/strings/str_cat.h"
|
#include "absl/strings/str_cat.h"
|
||||||
#include "absl/strings/str_join.h"
|
#include "absl/strings/str_join.h"
|
||||||
#include "mediapipe/framework/calculator_framework.h"
|
#include "mediapipe/framework/calculator_framework.h"
|
||||||
#include "mediapipe/framework/calculator_options.pb.h"
|
#include "mediapipe/framework/calculator_options.pb.h"
|
||||||
#include "mediapipe/framework/formats/landmark.pb.h"
|
#include "mediapipe/framework/formats/landmark.pb.h"
|
||||||
#include "mediapipe/framework/formats/location_data.pb.h"
|
#include "mediapipe/framework/formats/location_data.pb.h"
|
||||||
#include "mediapipe/framework/port/ret_check.h"
|
|
||||||
#include "mediapipe/util/color.pb.h"
|
|
||||||
#include "mediapipe/util/render_data.pb.h"
|
|
||||||
#include "mediapipe/framework/formats/image_format.pb.h"
|
#include "mediapipe/framework/formats/image_format.pb.h"
|
||||||
#include "mediapipe/framework/formats/image_frame.h"
|
#include "mediapipe/framework/formats/image_frame.h"
|
||||||
#include "mediapipe/framework/formats/image_frame_opencv.h"
|
#include "mediapipe/framework/formats/image_frame_opencv.h"
|
||||||
#include "mediapipe/framework/port/opencv_core_inc.h"
|
#include "mediapipe/framework/port/opencv_core_inc.h"
|
||||||
#include "mediapipe/framework/port/opencv_imgproc_inc.h"
|
#include "mediapipe/framework/port/opencv_imgproc_inc.h"
|
||||||
#include "mediapipe/framework/port/logging.h"
|
|
||||||
#include "mediapipe/framework/port/status.h"
|
|
||||||
#include "mediapipe/framework/port/vector.h"
|
|
||||||
|
|
||||||
namespace mediapipe
|
namespace mediapipe
|
||||||
{
|
{
|
||||||
|
|
||||||
// A calculator that converts Landmark proto to RenderData proto for
|
// A calculator that uses face landmarks to create face part masks and facebox for
|
||||||
// visualization. The input should be LandmarkList proto. It is also possible
|
// visualization. The input should be LandmarkList proto and ImageFrame.
|
||||||
// to specify the connections between landmarks.
|
|
||||||
//
|
//
|
||||||
// Example config:
|
// Example config:
|
||||||
// node {
|
// node {
|
||||||
// calculator: "LandmarksToMaskCalculator"
|
// calculator: "LandmarksToMaskCalculator"
|
||||||
// input_stream: "NORM_LANDMARKS:landmarks"
|
// input_stream: "IMAGE:image"
|
||||||
// output_stream: "RENDER_DATA:render_data"
|
// input_stream: "NORM_LANDMARKS:face_landmarks"
|
||||||
// options {
|
// output_stream: "FACEBOX:face_box"
|
||||||
// [LandmarksToRenderDataCalculatorOptions.ext] {
|
// output_stream: "MASK:mask"
|
||||||
// landmark_connections: [0, 1, 1, 2]
|
|
||||||
// landmark_color { r: 0 g: 255 b: 0 }
|
|
||||||
// connection_color { r: 0 g: 255 b: 0 }
|
|
||||||
// thickness: 4.0
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
class LandmarksToMaskCalculator : public CalculatorBase
|
class LandmarksToMaskCalculator : public CalculatorBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -74,9 +61,9 @@ namespace mediapipe
|
||||||
absl::Status RenderToCpu(CalculatorContext *cc,
|
absl::Status RenderToCpu(CalculatorContext *cc,
|
||||||
std::unordered_map<std::string, cv::Mat> &all_masks);
|
std::unordered_map<std::string, cv::Mat> &all_masks);
|
||||||
|
|
||||||
absl::Status GetFaceBox(CalculatorContext *cc, std::unique_ptr<cv::Mat> &image_mat);
|
absl::Status GetFaceBox(CalculatorContext *cc);
|
||||||
|
|
||||||
absl::Status GetMasks(CalculatorContext *cc, std::unordered_map<std::string, cv::Mat> &all_masks, std::unique_ptr<cv::Mat> &image_mat);
|
absl::Status GetMasks(CalculatorContext *cc, std::unordered_map<std::string, cv::Mat> &all_masks);
|
||||||
|
|
||||||
absl::Status CreateRenderTargetCpu(
|
absl::Status CreateRenderTargetCpu(
|
||||||
CalculatorContext *cc, std::unique_ptr<cv::Mat> &image_mat,
|
CalculatorContext *cc, std::unique_ptr<cv::Mat> &image_mat,
|
||||||
|
|
|
@ -17,7 +17,7 @@ licenses(["notice"])
|
||||||
package(default_visibility = ["//mediapipe/examples:__subpackages__"])
|
package(default_visibility = ["//mediapipe/examples:__subpackages__"])
|
||||||
|
|
||||||
cc_binary(
|
cc_binary(
|
||||||
name = "face_mesh_tflite",
|
name = "beauty_tflite",
|
||||||
deps = [
|
deps = [
|
||||||
"//mediapipe/examples/desktop:simple_run_graph_main",
|
"//mediapipe/examples/desktop:simple_run_graph_main",
|
||||||
"//mediapipe/graphs/beauty:desktop_calculators",
|
"//mediapipe/graphs/beauty:desktop_calculators",
|
||||||
|
@ -25,9 +25,25 @@ cc_binary(
|
||||||
)
|
)
|
||||||
|
|
||||||
cc_binary(
|
cc_binary(
|
||||||
name = "face_mesh_cpu",
|
name = "beauty_cpu",
|
||||||
deps = [
|
deps = [
|
||||||
"//mediapipe/examples/desktop:demo_run_graph_main",
|
"//mediapipe/examples/desktop:demo_run_graph_main",
|
||||||
"//mediapipe/graphs/beauty:desktop_live_calculators",
|
"//mediapipe/graphs/beauty:desktop_live_calculators",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
cc_binary(
|
||||||
|
name = "beauty_cpu_over",
|
||||||
|
deps = [
|
||||||
|
"//mediapipe/examples/desktop:demo_run_graph_main",
|
||||||
|
"//mediapipe/graphs/beauty:desktop_live_over_calculators",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
cc_binary(
|
||||||
|
name = "beauty_gpu_over",
|
||||||
|
deps = [
|
||||||
|
"//mediapipe/examples/desktop:demo_run_graph_main",
|
||||||
|
"//mediapipe/graphs/beauty:desktop_gpu_over",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
50
mediapipe/graphs/beauty/beauty_desktop.pbtxt
Normal file
50
mediapipe/graphs/beauty/beauty_desktop.pbtxt
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
# MediaPipe graph that performs face mesh with TensorFlow Lite on CPU.
|
||||||
|
|
||||||
|
# Input image. (ImageFrame)
|
||||||
|
input_stream: "input_video"
|
||||||
|
|
||||||
|
# Output image with rendered results. (ImageFrame)
|
||||||
|
output_stream: "output_video"
|
||||||
|
# Collection of detected/processed faces, each represented as a list of
|
||||||
|
# landmarks. (std::vector<NormalizedLandmarkList>)
|
||||||
|
output_stream: "multi_face_landmarks"
|
||||||
|
|
||||||
|
node {
|
||||||
|
calculator: "FlowLimiterCalculator"
|
||||||
|
input_stream: "input_video"
|
||||||
|
input_stream: "FINISHED:output_video"
|
||||||
|
input_stream_info: {
|
||||||
|
tag_index: "FINISHED"
|
||||||
|
back_edge: true
|
||||||
|
}
|
||||||
|
output_stream: "throttled_input_video"
|
||||||
|
}
|
||||||
|
|
||||||
|
node {
|
||||||
|
calculator: "ConstantSidePacketCalculator"
|
||||||
|
output_side_packet: "PACKET:0:num_faces"
|
||||||
|
output_side_packet: "PACKET:1:with_attention"
|
||||||
|
node_options: {
|
||||||
|
[type.googleapis.com/mediapipe.ConstantSidePacketCalculatorOptions]: {
|
||||||
|
packet { int_value: 1 }
|
||||||
|
packet { bool_value: true }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Subgraph that detects faces and corresponding landmarks.
|
||||||
|
node {
|
||||||
|
calculator: "FaceLandmarkFrontCpu"
|
||||||
|
input_stream: "IMAGE:throttled_input_video"
|
||||||
|
input_side_packet: "NUM_FACES:num_faces"
|
||||||
|
input_side_packet: "WITH_ATTENTION:with_attention"
|
||||||
|
output_stream: "LANDMARKS:multi_face_landmarks"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Subgraph that renders onto the input image.
|
||||||
|
node {
|
||||||
|
calculator: "FaceRendererCpu"
|
||||||
|
input_stream: "IMAGE:throttled_input_video"
|
||||||
|
input_stream: "LANDMARKS:multi_face_landmarks"
|
||||||
|
output_stream: "IMAGE:output_video"
|
||||||
|
}
|
|
@ -27,15 +27,12 @@ cc_library(
|
||||||
"//mediapipe/calculators/core:split_proto_list_calculator",
|
"//mediapipe/calculators/core:split_proto_list_calculator",
|
||||||
"//mediapipe/util:annotation_renderer",
|
"//mediapipe/util:annotation_renderer",
|
||||||
"//mediapipe/calculators/util:annotation_overlay_calculator",
|
"//mediapipe/calculators/util:annotation_overlay_calculator",
|
||||||
"//mediapipe/calculators/beauty:form_face_mask_calculator",
|
|
||||||
"//mediapipe/calculators/beauty:smooth_face_calculator",
|
"//mediapipe/calculators/beauty:smooth_face_calculator",
|
||||||
"//mediapipe/calculators/beauty:draw_lipstick_calculator",
|
"//mediapipe/calculators/beauty:draw_lipstick_calculator",
|
||||||
"//mediapipe/calculators/beauty:whiten_teeth_calculator",
|
"//mediapipe/calculators/beauty:whiten_teeth_calculator",
|
||||||
"//mediapipe/calculators/util:detections_to_render_data_calculator",
|
"//mediapipe/calculators/util:detections_to_render_data_calculator",
|
||||||
"//mediapipe/calculators/util:landmarks_to_render_data_calculator",
|
"//mediapipe/calculators/util:landmarks_to_render_data_calculator",
|
||||||
"//mediapipe/calculators/landmarks:landmarks_to_mask_calculator",
|
"//mediapipe/calculators/landmarks:landmarks_to_mask_calculator",
|
||||||
"//mediapipe/calculators/util:rect_to_render_data_calculator",
|
|
||||||
"//mediapipe/graphs/beauty/calculators:face_landmarks_to_render_data_calculator",
|
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ node {
|
||||||
output_stream: "BATCH_END:landmark_timestamp"
|
output_stream: "BATCH_END:landmark_timestamp"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Converts landmarks to drawing primitives for annotation overlay.
|
# Converts landmarks to face part masks.
|
||||||
node {
|
node {
|
||||||
calculator: "LandmarksToMaskCalculator"
|
calculator: "LandmarksToMaskCalculator"
|
||||||
input_stream: "IMAGE:loop_image"
|
input_stream: "IMAGE:loop_image"
|
||||||
|
@ -39,7 +39,7 @@ node {
|
||||||
output_stream: "MASK:mask"
|
output_stream: "MASK:mask"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Collects a RenderData object for each hand into a vector. Upon receiving the
|
# Collects a MapMask object for each hand into a vector. Upon receiving the
|
||||||
# BATCH_END timestamp, outputs the vector of RenderData at the BATCH_END
|
# BATCH_END timestamp, outputs the vector of RenderData at the BATCH_END
|
||||||
# timestamp.
|
# timestamp.
|
||||||
node {
|
node {
|
||||||
|
@ -56,7 +56,7 @@ node {
|
||||||
output_stream: "ITERABLE:multi_face_box"
|
output_stream: "ITERABLE:multi_face_box"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#Applies lipstick to the face on the IMAGE using MASK.
|
||||||
node {
|
node {
|
||||||
calculator: "DrawLipstickCalculator"
|
calculator: "DrawLipstickCalculator"
|
||||||
input_stream: "IMAGE:input_image"
|
input_stream: "IMAGE:input_image"
|
||||||
|
@ -64,6 +64,7 @@ node {
|
||||||
output_stream: "IMAGE:input_image_1"
|
output_stream: "IMAGE:input_image_1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#Whitens teeth of the face on the IMAGE using MASK.
|
||||||
node {
|
node {
|
||||||
calculator: "WhitenTeethCalculator"
|
calculator: "WhitenTeethCalculator"
|
||||||
input_stream: "IMAGE:input_image_1"
|
input_stream: "IMAGE:input_image_1"
|
||||||
|
@ -71,6 +72,7 @@ node {
|
||||||
output_stream: "IMAGE:input_image_2"
|
output_stream: "IMAGE:input_image_2"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#Smoothes face on the IMAGE using MASK.
|
||||||
node {
|
node {
|
||||||
calculator: "SmoothFaceCalculator"
|
calculator: "SmoothFaceCalculator"
|
||||||
input_stream: "IMAGE:input_image_2"
|
input_stream: "IMAGE:input_image_2"
|
||||||
|
|
|
@ -53,57 +53,13 @@ node {
|
||||||
output_stream: "ITERABLE:multi_face_landmarks_render_data"
|
output_stream: "ITERABLE:multi_face_landmarks_render_data"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Converts normalized rects to drawing primitives for annotation overlay.
|
# Draws annotations and overlays them on top of the input images.
|
||||||
#node {
|
|
||||||
# calculator: "RectToRenderDataCalculator"
|
|
||||||
# input_stream: "NORM_RECTS:rects"
|
|
||||||
# output_stream: "RENDER_DATA:rects_render_data"
|
|
||||||
# node_options: {
|
|
||||||
# [type.googleapis.com/mediapipe.RectToRenderDataCalculatorOptions] {
|
|
||||||
# filled: false
|
|
||||||
# color { r: 255 g: 0 b: 0 }
|
|
||||||
# thickness: 4.0
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
#}
|
|
||||||
|
|
||||||
node {
|
node {
|
||||||
calculator: "FormFaceMaskCalculator"
|
calculator: "AnnotationOverlayCalculator"
|
||||||
input_stream: "IMAGE:input_image"
|
input_stream: "IMAGE:input_image"
|
||||||
input_stream: "VECTOR:0:multi_face_landmarks_render_data"
|
input_stream: "VECTOR:0:multi_face_landmarks_render_data"
|
||||||
output_stream: "FACEBOX:face_box"
|
|
||||||
output_stream: "MASK:multi_mask"
|
|
||||||
}
|
|
||||||
|
|
||||||
node {
|
|
||||||
calculator: "DrawLipstickCalculator"
|
|
||||||
input_stream: "IMAGE:input_image"
|
|
||||||
input_stream: "MASK:0:multi_mask"
|
|
||||||
output_stream: "IMAGE:input_image_1"
|
|
||||||
}
|
|
||||||
|
|
||||||
node {
|
|
||||||
calculator: "WhitenTeethCalculator"
|
|
||||||
input_stream: "IMAGE:input_image_1"
|
|
||||||
input_stream: "MASK:0:multi_mask"
|
|
||||||
output_stream: "IMAGE:input_image_2"
|
|
||||||
}
|
|
||||||
|
|
||||||
node {
|
|
||||||
calculator: "SmoothFaceCalculator"
|
|
||||||
input_stream: "IMAGE:input_image_2"
|
|
||||||
input_stream: "MASK:0:multi_mask"
|
|
||||||
input_stream: "FACEBOX:face_box"
|
|
||||||
output_stream: "IMAGE:output_image"
|
output_stream: "IMAGE:output_image"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Draws annotations and overlays them on top of the input images.
|
|
||||||
#node {
|
|
||||||
# calculator: "AnnotationOverlayCalculator"
|
|
||||||
# input_stream: "IMAGE:input_image"
|
|
||||||
# input_stream: "VECTOR:0:multi_face_landmarks_render_data"
|
|
||||||
# output_stream: "IMAGE:output_image"
|
|
||||||
#}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user