mirror of
https://github.com/MaaAssistantArknights/MaaAssistantArknights.git
synced 2026-07-17 18:01:26 +08:00
feat: load onnx from memory
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user