WarpAffineCalculator on api2
This commit is contained in:
parent
51ed94633e
commit
ffa2853b79
|
@ -64,10 +64,6 @@ public:
|
|||
return vector<T>(M.ptr<T>(0), M.ptr<T>(0) + dims[1]);
|
||||
}
|
||||
|
||||
/* vector<int> get_dims() {
|
||||
return dims;
|
||||
} */
|
||||
|
||||
T at(vector<int> _indexes) {
|
||||
return M.at<T>(_indexes.data());
|
||||
}
|
||||
|
|
|
@ -283,9 +283,9 @@ namespace mediapipe
|
|||
|
||||
absl::Status FaceProcessorCalculator::ProcessImage(CalculatorContext *cc)
|
||||
{
|
||||
double alfaNose = 2.7;
|
||||
double alfaLips = 0.7;
|
||||
double alfaCheekbones = 0.7;
|
||||
double alfaNose = 1.2;
|
||||
double alfaLips = 0.4;
|
||||
double alfaCheekbones = 0.4;
|
||||
|
||||
if (cc->Inputs().HasTag(kNormLandmarksTag))
|
||||
{
|
||||
|
@ -381,7 +381,7 @@ namespace mediapipe
|
|||
|
||||
Tensor<double> _src = __facePts.index(_trianglesIndexes).index(_order);
|
||||
Tensor<double> _dst = ___facePts.index(_trianglesIndexes).index(_order);
|
||||
// cout << _src.get_dims().size() << endl;
|
||||
|
||||
auto srcPtr = absl::make_unique<Tensor<double>>(_src);
|
||||
cc->Outputs().Tag(kSrcTensorTag).Add(srcPtr.release(), cc->InputTimestamp());
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include "Tensor.h"
|
||||
#include "mediapipe/framework/calculator_framework.h"
|
||||
#include "mediapipe/framework/api2/node.h"
|
||||
#include "mediapipe/framework/formats/image_format.pb.h"
|
||||
#include "mediapipe/framework/formats/image_frame.h"
|
||||
#include "mediapipe/framework/formats/image_frame_opencv.h"
|
||||
|
@ -23,201 +24,48 @@
|
|||
#include "mediapipe/framework/port/opencv_highgui_inc.h"
|
||||
#include "mediapipe/framework/port/status.h"
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
namespace mediapipe
|
||||
{
|
||||
namespace
|
||||
namespace api2
|
||||
{
|
||||
constexpr char kImageFrameTag[] = "IMAGE";
|
||||
constexpr char kSrcTag[] = "SRC_TENSOR";
|
||||
constexpr char kDstTag[] = "DST_TENSOR";
|
||||
|
||||
inline bool HasImageTag(mediapipe::CalculatorContext *cc) { return false; }
|
||||
} // namespace
|
||||
|
||||
class WarpAffineCalculator : public CalculatorBase
|
||||
class WarpAffineCalculator : public Node
|
||||
{
|
||||
public:
|
||||
WarpAffineCalculator() = default;
|
||||
~WarpAffineCalculator() override = default;
|
||||
static constexpr Input<ImageFrame> kImageFrame{"IMAGE"};
|
||||
static constexpr Input<Tensor<double>>::Optional kSrc{"SRC_TENSOR"};
|
||||
static constexpr Input<Tensor<double>>::Optional kDst{"DST_TENSOR"};
|
||||
static constexpr Output<ImageFrame> kOut{"IMAGE"};
|
||||
|
||||
static absl::Status GetContract(CalculatorContract *cc);
|
||||
MEDIAPIPE_NODE_CONTRACT(kImageFrame, kSrc, kDst, kOut);
|
||||
|
||||
absl::Status Open(CalculatorContext *cc) override;
|
||||
absl::Status Process(CalculatorContext *cc) override;
|
||||
absl::Status Close(CalculatorContext *cc) override;
|
||||
|
||||
private:
|
||||
absl::Status CreateRenderTargetCpu(CalculatorContext *cc,
|
||||
std::unique_ptr<cv::Mat> &image_mat,
|
||||
ImageFormat::Format *target_format);
|
||||
|
||||
absl::Status RenderToCpu(
|
||||
CalculatorContext *cc, const ImageFormat::Format &target_format,
|
||||
uchar *data_image, std::unique_ptr<cv::Mat> &image_mat);
|
||||
|
||||
absl::Status AffineTransform(CalculatorContext *cc, std::unique_ptr<cv::Mat> &image_mat, Tensor<double> _src, Tensor<double> _dst);
|
||||
|
||||
bool image_frame_available_ = false;
|
||||
std::unique_ptr<Mat> image_mat;
|
||||
};
|
||||
|
||||
absl::Status WarpAffineCalculator::GetContract(CalculatorContract *cc)
|
||||
static absl::Status UpdateContract(CalculatorContract *cc)
|
||||
{
|
||||
RET_CHECK(cc->Inputs().HasTag(kImageFrameTag));
|
||||
|
||||
if (cc->Inputs().HasTag(kImageFrameTag))
|
||||
{
|
||||
cc->Inputs().Tag(kImageFrameTag).Set<ImageFrame>();
|
||||
}
|
||||
if (cc->Inputs().HasTag(kSrcTag))
|
||||
{
|
||||
cc->Inputs().Tag(kSrcTag).Set<Tensor<double>>();
|
||||
}
|
||||
if (cc->Inputs().HasTag(kDstTag))
|
||||
{
|
||||
cc->Inputs().Tag(kDstTag).Set<Tensor<double>>();
|
||||
}
|
||||
if (cc->Outputs().HasTag(kImageFrameTag))
|
||||
{
|
||||
cc->Outputs().Tag(kImageFrameTag).Set<ImageFrame>();
|
||||
}
|
||||
|
||||
RET_CHECK(kOut(cc).IsConnected())
|
||||
<< "At least one output stream is expected.";
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status WarpAffineCalculator::Open(CalculatorContext *cc)
|
||||
absl::Status Process(CalculatorContext *cc) override
|
||||
{
|
||||
cc->SetOffset(TimestampDiff(0));
|
||||
|
||||
if (cc->Inputs().HasTag(kImageFrameTag) || HasImageTag(cc))
|
||||
{
|
||||
image_frame_available_ = true;
|
||||
}
|
||||
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status WarpAffineCalculator::Process(CalculatorContext *cc)
|
||||
{
|
||||
if (cc->Inputs().Tag(kImageFrameTag).IsEmpty())
|
||||
if (kImageFrame(cc).IsEmpty())
|
||||
{
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
ImageFormat::Format target_format;
|
||||
const ImageFrame &input = *kImageFrame(cc);
|
||||
auto image = absl::make_unique<cv::Mat>(
|
||||
input.Height(), input.Width(), CV_8UC3);
|
||||
|
||||
MP_RETURN_IF_ERROR(CreateRenderTargetCpu(cc, image_mat, &target_format));
|
||||
|
||||
if (!cc->Inputs().Tag(kSrcTag).IsEmpty() && !cc->Inputs().Tag(kDstTag).IsEmpty())
|
||||
{
|
||||
const Tensor<double> _src = cc->Inputs().Tag(kSrcTag).Get<Tensor<double>>();
|
||||
const Tensor<double> _dst = cc->Inputs().Tag(kDstTag).Get<Tensor<double>>();
|
||||
MP_RETURN_IF_ERROR(AffineTransform(cc, image_mat, _src, _dst));
|
||||
}
|
||||
|
||||
// Copy the rendered image to output.
|
||||
uchar *image_mat_ptr = image_mat->data;
|
||||
MP_RETURN_IF_ERROR(RenderToCpu(cc, target_format, image_mat_ptr, image_mat));
|
||||
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status WarpAffineCalculator::Close(CalculatorContext *cc)
|
||||
{
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status WarpAffineCalculator::RenderToCpu(
|
||||
CalculatorContext *cc, const ImageFormat::Format &target_format,
|
||||
uchar *data_image, std::unique_ptr<cv::Mat> &image_mat)
|
||||
{
|
||||
auto output_frame = absl::make_unique<ImageFrame>(
|
||||
target_format, image_mat->cols, image_mat->rows);
|
||||
|
||||
output_frame->CopyPixelData(target_format, image_mat->cols, image_mat->rows, data_image,
|
||||
ImageFrame::kDefaultAlignmentBoundary);
|
||||
|
||||
if (cc->Outputs().HasTag(kImageFrameTag))
|
||||
{
|
||||
cc->Outputs()
|
||||
.Tag(kImageFrameTag)
|
||||
.Add(output_frame.release(), cc->InputTimestamp());
|
||||
}
|
||||
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status WarpAffineCalculator::CreateRenderTargetCpu(
|
||||
CalculatorContext *cc, std::unique_ptr<cv::Mat> &image_mat,
|
||||
ImageFormat::Format *target_format)
|
||||
{
|
||||
if (image_frame_available_)
|
||||
{
|
||||
const auto &input_frame =
|
||||
cc->Inputs().Tag(kImageFrameTag).Get<ImageFrame>();
|
||||
|
||||
int target_mat_type;
|
||||
switch (input_frame.Format())
|
||||
{
|
||||
case ImageFormat::SRGBA:
|
||||
*target_format = ImageFormat::SRGBA;
|
||||
target_mat_type = CV_8UC4;
|
||||
break;
|
||||
case ImageFormat::SRGB:
|
||||
*target_format = ImageFormat::SRGB;
|
||||
target_mat_type = CV_8UC3;
|
||||
break;
|
||||
case ImageFormat::SBGR:
|
||||
*target_format = ImageFormat::SBGR;
|
||||
target_mat_type = CV_8UC3;
|
||||
break;
|
||||
case ImageFormat::GRAY8:
|
||||
*target_format = ImageFormat::SRGB;
|
||||
target_mat_type = CV_8UC3;
|
||||
break;
|
||||
default:
|
||||
return absl::UnknownError("Unexpected image frame format.");
|
||||
break;
|
||||
}
|
||||
|
||||
image_mat = absl::make_unique<cv::Mat>(
|
||||
input_frame.Height(), input_frame.Width(), target_mat_type);
|
||||
|
||||
auto input_mat = formats::MatView(&input_frame);
|
||||
|
||||
if (input_frame.Format() == ImageFormat::GRAY8)
|
||||
{
|
||||
cv::Mat rgb_mat;
|
||||
cv::cvtColor(input_mat, rgb_mat, CV_GRAY2RGB);
|
||||
rgb_mat.copyTo(*image_mat);
|
||||
}
|
||||
else
|
||||
{
|
||||
input_mat.copyTo(*image_mat);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
image_mat = absl::make_unique<cv::Mat>(
|
||||
1920, 1080, CV_8UC4,
|
||||
cv::Scalar(cv::Scalar::all(255)));
|
||||
*target_format = ImageFormat::SRGBA;
|
||||
}
|
||||
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status WarpAffineCalculator::AffineTransform(CalculatorContext *cc, std::unique_ptr<cv::Mat> &image_mat, Tensor<double> _src, Tensor<double> _dst)
|
||||
{
|
||||
Mat mat_image_ = *image_mat.get();
|
||||
Mat clone_image = mat_image_.clone();
|
||||
|
||||
Mat outImage = Mat(mat_image_.size(), mat_image_.type());
|
||||
auto mat_image_ = formats::MatView(&input);
|
||||
Mat out = mat_image_.clone();
|
||||
|
||||
if (!kSrc(cc).IsEmpty() && !kDst(cc).IsEmpty())
|
||||
{
|
||||
Tensor<double> _src = (*kSrc(cc));
|
||||
Tensor<double> _dst = (*kDst(cc));
|
||||
|
||||
Mat clone_image = mat_image_.clone();
|
||||
|
||||
for (int i = 0; i < 854; ++i)
|
||||
{
|
||||
if (i == 246)
|
||||
|
@ -277,9 +125,21 @@ namespace mediapipe
|
|||
}
|
||||
}
|
||||
}
|
||||
out.copyTo(*image_mat);
|
||||
}
|
||||
|
||||
out.copyTo(*image);
|
||||
|
||||
auto output_frame = absl::make_unique<ImageFrame>(
|
||||
input.Format(), mat_image_.cols, mat_image_.rows);
|
||||
uchar *image_mat_ptr = image->data;
|
||||
output_frame->CopyPixelData(input.Format(), mat_image_.cols, mat_image_.rows, image_mat_ptr,
|
||||
ImageFrame::kDefaultAlignmentBoundary);
|
||||
|
||||
kOut(cc).Send(std::move(output_frame));
|
||||
return absl::OkStatus();
|
||||
}
|
||||
REGISTER_CALCULATOR(WarpAffineCalculator);
|
||||
};
|
||||
|
||||
MEDIAPIPE_REGISTER_NODE(WarpAffineCalculator);
|
||||
}
|
||||
} // namespace mediapipe
|
Loading…
Reference in New Issue
Block a user