diff --git a/modules/dnn/src/net_impl.cpp b/modules/dnn/src/net_impl.cpp index 84c06aa1b1..b33b974526 100644 --- a/modules/dnn/src/net_impl.cpp +++ b/modules/dnn/src/net_impl.cpp @@ -2774,7 +2774,7 @@ void Net::Impl::collectOrtProfileData() const } // Read the JSON entirely into memory, then parse it from the string. - std::ifstream in(profile_path.get()); + std::ifstream in(toOrtPath(profile_path.get()).c_str()); if (!in.is_open()) { CV_LOG_WARNING(NULL, "DNN/ORT: failed to open profile JSON " << profile_path.get()); return; diff --git a/modules/dnn/src/net_impl.hpp b/modules/dnn/src/net_impl.hpp index c9c66041bf..2dff534b37 100644 --- a/modules/dnn/src/net_impl.hpp +++ b/modules/dnn/src/net_impl.hpp @@ -48,6 +48,13 @@ typedef std::unordered_map NamesHash; #ifdef HAVE_ONNXRUNTIME struct OrtNamesCache; + +#ifdef _WIN32 +typedef std::wstring OrtPathString; +#else +typedef std::string OrtPathString; +#endif +OrtPathString toOrtPath(const std::string& utf8Path); #endif /** @brief Single entry in a @ref PerfProfile. diff --git a/modules/dnn/src/net_impl_backend.cpp b/modules/dnn/src/net_impl_backend.cpp index beba37ff74..7717cec264 100644 --- a/modules/dnn/src/net_impl_backend.cpp +++ b/modules/dnn/src/net_impl_backend.cpp @@ -16,6 +16,9 @@ #ifdef HAVE_ONNXRUNTIME #include +#ifdef _WIN32 +#include +#endif #endif namespace cv { @@ -23,6 +26,31 @@ namespace dnn { CV__DNN_INLINE_NS_BEGIN #ifdef HAVE_ONNXRUNTIME + +OrtPathString toOrtPath(const std::string& utf8Path) +{ +#ifdef _WIN32 + if (utf8Path.empty()) + return std::wstring(); + + const int len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, + utf8Path.c_str(), (int)utf8Path.size(), NULL, 0); + if (len <= 0) + { + CV_LOG_WARNING(NULL, "DNN/ONNX/ORT: path is not valid UTF-8, cannot pass it to ONNX Runtime: " + << utf8Path); + return std::wstring(); + } + + std::wstring wide((size_t)len, L'\0'); + MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, + utf8Path.c_str(), (int)utf8Path.size(), &wide[0], len); + return wide; +#else + return utf8Path; +#endif +} + void Net::Impl::refreshOrtMainGraphOutputs() { CV_Assert(mainGraph && ort_session); @@ -96,20 +124,12 @@ void Net::Impl::finalizeOrt() ort_profile_data.clear(); if (profilingMode != DNN_PROFILE_NONE) { ort_profile_path_prefix = cv::tempfile("opencv_ort_profile_"); -#ifdef _WIN32 - std::wstring w_profile_path(ort_profile_path_prefix.begin(), ort_profile_path_prefix.end()); - opts.EnableProfiling(w_profile_path.c_str()); -#else - opts.EnableProfiling(ort_profile_path_prefix.c_str()); -#endif + const OrtPathString profilePath = toOrtPath(ort_profile_path_prefix); + opts.EnableProfiling(profilePath.c_str()); } -#ifdef _WIN32 - std::wstring wpath(modelFileName.begin(), modelFileName.end()); - ort_session = std::make_shared(*ort_env, wpath.c_str(), opts); -#else - ort_session = std::make_shared(*ort_env, modelFileName.c_str(), opts); -#endif + const OrtPathString modelPath = toOrtPath(modelFileName); + ort_session = std::make_shared(*ort_env, modelPath.c_str(), opts); preferableTarget = target; ortNeedsReinit = false;