feat: load onnx from memory

This commit is contained in:
dantmnf
2023-01-16 20:11:23 +08:00
parent b5c66addd9
commit 7b861b7fc2
4 changed files with 18 additions and 97 deletions

View File

@@ -64,8 +64,8 @@ endif (BUILD_TEST)
find_package(OpenCV REQUIRED COMPONENTS core imgproc)
find_package(ZLIB REQUIRED)
find_package(FastDeploy REQUIRED)
target_link_libraries(MaaCore ${OpenCV_LIBS} FastDeploy::FastDeploy ZLIB::ZLIB header_only_libraries)
find_package(MaaDerpLearning REQUIRED)
target_link_libraries(MaaCore ${OpenCV_LIBS} MaaDerpLearning ZLIB::ZLIB header_only_libraries)
if(WIN32)
target_link_libraries(MaaCore ws2_32)

View File

@@ -15,23 +15,13 @@ ASST_SUPPRESS_CV_WARNINGS_END
#include "Utils/Platform.hpp"
#include "Utils/Ranges.hpp"
#include "Utils/StringMisc.hpp"
#include "Utils/File.hpp"
#ifdef _WIN32
#include <format>
static std::filesystem::path prepare_paddle_dir(const std::filesystem::path& dir, bool* is_temp);
#else
static std::filesystem::path prepare_paddle_dir(const std::filesystem::path& dir, bool* is_temp)
{
*is_temp = false;
return dir;
}
#endif
asst::OcrPack::OcrPack()
: m_ocr_option(std::make_unique<fastdeploy::RuntimeOption>()), m_det(nullptr), m_rec(nullptr), m_ocr(nullptr)
: m_det(nullptr), m_rec(nullptr), m_ocr(nullptr)
{
LogTraceFunction;
m_ocr_option->UseOrtBackend();
}
asst::OcrPack::~OcrPack()
@@ -44,12 +34,10 @@ bool asst::OcrPack::load(const std::filesystem::path& path)
LogTraceFunction;
Log.info("load", path);
bool use_temp_dir = false;
auto paddle_dir = prepare_paddle_dir(path, &use_temp_dir);
auto& paddle_dir = path;
if (paddle_dir.empty() || !std::filesystem::exists(paddle_dir)) {
return false;
}
fastdeploy::RuntimeOption option;
option.UseOrtBackend();
do {
using namespace asst::utils::path_literals;
@@ -62,9 +50,9 @@ bool asst::OcrPack::load(const std::filesystem::path& path)
const auto rec_label_file = rec_dir / "keys.txt"_p;
if (std::filesystem::exists(dst_model_file)) {
m_det = std::make_unique<fastdeploy::vision::ocr::DBDetector>(
asst::utils::path_to_ansi_string(dst_model_file), std::string(), *m_ocr_option,
fastdeploy::ModelFormat::ONNX);
auto det_model = asst::utils::read_file<std::string>(dst_model_file);
option.SetModelBuffer(det_model.data(), det_model.size(), nullptr, 0, fastdeploy::ModelFormat::ONNX);
m_det = std::make_unique<fastdeploy::vision::ocr::DBDetector>("dummy.onnx", std::string(), option, fastdeploy::ModelFormat::ONNX);
}
else if (!m_det) {
break;
@@ -72,9 +60,10 @@ bool asst::OcrPack::load(const std::filesystem::path& path)
// else 沿用原来的模型
if (std::filesystem::exists(rec_model_file) && std::filesystem::exists(rec_label_file)) {
m_rec = std::make_unique<fastdeploy::vision::ocr::Recognizer>(
asst::utils::path_to_ansi_string(rec_model_file), std::string(),
asst::utils::path_to_ansi_string(rec_label_file), *m_ocr_option, fastdeploy::ModelFormat::ONNX);
auto rec_model = asst::utils::read_file<std::string>(rec_model_file);
auto label = asst::utils::read_file<std::string>(rec_label_file);
option.SetModelBuffer(rec_model.data(), rec_model.size(), nullptr, 0, fastdeploy::ModelFormat::ONNX);
m_rec = std::make_unique<fastdeploy::vision::ocr::Recognizer>("dummy.onnx", std::string(), label, option, fastdeploy::ModelFormat::ONNX);
}
else if (!m_rec) {
break;
@@ -89,15 +78,6 @@ bool asst::OcrPack::load(const std::filesystem::path& path)
}
} while (false);
if (use_temp_dir) {
// files can be removed after load
std::thread([paddle_dir]() {
for (int i = 0; i < 50; i++) {
if (std::filesystem::remove(paddle_dir)) break;
std::this_thread::sleep_for(std::chrono::milliseconds(20));
}
}).detach();
}
return m_det != nullptr && m_rec != nullptr && m_ocr != nullptr && m_det->Initialized() && m_rec->Initialized() &&
m_ocr->Initialized();
@@ -184,61 +164,3 @@ std::vector<asst::TextRect> asst::OcrPack::recognize(const cv::Mat& image, const
Log.trace("OcrPack::recognize | proc:", proced_result);
return proced_result;
}
#ifdef _WIN32
static std::filesystem::path prepare_paddle_dir(const std::filesystem::path& dir, bool* is_temp)
{
static std::atomic<uint64_t> id {};
*is_temp = false;
auto is_ascii = [](const std::filesystem::path& path) {
return asst::ranges::all_of(path.wstring(), [](auto ch) { return ch < 127; });
};
if (is_ascii(dir)) {
// can be passed to paddle via path_to_ansi_string
return dir;
}
// fallback: create junction (reparse point) in user temp directory
std::filesystem::path tempdir = std::filesystem::temp_directory_path();
if (!is_ascii(tempdir)) {
// 临时目录(如 C:\Users\XXX\AppData\Local\Temp也是中文路径无法使用
asst::Log.warn("failed to escape unicode path: temp dir cannot be escaped", tempdir);
// 只能随地拉屎了。这里使用盘符根目录
tempdir = dir.root_path();
}
auto pid = GetCurrentProcessId();
while (true) {
auto dirname = std::format(L"MaaLink-{}-{}", pid, id++);
auto linkdir = tempdir / dirname;
asst::Log.info("tempdir", tempdir, "linkdir", linkdir);
if (CreateDirectoryW(linkdir.c_str(), nullptr)) {
auto success = asst::win32::SetDirectoryReparsePoint(linkdir, dir);
if (success) {
*is_temp = true;
return linkdir;
}
else {
asst::Log.error("failed to escape unicode path: failed to create junction");
return {};
}
}
else {
auto err = GetLastError();
if (err == ERROR_ALREADY_EXISTS) {
// try next id
continue;
}
else {
// cannot create link, no luck
asst::Log.error("failed to escape unicode path: failed to create junction");
return {};
}
}
}
}
#endif

View File

@@ -43,7 +43,6 @@ namespace asst
protected:
OcrPack();
std::unique_ptr<fastdeploy::RuntimeOption> m_ocr_option;
std::unique_ptr<fastdeploy::vision::ocr::DBDetector> m_det;
std::unique_ptr<fastdeploy::vision::ocr::Recognizer> m_rec;
std::unique_ptr<fastdeploy::pipeline::PPOCRv3> m_ocr;

View File

@@ -375,7 +375,7 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>adb-lite.lib;fastdeploy.lib;opencv_world4.lib;zlib.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>adb-lite.lib;MaaDerpLearning.lib;opencv_world4.lib;zlib.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
<Profile>true</Profile>
<IgnoreSpecificDefaultLibraries>msvcrt.lib</IgnoreSpecificDefaultLibraries>
@@ -422,7 +422,7 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>adb-lite.lib;fastdeploy.lib;opencv_world4.lib;zlib.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>adb-lite.lib;MaaDerpLearning.lib;opencv_world4.lib;zlib.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
<Profile>true</Profile>
<IgnoreSpecificDefaultLibraries>msvcrt.lib</IgnoreSpecificDefaultLibraries>
@@ -472,7 +472,7 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>adb-lite.lib;fastdeploy.lib;opencv_world4.lib;zlib.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>adb-lite.lib;MaaDerpLearning.lib;opencv_world4.lib;zlib.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
<Profile>true</Profile>
<IgnoreSpecificDefaultLibraries>msvcrt.lib</IgnoreSpecificDefaultLibraries>
@@ -522,7 +522,7 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>adb-lite.lib;fastdeploy.lib;opencv_world4.lib;zlib.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>adb-lite.lib;MaaDerpLearning.lib;opencv_world4.lib;zlib.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
<Profile>true</Profile>
<IgnoreSpecificDefaultLibraries>msvcrt.lib</IgnoreSpecificDefaultLibraries>