是的,有可能,但取决于 Visual Studio 而不是跨平台
您应该创建资源文件并将 hape_predictor_68_face_landmarks.dat 包含到您的项目中。有关详细信息,请参阅https://msdn.microsoft.com/ru-ru/library/7zxb70x7.aspx。这将使编译器将此文件放入您的 exe/dll
在运行时打开资源并获取内存指针https://msdn.microsoft.com/en-us/library/windows/desktop/ee719660(v=vs.85).aspx
-
从指针创建内存流(std::istream)。
- 使用 dlib::deserialize 从此流中反序列化
这是最小的例子,但没有资源阅读:
#include <string>
#include <iostream>
#include <dlib/image_processing/shape_predictor.h>
struct membuf : std::streambuf {
membuf(char const* base, size_t size) {
char* p(const_cast<char*>(base));
this->setg(p, p, p + size);
}
};
struct imemstream : virtual membuf, std::istream {
imemstream(char const* base, size_t size)
: membuf(base, size)
, std::istream(static_cast<std::streambuf*>(this)) {
}
};
using namespace dlib; //its important to use namespace dlib for deserialize work correctly
using namespace std;
int main(int argc, const char* argv[])
{
const char* file_name = "shape_predictor_68_face_landmarks.dat";
ifstream fs(file_name, ios::binary | ios::ate);
streamsize size = fs.tellg();
fs.seekg(0, ios::beg);
std::vector<char> buffer(size);
if (fs.read(buffer.data(), size))
{
cout << "Successfully read " << size << " bytes from " << file_name << " into buffer" << endl;
imemstream stream(&buffer.front(), size); // here we are loading from memory buffer. you can change this line to use pointer from Resource
shape_predictor sp;
deserialize(sp, stream);
cout << "Deserialized shape_predictor" << endl;
}
else cout << "Failed to read " << file_name << " into buffer" << endl;
return 0;
}
关于内存使用情况。
首先你应该知道 shape_predictor::operator() 是 const,并且文档说对不同的线程使用一个 shape_predictor 是安全的。
因此,您可以在程序开始时创建一个 shape_predictor 并多次使用它,即使来自不同的线程
接下来,将形状预测器放入资源中会在程序启动时将其加载到 RAM 中,但是从资源中反序列化它会复制此内存,这将导致 RAM 使用开销。如果您需要尽可能少的 RAM 使用量 - 您应该从文件中加载它
最后一个问题 - 如何通过编译器初始化它。它没有现成的解决方案,但您可以使用 shape_predictor.h/deserialize 函数中的代码并手动加载它。我认为,这是一个糟糕的解决方案,因为与加载文件相比,您不会获得更少的 RAM 使用量
所以我的建议是从文件中加载一个 shape_predictor 并将其全局用于所有线程