"docs/vscode:/vscode.git/clone" did not exist on "b38b6078dc5b647290ed5bb0dcabdfa58b556dc9"
Commit 546b4279 authored by limm's avatar limm
Browse files

add csrc and mmdeploy module

parent 502f4fb9
Pipeline #2810 canceled with stages
// Copyright (c) OpenMMLab. All rights reserved.
#ifndef MMDEPLOY_CSRC_MMDEPLOY_APIS_CXX_COMMON_H_
#define MMDEPLOY_CSRC_MMDEPLOY_APIS_CXX_COMMON_H_
#include <memory>
#include <type_traits>
#include <utility>
#include <vector>
#include "mmdeploy/common.h"
#include "mmdeploy/core/mpl/span.h"
#include "mmdeploy/core/status_code.h"
#include "mmdeploy/core/types.h"
#include "mmdeploy/executor.h"
#include "mmdeploy/model.h"
#ifndef MMDEPLOY_CXX_USE_OPENCV
#define MMDEPLOY_CXX_USE_OPENCV 1
#endif
#if MMDEPLOY_CXX_USE_OPENCV
#include "opencv2/core/core.hpp"
#endif
namespace mmdeploy {
namespace cxx {
using Rect = mmdeploy_rect_t;
template <typename T>
class UniqueHandle : public NonCopyable {
public:
UniqueHandle() = default;
explicit UniqueHandle(T handle) : handle_(handle) {}
// derived class must destroy the object and reset `handle_`
~UniqueHandle() { assert(handle_ == nullptr); }
UniqueHandle(UniqueHandle&& o) noexcept : handle_(std::exchange(o.handle_, nullptr)) {}
UniqueHandle& operator=(UniqueHandle&& o) noexcept {
if (this != &o) {
handle_ = std::exchange(o.handle_, nullptr);
}
return *this;
}
explicit operator T() const noexcept { return handle_; }
T operator->() const noexcept { return handle_; }
protected:
T handle_{};
};
class Model {
public:
explicit Model(const char* path) {
mmdeploy_model_t model{};
auto ec = mmdeploy_model_create_by_path(path, &model);
if (ec != MMDEPLOY_SUCCESS) {
throw_exception(static_cast<ErrorCode>(ec));
}
model_.reset(model, [](auto p) { mmdeploy_model_destroy(p); });
}
explicit Model(const std::string& path) : Model(path.c_str()) {}
Model(const void* buffer, size_t size) {
mmdeploy_model_t model{};
auto ec = mmdeploy_model_create(buffer, static_cast<int>(size), &model);
if (ec != MMDEPLOY_SUCCESS) {
throw_exception(static_cast<ErrorCode>(ec));
}
model_.reset(model, [](auto p) { mmdeploy_model_destroy(p); });
}
operator mmdeploy_model_t() const noexcept { return model_.get(); }
private:
std::shared_ptr<mmdeploy_model> model_{};
};
class Device {
public:
explicit Device(std::string name, int index = 0) : name_(std::move(name)), index_(index) {
mmdeploy_device_t device{};
auto ec = mmdeploy_device_create(name_.c_str(), index, &device);
if (ec != MMDEPLOY_SUCCESS) {
throw_exception(static_cast<ErrorCode>(ec));
}
device_.reset(device, [](auto p) { mmdeploy_device_destroy(p); });
}
const char* name() const noexcept { return name_.c_str(); }
int index() const noexcept { return index_; }
operator mmdeploy_device_t() const noexcept { return device_.get(); }
private:
std::string name_;
int index_;
std::shared_ptr<mmdeploy_device> device_;
};
class Profiler {
public:
explicit Profiler(std::string_view path) : path_(path) {
mmdeploy_profiler_t profiler{};
auto ec = mmdeploy_profiler_create(path_.c_str(), &profiler);
if (ec != MMDEPLOY_SUCCESS) {
throw_exception(static_cast<ErrorCode>(ec));
}
profiler_.reset(profiler, [](auto p) { mmdeploy_profiler_destroy(p); });
};
operator mmdeploy_profiler_t() const noexcept { return profiler_.get(); }
private:
std::string path_;
std::shared_ptr<mmdeploy_profiler> profiler_;
};
class Mat {
public:
Mat() : desc_{} {}
Mat(int height, int width, int channels, mmdeploy_pixel_format_t format,
mmdeploy_data_type_t type, uint8_t* data, mmdeploy_device_t device = nullptr)
: desc_{data, height, width, channels, format, type, device} {}
Mat(const mmdeploy_mat_t& desc) : desc_(desc) {} // NOLINT
const mmdeploy_mat_t& desc() const noexcept { return desc_; }
#if MMDEPLOY_CXX_USE_OPENCV
Mat(const cv::Mat& mat, mmdeploy_pixel_format_t pixel_format)
: desc_{mat.data, mat.rows, mat.cols, mat.channels(), pixel_format, GetCvType(mat.depth())} {
if (pixel_format == MMDEPLOY_PIXEL_FORMAT_COUNT) {
throw_exception(eNotSupported);
}
if (desc_.type == MMDEPLOY_DATA_TYPE_COUNT) {
throw_exception(eNotSupported);
}
}
Mat(const cv::Mat& mat) : Mat(mat, GetCvFormat(mat.channels())) {}
static mmdeploy_data_type_t GetCvType(int depth) {
switch (depth) {
case CV_8U:
return MMDEPLOY_DATA_TYPE_UINT8;
case CV_32F:
return MMDEPLOY_DATA_TYPE_FLOAT;
default:
return MMDEPLOY_DATA_TYPE_COUNT;
}
}
static mmdeploy_pixel_format_t GetCvFormat(int channels) {
switch (channels) {
case 1:
return MMDEPLOY_PIXEL_FORMAT_GRAYSCALE;
case 3:
return MMDEPLOY_PIXEL_FORMAT_BGR;
case 4:
return MMDEPLOY_PIXEL_FORMAT_BGRA;
default:
return MMDEPLOY_PIXEL_FORMAT_COUNT;
}
}
#endif
private:
mmdeploy_mat_t desc_;
};
template <typename T>
class Result_ {
public:
using value_type = T;
using size_type = size_t;
using difference_type = ptrdiff_t;
using reference = T&;
using const_reference = const T&;
using pointer = T*;
using const_pointer = const T*;
using iterator = T*;
using const_iterator = T*;
Result_(size_t offset, size_t size, std::shared_ptr<T> data)
: offset_(offset), size_(size), data_(std::move(data)) {}
T& operator[](size_t index) const noexcept { return *(data_.get() + offset_ + index); }
size_t size() const noexcept { return size_; }
T* begin() const noexcept { return data_.get() + offset_; }
T* end() const noexcept { return begin() + size_; }
T* operator->() const noexcept { return data_.get(); }
T& operator*() const noexcept { return *data_; }
private:
size_t offset_;
size_t size_;
std::shared_ptr<T> data_;
};
inline const mmdeploy_mat_t* reinterpret(const Mat* p) {
return reinterpret_cast<const mmdeploy_mat_t*>(p);
}
class Scheduler {
public:
explicit Scheduler(mmdeploy_scheduler_t scheduler) {
scheduler_.reset(scheduler, [](auto p) { mmdeploy_scheduler_destroy(p); });
}
static Scheduler ThreadPool(int num_threads) {
return Scheduler(mmdeploy_executor_create_thread_pool(num_threads));
}
static Scheduler Thread() { return Scheduler(mmdeploy_executor_create_thread()); }
operator mmdeploy_scheduler_t() const noexcept { return scheduler_.get(); }
private:
std::shared_ptr<mmdeploy_scheduler> scheduler_;
};
class Context {
public:
Context() {
mmdeploy_context_t context{};
mmdeploy_context_create(&context);
context_.reset(context, [](auto p) { mmdeploy_context_destroy(p); });
}
/* implicit */ Context(const Device& device) : Context() { Add(device); }
void Add(const std::string& name, const Scheduler& scheduler) {
mmdeploy_context_add(*this, MMDEPLOY_TYPE_SCHEDULER, name.c_str(), scheduler);
}
void Add(const std::string& name, const Model& model) {
mmdeploy_context_add(*this, MMDEPLOY_TYPE_MODEL, name.c_str(), model);
}
void Add(const Device& device) {
mmdeploy_context_add(*this, MMDEPLOY_TYPE_DEVICE, nullptr, device);
}
void Add(const Profiler& profiler) {
mmdeploy_context_add(*this, MMDEPLOY_TYPE_PROFILER, nullptr, profiler);
}
operator mmdeploy_context_t() const noexcept { return context_.get(); }
private:
std::shared_ptr<mmdeploy_context> context_;
};
} // namespace cxx
using cxx::Context;
using cxx::Device;
using cxx::Mat;
using cxx::Model;
using cxx::Profiler;
using cxx::Rect;
using cxx::Scheduler;
} // namespace mmdeploy
#endif // MMDEPLOY_CSRC_MMDEPLOY_APIS_CXX_COMMON_H_
// Copyright (c) OpenMMLab. All rights reserved.
#ifndef MMDEPLOY_CSRC_MMDEPLOY_APIS_CXX_DETECTOR_HPP_
#define MMDEPLOY_CSRC_MMDEPLOY_APIS_CXX_DETECTOR_HPP_
#include "mmdeploy/common.hpp"
#include "mmdeploy/detector.h"
namespace mmdeploy {
namespace cxx {
using Detection = mmdeploy_detection_t;
class Detector : public NonMovable {
public:
Detector(const Model& model, const Context& context) {
auto ec = mmdeploy_detector_create_v2(model, context, &detector_);
if (ec != MMDEPLOY_SUCCESS) {
throw_exception(static_cast<ErrorCode>(ec));
}
}
~Detector() {
if (detector_) {
mmdeploy_detector_destroy(detector_);
detector_ = {};
}
}
using Result = Result_<Detection>;
std::vector<Result> Apply(Span<const Mat> images) {
if (images.empty()) {
return {};
}
Detection* results{};
int* result_count{};
auto ec = mmdeploy_detector_apply(detector_, reinterpret(images.data()),
static_cast<int>(images.size()), &results, &result_count);
if (ec != MMDEPLOY_SUCCESS) {
throw_exception(static_cast<ErrorCode>(ec));
}
std::shared_ptr<Detection> data(results, [result_count, count = images.size()](auto p) {
mmdeploy_detector_release_result(p, result_count, count);
});
std::vector<Result> rets;
rets.reserve(images.size());
size_t offset = 0;
for (size_t i = 0; i < images.size(); ++i) {
offset += rets.emplace_back(offset, result_count[i], data).size();
}
return rets;
}
Result Apply(const Mat& image) { return Apply(Span{image})[0]; }
private:
mmdeploy_detector_t detector_{};
};
} // namespace cxx
using cxx::Detection;
using cxx::Detector;
} // namespace mmdeploy
#endif // MMDEPLOY_CSRC_MMDEPLOY_APIS_CXX_DETECTOR_HPP_
// Copyright (c) OpenMMLab. All rights reserved.
#ifndef MMDEPLOY_CSRC_MMDEPLOY_APIS_CXX_MMDEPLOY_PIPELINE_HPP_
#define MMDEPLOY_CSRC_MMDEPLOY_APIS_CXX_MMDEPLOY_PIPELINE_HPP_
#include "mmdeploy/common.hpp"
#include "mmdeploy/core/value.h"
#include "mmdeploy/pipeline.h"
namespace mmdeploy {
namespace cxx {
class Pipeline : public NonMovable {
public:
Pipeline(const Value& config, const Context& context) {
mmdeploy_pipeline_t pipeline{};
auto ec = mmdeploy_pipeline_create_v3((mmdeploy_value_t)&config, context, &pipeline);
if (ec != MMDEPLOY_SUCCESS) {
throw_exception(static_cast<ErrorCode>(ec));
}
pipeline_ = pipeline;
}
~Pipeline() {
if (pipeline_) {
mmdeploy_pipeline_destroy(pipeline_);
pipeline_ = nullptr;
}
}
Value Apply(const Value& inputs) {
mmdeploy_value_t tmp{};
auto ec = mmdeploy_pipeline_apply(pipeline_, (mmdeploy_value_t)&inputs, &tmp);
if (ec != MMDEPLOY_SUCCESS) {
throw_exception(static_cast<ErrorCode>(ec));
}
Value output = std::move(*(Value*)tmp);
mmdeploy_value_destroy(tmp);
return output;
}
Value Apply(Span<const Mat> images) {
if (images.empty()) {
return {};
}
mmdeploy_value_t inputs{};
auto ec = mmdeploy_common_create_input(reinterpret(images.data()),
static_cast<int>(images.size()), &inputs);
if (ec != MMDEPLOY_SUCCESS) {
throw_exception(static_cast<ErrorCode>(ec));
}
auto outputs = Apply(*reinterpret_cast<Value*>(inputs));
mmdeploy_value_destroy(inputs);
return outputs;
}
Value Apply(const Mat& image) {
auto outputs = Apply(Span{image});
Value::Array rets;
rets.reserve(outputs.size());
for (auto& output : outputs) {
rets.push_back(std::move(output[0]));
}
return rets;
}
private:
mmdeploy_pipeline_t pipeline_{};
};
} // namespace cxx
using cxx::Pipeline;
} // namespace mmdeploy
#endif // MMDEPLOY_CSRC_MMDEPLOY_APIS_CXX_MMDEPLOY_PIPELINE_HPP_
// Copyright (c) OpenMMLab. All rights reserved.
#ifndef MMDEPLOY_CSRC_MMDEPLOY_APIS_CXX_MMDEPLOY_POSE_DETECTOR_HPP_
#define MMDEPLOY_CSRC_MMDEPLOY_APIS_CXX_MMDEPLOY_POSE_DETECTOR_HPP_
#include "mmdeploy/common.hpp"
#include "mmdeploy/pose_detector.h"
namespace mmdeploy {
namespace cxx {
using PoseDetection = mmdeploy_pose_detection_t;
class PoseDetector : public NonMovable {
public:
PoseDetector(const Model& model, const Context& context) {
auto ec = mmdeploy_pose_detector_create_v2(model, context, &detector_);
if (ec != MMDEPLOY_SUCCESS) {
throw_exception(static_cast<ErrorCode>(ec));
}
}
~PoseDetector() {
if (detector_) {
mmdeploy_pose_detector_destroy(detector_);
detector_ = {};
}
}
using Result = Result_<PoseDetection>;
std::vector<Result> Apply(Span<const Mat> images, Span<const Rect> bboxes,
Span<const int> bbox_count) {
if (images.empty()) {
return {};
}
const mmdeploy_rect_t* p_bboxes{};
const int* p_bbox_count{};
if (!bboxes.empty()) {
p_bboxes = bboxes.data();
p_bbox_count = bbox_count.data();
}
PoseDetection* results{};
auto ec = mmdeploy_pose_detector_apply_bbox(detector_, reinterpret(images.data()),
static_cast<int>(images.size()), p_bboxes,
p_bbox_count, &results);
if (ec != MMDEPLOY_SUCCESS) {
throw_exception(static_cast<ErrorCode>(ec));
}
std::shared_ptr<PoseDetection> data(results, [count = images.size()](auto p) {
mmdeploy_pose_detector_release_result(p, count);
});
std::vector<Result> rets;
rets.reserve(images.size());
size_t offset = 0;
for (size_t i = 0; i < images.size(); ++i) {
offset += rets.emplace_back(offset, bboxes.empty() ? 1 : bbox_count[i], data).size();
}
return rets;
}
Result Apply(const Mat& image, Span<const Rect> bboxes = {}) {
return Apply(Span{image}, bboxes, {static_cast<int>(bboxes.size())})[0];
}
private:
mmdeploy_pose_detector_t detector_{};
};
} // namespace cxx
using cxx::PoseDetection;
using cxx::PoseDetector;
} // namespace mmdeploy
#endif // MMDEPLOY_CSRC_MMDEPLOY_APIS_CXX_MMDEPLOY_POSE_DETECTOR_HPP_
// Copyright (c) OpenMMLab. All rights reserved.
#ifndef MMDEPLOY_POSE_TRACKER_HPP
#define MMDEPLOY_POSE_TRACKER_HPP
#include "mmdeploy/common.hpp"
#include "mmdeploy/pose_tracker.h"
namespace mmdeploy {
namespace cxx {
class PoseTracker : public UniqueHandle<mmdeploy_pose_tracker_t> {
public:
using Result = Result_<mmdeploy_pose_tracker_target_t>;
class State;
class Params;
public:
/**
* @brief Create pose tracker pipeline
* @param detect object detection model
* @param pose pose estimation model
* @param context execution context
*/
PoseTracker(const Model& detect, const Model& pose, const Context& context) {
auto ec = mmdeploy_pose_tracker_create(detect, pose, context, &handle_);
if (ec != MMDEPLOY_SUCCESS) {
throw_exception(static_cast<ErrorCode>(ec));
}
}
~PoseTracker() {
if (handle_) {
mmdeploy_pose_tracker_destroy(handle_);
handle_ = {};
}
}
PoseTracker(PoseTracker&&) noexcept = default;
/**
* @brief Create a tracker state corresponds to a video stream
* @param params params for creating the tracker state
* @return created tracker state
*/
State CreateState(const Params& params);
/**
* @brief Apply pose tracker pipeline
* @param state tracker state
* @param frame input video frame
* @param detect control the use of detector
* -1: use params.det_interval, 0: don't use detector, 1: force use detector
* @return
*/
Result Apply(State& state, const Mat& frame, int detect = -1);
/**
* @brief batched version of Apply
* @param states
* @param frames
* @param detects
* @return
*/
std::vector<Result> Apply(const Span<State>& states, const Span<const Mat>& frames,
const Span<const int>& detects = {});
public:
/**
* see \ref mmdeploy/pose_tracker.h for detail
*/
class Params : public UniqueHandle<mmdeploy_pose_tracker_param_t*> {
public:
explicit Params() {
handle_ = new mmdeploy_pose_tracker_param_t{};
mmdeploy_pose_tracker_default_params(handle_);
}
~Params() {
if (handle_) {
delete handle_;
handle_ = {};
}
}
};
class State : public UniqueHandle<mmdeploy_pose_tracker_state_t> {
public:
explicit State(mmdeploy_pose_tracker_t pipeline, const mmdeploy_pose_tracker_param_t* params) {
auto ec = mmdeploy_pose_tracker_create_state(pipeline, params, &handle_);
if (ec != MMDEPLOY_SUCCESS) {
throw_exception(static_cast<ErrorCode>(ec));
}
}
~State() {
if (handle_) {
mmdeploy_pose_tracker_destroy_state(handle_);
handle_ = {};
}
}
State(State&&) noexcept = default;
};
};
inline PoseTracker::State PoseTracker::CreateState(const PoseTracker::Params& params) {
return State(handle_, static_cast<mmdeploy_pose_tracker_param_t*>(params));
}
inline std::vector<PoseTracker::Result> PoseTracker::Apply(const Span<State>& states,
const Span<const Mat>& frames,
const Span<const int32_t>& detects) {
if (frames.empty()) {
return {};
}
mmdeploy_pose_tracker_target_t* results{};
int32_t* result_count{};
auto ec = mmdeploy_pose_tracker_apply(
handle_, reinterpret_cast<mmdeploy_pose_tracker_state_t*>(states.data()),
reinterpret(frames.data()), detects.data(), static_cast<int32_t>(frames.size()), &results,
&result_count);
if (ec != MMDEPLOY_SUCCESS) {
throw_exception(static_cast<ErrorCode>(ec));
}
std::shared_ptr<mmdeploy_pose_tracker_target_t> data(
results, [result_count, count = frames.size()](auto p) {
mmdeploy_pose_tracker_release_result(p, result_count, count);
});
std::vector<Result> rets;
rets.reserve(frames.size());
size_t offset = 0;
for (size_t i = 0; i < frames.size(); ++i) {
offset += rets.emplace_back(offset, result_count[i], data).size();
}
return rets;
}
inline PoseTracker::Result PoseTracker::Apply(PoseTracker::State& state, const Mat& frame,
int32_t detect) {
return Apply(Span(&state, 1), Span{frame}, Span{detect})[0];
}
} // namespace cxx
using cxx::PoseTracker;
} // namespace mmdeploy
#endif // MMDEPLOY_POSE_TRACKER_HPP
// Copyright (c) OpenMMLab. All rights reserved.
#ifndef MMDEPLOY_CSRC_MMDEPLOY_APIS_CXX_RESTORER_HPP_
#define MMDEPLOY_CSRC_MMDEPLOY_APIS_CXX_RESTORER_HPP_
#include "mmdeploy/common.hpp"
#include "mmdeploy/restorer.h"
namespace mmdeploy {
namespace cxx {
class Restorer : public NonMovable {
public:
Restorer(const Model& model, const Context& context) {
auto ec = mmdeploy_restorer_create_v2(model, context, &restorer_);
if (ec != MMDEPLOY_SUCCESS) {
throw_exception(static_cast<ErrorCode>(ec));
}
}
~Restorer() {
if (restorer_) {
mmdeploy_restorer_destroy(restorer_);
restorer_ = {};
}
}
using Result = Result_<mmdeploy_mat_t>;
std::vector<Result> Apply(Span<const Mat> images) {
if (images.empty()) {
return {};
}
mmdeploy_mat_t* results{};
auto ec = mmdeploy_restorer_apply(restorer_, reinterpret(images.data()),
static_cast<int>(images.size()), &results);
if (ec != MMDEPLOY_SUCCESS) {
throw_exception(static_cast<ErrorCode>(ec));
}
std::vector<Result> rets;
rets.reserve(images.size());
std::shared_ptr<mmdeploy_mat_t> data(
results, [count = images.size()](auto p) { mmdeploy_restorer_release_result(p, count); });
for (size_t i = 0; i < images.size(); ++i) {
rets.emplace_back(i, 1, data);
}
return rets;
}
Result Apply(const Mat& image) { return Apply(Span{image})[0]; }
private:
mmdeploy_restorer_t restorer_{};
};
} // namespace cxx
using cxx::Restorer;
} // namespace mmdeploy
#endif // MMDEPLOY_CSRC_MMDEPLOY_APIS_CXX_RESTORER_HPP_
// Copyright (c) OpenMMLab. All rights reserved.
#ifndef MMDEPLOY_CSRC_MMDEPLOY_APIS_CXX_MMDEPLOY_ROTATED_DETECTOR_HPP_
#define MMDEPLOY_CSRC_MMDEPLOY_APIS_CXX_MMDEPLOY_ROTATED_DETECTOR_HPP_
#include "mmdeploy/common.hpp"
#include "mmdeploy/rotated_detector.h"
namespace mmdeploy {
namespace cxx {
using RotatedDetection = mmdeploy_rotated_detection_t;
class RotatedDetector : public NonMovable {
public:
RotatedDetector(const Model& model, const Context& context) {
auto ec = mmdeploy_rotated_detector_create_v2(model, context, &detector_);
if (ec != MMDEPLOY_SUCCESS) {
throw_exception(static_cast<ErrorCode>(ec));
}
}
~RotatedDetector() {
if (detector_) {
mmdeploy_rotated_detector_destroy(detector_);
detector_ = {};
}
}
using Result = Result_<RotatedDetection>;
std::vector<Result> Apply(Span<const Mat> images) {
if (images.empty()) {
return {};
}
RotatedDetection* results{};
int* result_count{};
auto ec =
mmdeploy_rotated_detector_apply(detector_, reinterpret(images.data()),
static_cast<int>(images.size()), &results, &result_count);
if (ec != MMDEPLOY_SUCCESS) {
throw_exception(static_cast<ErrorCode>(ec));
}
std::shared_ptr<RotatedDetection> data(results, [result_count](auto p) {
mmdeploy_rotated_detector_release_result(p, result_count);
});
std::vector<Result> rets;
rets.reserve(images.size());
size_t offset = 0;
for (size_t i = 0; i < images.size(); ++i) {
offset += rets.emplace_back(offset, result_count[i], data).size();
}
return rets;
}
Result Apply(const Mat& image) { return Apply(Span{image})[0]; }
private:
mmdeploy_rotated_detector_t detector_{};
};
} // namespace cxx
using cxx::RotatedDetection;
using cxx::RotatedDetector;
} // namespace mmdeploy
#endif // MMDEPLOY_CSRC_MMDEPLOY_APIS_CXX_MMDEPLOY_ROTATED_DETECTOR_HPP_
// Copyright (c) OpenMMLab. All rights reserved.
#ifndef MMDEPLOY_CSRC_MMDEPLOY_APIS_CXX_SEGMENTOR_HPP_
#define MMDEPLOY_CSRC_MMDEPLOY_APIS_CXX_SEGMENTOR_HPP_
#include "mmdeploy/common.hpp"
#include "mmdeploy/segmentor.h"
namespace mmdeploy {
namespace cxx {
using Segmentation = mmdeploy_segmentation_t;
class Segmentor : public NonMovable {
public:
Segmentor(const Model& model, const Context& context) {
auto ec = mmdeploy_segmentor_create_v2(model, context, &segmentor_);
if (ec != MMDEPLOY_SUCCESS) {
throw_exception(static_cast<ErrorCode>(ec));
}
}
~Segmentor() {
if (segmentor_) {
mmdeploy_segmentor_destroy(segmentor_);
segmentor_ = {};
}
}
using Result = Result_<Segmentation>;
std::vector<Result> Apply(Span<const Mat> images) {
if (images.empty()) {
return {};
}
Segmentation* results{};
auto ec = mmdeploy_segmentor_apply(segmentor_, reinterpret(images.data()),
static_cast<int>(images.size()), &results);
if (ec != MMDEPLOY_SUCCESS) {
throw_exception(static_cast<ErrorCode>(ec));
}
std::vector<Result> rets;
rets.reserve(images.size());
std::shared_ptr<Segmentation> data(
results, [count = images.size()](auto p) { mmdeploy_segmentor_release_result(p, count); });
for (size_t i = 0; i < images.size(); ++i) {
rets.emplace_back(i, 1, data);
}
return rets;
}
Result Apply(const Mat& image) { return Apply(Span{image})[0]; }
private:
mmdeploy_segmentor_t segmentor_{};
};
} // namespace cxx
using cxx::Segmentation;
using cxx::Segmentor;
} // namespace mmdeploy
#endif // MMDEPLOY_CSRC_MMDEPLOY_APIS_CXX_SEGMENTOR_HPP_
// Copyright (c) OpenMMLab. All rights reserved.
#ifndef MMDEPLOY_CSRC_MMDEPLOY_APIS_CXX_TEXT_DETECTOR_HPP_
#define MMDEPLOY_CSRC_MMDEPLOY_APIS_CXX_TEXT_DETECTOR_HPP_
#include "mmdeploy/common.hpp"
#include "mmdeploy/text_detector.h"
namespace mmdeploy {
namespace cxx {
using TextDetection = mmdeploy_text_detection_t;
class TextDetector : public NonMovable {
public:
TextDetector(const Model& model, const Context& context) {
auto ec = mmdeploy_text_detector_create_v2(model, context, &detector_);
if (ec != MMDEPLOY_SUCCESS) {
throw_exception(static_cast<ErrorCode>(ec));
}
}
~TextDetector() {
if (detector_) {
mmdeploy_text_detector_destroy(detector_);
detector_ = {};
}
}
using Result = Result_<TextDetection>;
std::vector<Result> Apply(Span<const Mat> images) {
if (images.empty()) {
return {};
}
TextDetection* results{};
int* result_count{};
auto ec =
mmdeploy_text_detector_apply(detector_, reinterpret(images.data()),
static_cast<int>(images.size()), &results, &result_count);
if (ec != MMDEPLOY_SUCCESS) {
throw_exception(static_cast<ErrorCode>(ec));
}
std::shared_ptr<TextDetection> data(results, [result_count, count = images.size()](auto p) {
mmdeploy_text_detector_release_result(p, result_count, count);
});
std::vector<Result> rets;
rets.reserve(images.size());
size_t offset = 0;
for (size_t i = 0; i < images.size(); ++i) {
offset += rets.emplace_back(offset, result_count[i], data).size();
}
return rets;
}
Result Apply(const Mat& image) { return Apply(Span{image})[0]; }
private:
mmdeploy_text_detector_t detector_{};
};
} // namespace cxx
using cxx::TextDetection;
using cxx::TextDetector;
} // namespace mmdeploy
#endif // MMDEPLOY_CSRC_MMDEPLOY_APIS_CXX_TEXT_DETECTOR_HPP_
// Copyright (c) OpenMMLab. All rights reserved.
#ifndef MMDEPLOY_CSRC_MMDEPLOY_APIS_CXX_TEXT_RECOGNIZER_HPP_
#define MMDEPLOY_CSRC_MMDEPLOY_APIS_CXX_TEXT_RECOGNIZER_HPP_
#include <numeric>
#include "mmdeploy/common.hpp"
#include "mmdeploy/text_detector.hpp"
#include "mmdeploy/text_recognizer.h"
namespace mmdeploy {
namespace cxx {
using TextRecognition = mmdeploy_text_recognition_t;
class TextRecognizer : public NonMovable {
public:
TextRecognizer(const Model& model, const Context& context) {
auto ec = mmdeploy_text_recognizer_create_v2(model, context, &recognizer_);
if (ec != MMDEPLOY_SUCCESS) {
throw_exception(static_cast<ErrorCode>(ec));
}
}
~TextRecognizer() {
if (recognizer_) {
mmdeploy_text_recognizer_destroy(recognizer_);
recognizer_ = {};
}
}
using Result = Result_<TextRecognition>;
std::vector<Result> Apply(Span<const Mat> images, Span<const TextDetection> bboxes,
Span<const int> bbox_count) {
if (images.empty()) {
return {};
}
const TextDetection* p_bboxes{};
const int* p_bbox_count{};
auto n_total_bboxes = static_cast<int>(images.size());
if (!bboxes.empty()) {
p_bboxes = bboxes.data();
p_bbox_count = bbox_count.data();
n_total_bboxes = std::accumulate(bbox_count.begin(), bbox_count.end(), 0);
}
TextRecognition* results{};
auto ec = mmdeploy_text_recognizer_apply_bbox(recognizer_, reinterpret(images.data()),
static_cast<int>(images.size()), p_bboxes,
p_bbox_count, &results);
if (ec != MMDEPLOY_SUCCESS) {
throw_exception(static_cast<ErrorCode>(ec));
}
std::shared_ptr<TextRecognition> data(results, [count = n_total_bboxes](auto p) {
mmdeploy_text_recognizer_release_result(p, count);
});
std::vector<Result> rets;
rets.reserve(images.size());
size_t offset = 0;
for (size_t i = 0; i < images.size(); ++i) {
offset += rets.emplace_back(offset, bboxes.empty() ? 1 : bbox_count[i], data).size();
}
return rets;
}
Result Apply(const Mat& image, Span<const TextDetection> bboxes = {}) {
return Apply(Span{image}, bboxes, {static_cast<int>(bboxes.size())})[0];
}
private:
mmdeploy_text_recognizer_t recognizer_{};
};
} // namespace cxx
using cxx::TextRecognition;
using cxx::TextRecognizer;
} // namespace mmdeploy
#endif // MMDEPLOY_CSRC_MMDEPLOY_APIS_CXX_TEXT_RECOGNIZER_HPP_
// Copyright (c) OpenMMLab. All rights reserved.
#ifndef MMDEPLOY_CSRC_MMDEPLOY_APIS_CXX_VIDEO_RECOGNIZER_HPP_
#define MMDEPLOY_CSRC_MMDEPLOY_APIS_CXX_VIDEO_RECOGNIZER_HPP_
#include "mmdeploy/common.hpp"
#include "mmdeploy/video_recognizer.h"
namespace mmdeploy {
namespace cxx {
using VideoRecognition = mmdeploy_video_recognition_t;
using VideoSampleInfo = mmdeploy_video_sample_info_t;
class VideoRecognizer : public NonMovable {
public:
VideoRecognizer(const Model& model, const Context& context) {
auto ec = mmdeploy_video_recognizer_create_v2(model, context, &recognizer_);
if (ec != MMDEPLOY_SUCCESS) {
throw_exception(static_cast<ErrorCode>(ec));
}
}
~VideoRecognizer() {
if (recognizer_) {
mmdeploy_video_recognizer_destroy(recognizer_);
recognizer_ = {};
}
}
using Result = Result_<VideoRecognition>;
std::vector<Result> Apply(Span<const std::vector<Mat>> videos,
Span<const VideoSampleInfo> infos) {
if (videos.empty()) {
return {};
}
int video_count = videos.size();
VideoRecognition* results{};
int* result_count{};
std::vector<Mat> images;
std::vector<VideoSampleInfo> video_info;
for (int i = 0; i < videos.size(); i++) {
for (auto& mat : videos[i]) {
images.push_back(mat);
}
video_info.push_back(infos[i]);
}
auto ec =
mmdeploy_video_recognizer_apply(recognizer_, reinterpret(images.data()), video_info.data(),
video_count, &results, &result_count);
if (ec != MMDEPLOY_SUCCESS) {
throw_exception(static_cast<ErrorCode>(ec));
}
std::vector<Result> rets;
rets.reserve(video_count);
std::shared_ptr<VideoRecognition> data(results, [result_count, count = video_count](auto p) {
mmdeploy_video_recognizer_release_result(p, result_count, count);
});
size_t offset = 0;
for (size_t i = 0; i < video_count; ++i) {
offset += rets.emplace_back(offset, result_count[i], data).size();
}
return rets;
}
Result Apply(const std::vector<Mat>& video, const VideoSampleInfo info) {
return Apply(Span{video}, Span{info})[0];
}
private:
mmdeploy_video_recognizer_t recognizer_{};
};
} // namespace cxx
using cxx::VideoRecognition;
using cxx::VideoRecognizer;
using cxx::VideoSampleInfo;
} // namespace mmdeploy
#endif // MMDEPLOY_CSRC_MMDEPLOY_APIS_CXX_VIDEO_RECOGNIZER_HPP_
if (NOT MMDEPLOY_BUILD_SDK_JAVA_API)
return ()
endif ()
project(mmdeploy_java_package)
find_package(Java REQUIRED)
include(UseJava)
add_subdirectory(native)
add_jar(${PROJECT_NAME} SOURCES
mmdeploy/DataType.java
mmdeploy/Mat.java
mmdeploy/InstanceMask.java
mmdeploy/PixelFormat.java
mmdeploy/PointF.java
mmdeploy/Rect.java
mmdeploy/Classifier.java
mmdeploy/Detector.java
mmdeploy/Segmentor.java
mmdeploy/TextDetector.java
mmdeploy/TextRecognizer.java
mmdeploy/Restorer.java
mmdeploy/PoseDetector.java
mmdeploy/Context.java
mmdeploy/Device.java
mmdeploy/Model.java
mmdeploy/Profiler.java
mmdeploy/Scheduler.java
mmdeploy/PoseTracker.java
mmdeploy/RotatedDetector.java
OUTPUT_NAME mmdeploy
OUTPUT_DIR ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
# Build Java API
## From Source
### Requirements
- OpenJDK >= 10
**Step 1.** Download OpenJDK. Using OpenJDK-18 as example:
```bash
wget https://download.java.net/java/GA/jdk18/43f95e8614114aeaa8e8a5fcf20a682d/36/GPL/openjdk-18_linux-x64_bin.tar.gz
tar xvf openjdk-18_linux-x64_bin.tar.gz
```
**Step 2.** Setting environment variables:
```bash
export JAVA_HOME=${PWD}/jdk-18
export PATH=${JAVA_HOME}/bin:${PATH}
```
**Step 3.** Switch default Java version(optional):
```bash
sudo update-alternatives --config java
sudo update-alternatives --config javac
```
If you have multiple Java versions, you should select the version you will use.
### Installation
For using Java apis, you should build Java class and C++ SDK.
**Step 1.** Build Java class.
Build Java `.class` files.
```bash
cd csrc/mmdeploy/apis/java
javac mmdeploy/*.java
cd ../../../..
```
**Step 2.** Build SDK.
Build MMDeploy SDK. Please follow this [tutorial](../../../../docs/en/01-how-to-build/linux-x86_64.md)/[教程](../../../../docs/zh_cn/01-how-to-build/linux-x86_64.md) to build SDK. Remember to set the MMDEPLOY_BUILD_SDK_JAVA_API option to ON.
package mmdeploy;
/** @description: the Java API class of Classifier. */
public class Classifier {
static {
System.loadLibrary("mmdeploy_java");
}
private final long handle;
/** @description: Single classification result of a picture. */
public static class Result {
/** Class id. */
public int label_id;
/** Class score. */
public float score;
/** Initializes a new instance of the Result class.
* @param label_id: class id.
* @param score: class score.
*/
public Result(int label_id, float score) {
this.label_id = label_id;
this.score = score;
}
}
/** Initializes a new instance of the Classifier class.
* @param modelPath: model path.
* @param deviceName: device name.
* @param deviceId: device ID.
* @exception Exception: create Classifier failed exception.
*/
public Classifier(String modelPath, String deviceName, int deviceId) throws Exception{
handle = create(modelPath, deviceName, deviceId);
if (handle == -1) {
throw new Exception("Create Classifier failed!");
}
}
/** Get label information of each image in a batch.
* @param images: input mats.
* @return: results of each input mat.
* @exception Exception: apply Classifier failed exception.
*/
public Result[][] apply(Mat[] images) throws Exception{
int[] counts = new int[images.length];
Result[] results = apply(handle, images, counts);
if (results == null) {
throw new Exception("Apply Classifier failed!");
}
Result[][] rets = new Result[images.length][];
int offset = 0;
for (int i = 0; i < images.length; ++i) {
Result[] row = new Result[counts[i]];
if (counts[i] >= 0) {
System.arraycopy(results, offset, row, 0, counts[i]);
}
offset += counts[i];
rets[i] = row;
}
return rets;
}
/** Get label information of one image.
* @param image: input mat.
* @return: result of input mat.
* @exception Exception: apply Classifier failed exception.
*/
public Result[] apply(Mat image) throws Exception{
int[] counts = new int[1];
Mat[] images = new Mat[]{image};
Result[] results = apply(handle, images, counts);
if (results == null) {
throw new Exception("Apply Classifier failed!");
}
return results;
}
/** Release the instance of Classifier. */
public void release() {
destroy(handle);
}
private native long create(String modelPath, String deviceName, int deviceId);
private native void destroy(long handle);
private native Result[] apply(long handle, Mat[] images, int[] count);
}
package mmdeploy;
/** @description: the Context class. */
public class Context {
static {
System.loadLibrary("mmdeploy_java");
}
private final long contextHandle;
/** @description: ContextType. */
public enum ContextType {
DEVICE,
STREAM,
MODEL,
SCHEDULER,
MAT,
PROFILER
}
/** Initializes a new instance of the Context class. */
public Context() {
contextHandle = create();
}
/** Add Model to the Context.
* @param name: name.
* @param model: model.
*/
public void add(String name, Model model) {
add(contextHandle, ContextType.MODEL.ordinal(), name, model.handle());
}
/** Add Scheduler to the Context.
* @param name: name.
* @param scheduler: scheduler.
*/
public void add(String name, Scheduler scheduler) {
add(contextHandle, ContextType.SCHEDULER.ordinal(), name, scheduler.handle());
}
/** Add Device to the Context.
* @param device: device.
*/
public void add(Device device) {
add(contextHandle, ContextType.DEVICE.ordinal(), "", device.handle());
}
/** Add Profiler to the Context.
* @param profiler: profiler.
*/
public void add(Profiler profiler) {
add(contextHandle, ContextType.PROFILER.ordinal(), "", profiler.handle());
}
/** Release the instance of Context. */
public void release() {
destroy(contextHandle);
}
/** Get the handle of Context
* @return: the handle of context.
*/
public long handle() {
return contextHandle;
}
private native long create();
public native int add(long context, int contextType, String name, long handle);
private native void destroy(long context);
}
package mmdeploy;
/** @description: DataType. */
public enum DataType {
FLOAT(0),
HALF(1),
INT8(2),
INT32(3);
final int value;
/** Initializes a new instance of the DataType class.
* @param value: the value.
*/
DataType(int value) {
this.value = value;
}
}
package mmdeploy;
/** @description: the Java API class of Detector. */
public class Detector {
static {
System.loadLibrary("mmdeploy_java");
}
private final long handle;
/** @description: Single detection result of a picture. */
public static class Result {
/** Bbox class id. */
public int label_id;
/** Bbox score. */
public float score;
/** Bbox coordinates. */
public Rect bbox;
/** Bbox mask. */
public InstanceMask mask;
/** Initializes a new instance of the Result class.
* @param label_id: bbox class id.
* @param score: bbox score.
* @param bbox: bbox coordinates.
* @param mask: bbox mask.
*/
public Result(int label_id, float score, Rect bbox, InstanceMask mask) {
this.label_id = label_id;
this.score = score;
this.bbox = bbox;
this.mask = mask;
}
}
/** Initializes a new instance of the Detector class.
* @param modelPath: model path.
* @param deviceName: device name.
* @param deviceId: device ID.
* @exception Exception: create Detector failed exception.
*/
public Detector(String modelPath, String deviceName, int deviceId) throws Exception {
handle = create(modelPath, deviceName, deviceId);
if (handle == -1) {
throw new Exception("Create Detector failed!");
}
}
/** Get information of each image in a batch.
* @param images: input mats.
* @return: results of each input mat.
* @exception Exception: apply Detector failed exception.
*/
public Result[][] apply(Mat[] images) throws Exception {
int[] counts = new int[images.length];
Result[] results = apply(handle, images, counts);
if (results == null) {
throw new Exception("Apply Detector failed!");
}
Result[][] rets = new Result[images.length][];
int offset = 0;
for (int i = 0; i < images.length; ++i) {
Result[] row = new Result[counts[i]];
if (counts[i] >= 0) {
System.arraycopy(results, offset, row, 0, counts[i]);
}
offset += counts[i];
rets[i] = row;
}
return rets;
}
/** Get information of one image.
* @param image: input mat.
* @return: result of input mat.
* @exception Exception: apply Detector failed exception.
*/
public Result[] apply(Mat image) throws Exception{
int[] counts = new int[1];
Mat[] images = new Mat[]{image};
Result[] results = apply(handle, images, counts);
if (results == null) {
throw new Exception("Apply Detector failed!");
}
return results;
}
/** Release the instance of Detector. */
public void release() {
destroy(handle);
}
private native long create(String modelPath, String deviceName, int deviceId);
private native void destroy(long handle);
private native Result[] apply(long handle, Mat[] images, int[] count);
}
package mmdeploy;
/** @description: the Device class. */
public class Device {
static {
System.loadLibrary("mmdeploy_java");
}
private final long deviceHandle;
private String deviceName;
private int deviceIndex;
/** Initialize a new instance of the Device class.
* @param name: device name.
* @param index: device index.
*/
public Device(String name, int index) {
deviceName = name;
deviceIndex = index;
deviceHandle = create(deviceName, deviceIndex);
}
/** Get device name.
* @return: device name.
*/
public String name() {
return deviceName;
}
/** Get device index.
* @return: device index.
*/
public int index() {
return deviceIndex;
}
/** Get device handle.
* @return: device handle.
*/
public long handle() {
return deviceHandle;
}
/** Release the instance of Device. */
public void release() {
destroy(deviceHandle);
}
private native long create(String name, int index);
private native void destroy(long deviceHandle);
}
package mmdeploy;
/** @description: InstanceMask. */
public class InstanceMask {
/** Mask shape. */
public int[] shape;
/** Mask data. */
public char[] data;
/** Initialize a new instance of the InstanceMask class.
* @param height: height.
* @param width: width.
* @param data: mask data.
*/
public InstanceMask(int height, int width, char[] data) {
shape = new int[]{height, width};
this.data = data;
}
}
package mmdeploy;
/** @description: Mat. */
public class Mat {
/** Shape. */
public int[] shape;
/** Pixel format. */
public int format;
/** Data type. */
public int type;
/** Mat data. */
public byte[] data;
/** Initialize a new instance of the Mat class.
* @param height: height.
* @param width: width.
* @param channel: channel.
* @param format: pixel format.
* @param type: data type.
* @param data: mat data.
*/
public Mat(int height, int width, int channel,
PixelFormat format, DataType type, byte[] data) {
shape = new int[]{height, width, channel};
this.format = format.value;
this.type = type.value;
this.data = data;
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment