ANU*_*NGH 2 c++ memory-management file static-members dlib
我正在尝试使用DLIB的face_landmark_detection_ex.cpp在Visual Studio中构建C++应用程序.构建应用程序从命令promt运行,经过训练的模型和映像文件作为参数传递.
face_landmark_detection_ex.exe shape_predictor_68_face_landmarks.dat image.jpg
Run Code Online (Sandbox Code Playgroud)
这 shape_predictor_68_face_landmarks.dat是68个地标的训练模型,用于对输入图像执行检测,并且每次都需要在运行时加载以执行任何检测.我正在尝试做以下事情.
有没有办法在我的应用程序中打包此文件,以便运行更少的物理内存.
更新:
如何将此shape_predictor_68_face_landmarks.dat文件存储在静态缓冲区中,以便每次shape_predictor都可以从此缓冲区读取.
是的,它可能,但取决于Visual Studio而不是跨平台
您应该创建资源文件并在项目中包含hape_predictor_68_face_landmarks.dat.有关详细信息,请参阅https://msdn.microsoft.com/ru-ru/library/7zxb70x7.aspx.这将使编译器将此文件放入您的exe/dll中
在运行时打开resoure并获取内存指针https://msdn.microsoft.com/en-us/library/windows/desktop/ee719660(v=vs.85).aspx
从指针创建内存流(std :: istream).
这是最小的例子,但没有资源阅读:
#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;
}
Run Code Online (Sandbox Code Playgroud)
关于内存使用情况.
首先你应该知道shape_predictor :: operator()是const,并且文档说可以安全地为不同的线程使用一个shape_predictor.
因此,您可以在程序开始时创建一个shape_predictor并使用它多次,甚至可以从不同的线程使用它
接下来,将形状预测器置于资源内部将使其在程序启动时加载到RAM中,但是从资源中反序列化它将复制此内存,这将导致RAM使用开销.如果您需要尽可能少的RAM使用 - 您应该从文件中加载它
最后一个问题 - 如何通过编译器初始化它.没有现成的解决方案,但您可以使用shape_predictor.h/deserialize函数中的代码并手动加载它.我认为,这是一个糟糕的解决方案,因为与加载文件相比,你不会减少RAM的使用
所以我的建议是从文件加载一个shape_predictor并对所有线程全局使用它
| 归档时间: |
|
| 查看次数: |
1805 次 |
| 最近记录: |