-
Notifications
You must be signed in to change notification settings - Fork 629
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Feature] Add C++ API for SDK #831
Merged
Merged
Changes from 8 commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
0b70dfd
add C++ API
lzhangzz 29b1a9f
unify result type & add examples
lzhangzz 4323d90
minor fix
lzhangzz f9bd3cd
Merge remote-tracking branch 'zhangli/master' into cxx-api
lzhangzz f52b004
install cxx API headers
lzhangzz 8189a2c
fix Mat, add more examples
lzhangzz eb36a94
fix monolithic build & fix lint
lzhangzz fc11fc5
install examples correctly
lzhangzz 6f01c3b
fix lint
lzhangzz File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# Copyright (c) OpenMMLab. All rights reserved. | ||
|
||
cmake_minimum_required(VERSION 3.14) | ||
project(mmdeploy_cxx_api) | ||
|
||
if (MMDEPLOY_BUILD_SDK_CXX_API) | ||
add_library(${PROJECT_NAME} INTERFACE) | ||
target_include_directories(${PROJECT_NAME} INTERFACE | ||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> | ||
$<INSTALL_INTERFACE:include>) | ||
target_compile_features(${PROJECT_NAME} INTERFACE cxx_std_17) | ||
target_link_libraries(${PROJECT_NAME} INTERFACE mmdeploy::core) | ||
foreach (task ${MMDEPLOY_TASKS}) | ||
target_link_libraries(mmdeploy_${task} INTERFACE ${PROJECT_NAME}) | ||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/mmdeploy/${task}.hpp | ||
DESTINATION include/mmdeploy) | ||
endforeach () | ||
if (TARGET mmdeploy) | ||
target_link_libraries(mmdeploy INTERFACE ${PROJECT_NAME}) | ||
endif () | ||
mmdeploy_export(${PROJECT_NAME}) | ||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/mmdeploy/common.hpp | ||
DESTINATION include/mmdeploy) | ||
endif () |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
// Copyright (c) OpenMMLab. All rights reserved. | ||
|
||
#ifndef MMDEPLOY_CSRC_MMDEPLOY_APIS_CXX_CLASSIFIER_HPP_ | ||
#define MMDEPLOY_CSRC_MMDEPLOY_APIS_CXX_CLASSIFIER_HPP_ | ||
|
||
#include "mmdeploy/classifier.h" | ||
#include "mmdeploy/common.hpp" | ||
|
||
namespace mmdeploy { | ||
|
||
using Classification = mmdeploy_classification_t; | ||
|
||
class Classifier : public NonMovable { | ||
public: | ||
Classifier(const Model& model, const Device& device) { | ||
auto ec = mmdeploy_classifier_create(model, device.name(), device.index(), &classifier_); | ||
if (ec != MMDEPLOY_SUCCESS) { | ||
throw_exception(static_cast<ErrorCode>(ec)); | ||
} | ||
} | ||
|
||
~Classifier() { | ||
if (classifier_) { | ||
mmdeploy_classifier_destroy(classifier_); | ||
classifier_ = {}; | ||
} | ||
} | ||
|
||
using Result = Result_<Classification>; | ||
|
||
std::vector<Result> Apply(Span<const Mat> images) { | ||
if (images.empty()) { | ||
return {}; | ||
} | ||
|
||
Classification* results{}; | ||
int* result_count{}; | ||
auto ec = mmdeploy_classifier_apply(classifier_, reinterpret(images.data()), | ||
static_cast<int>(images.size()), &results, &result_count); | ||
if (ec != MMDEPLOY_SUCCESS) { | ||
throw_exception(static_cast<ErrorCode>(ec)); | ||
} | ||
|
||
std::vector<Result> rets; | ||
rets.reserve(images.size()); | ||
|
||
std::shared_ptr<Classification> data(results, [result_count, count = images.size()](auto p) { | ||
mmdeploy_classifier_release_result(p, result_count, count); | ||
}); | ||
|
||
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& img) { return Apply(Span{img})[0]; } | ||
|
||
private: | ||
mmdeploy_classifier_t classifier_{}; | ||
}; | ||
|
||
} // namespace mmdeploy | ||
|
||
#endif // MMDEPLOY_CSRC_MMDEPLOY_APIS_CXX_CLASSIFIER_HPP_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
// 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 "mmdeploy/common.h" | ||
#include "mmdeploy/core/mpl/span.h" | ||
#include "mmdeploy/core/status_code.h" | ||
#include "mmdeploy/core/types.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 { | ||
|
||
using Rect = mmdeploy_rect_t; | ||
|
||
namespace { // for now, avoid conflict with internal classes, for now | ||
|
||
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); }); | ||
} | ||
|
||
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) {} | ||
|
||
const char* name() const noexcept { return name_.c_str(); } | ||
int index() const noexcept { return index_; } | ||
|
||
private: | ||
std::string name_; | ||
int index_; | ||
}; | ||
|
||
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) | ||
: desc_{data, height, width, channels, format, type} {} | ||
|
||
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: | ||
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); | ||
} | ||
|
||
} // namespace | ||
|
||
} // namespace mmdeploy | ||
|
||
#endif // MMDEPLOY_CSRC_MMDEPLOY_APIS_CXX_COMMON_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
// 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 { | ||
|
||
using Detection = mmdeploy_detection_t; | ||
|
||
class Detector : public NonMovable { | ||
public: | ||
Detector(const Model& model, const Device& device) { | ||
auto ec = mmdeploy_detector_create(model, device.name(), device.index(), &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 mmdeploy | ||
|
||
#endif // MMDEPLOY_CSRC_MMDEPLOY_APIS_CXX_DETECTOR_HPP_ |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool