c++ - Is it possible to load/read shape_predictor_68_face_landmarks.dat at compile time? -
i trying build c++ application in visual studio using dlib's face_landmark_detection_ex.cpp. build application run command promt , trained model , image file passed arguments.
face_landmark_detection_ex.exe shape_predictor_68_face_landmarks.dat image.jpg
this shape_predictor_68_face_landmarks.dat
trained model 68 landmarks perform detection on input image , needs load @ run-time every time perform detection. trying following things.
- load shape_predictor_68_face_landmarks.dat @ building application or compile time.
- read shape_predictor_68_face_landmarks.dat inside code every time application strarts execution, not take more amount of memory.
is there way pack file inside application take less physical memory run.
update:
how can store shape_predictor_68_face_landmarks.dat file in static buffer every time shape_predictor can read buffer.
yes, possible, depends on visual studio , not cross-platform
you should create resource file , include hape_predictor_68_face_landmarks.dat project. see https://msdn.microsoft.com/ru-ru/library/7zxb70x7.aspx details. make compiler put file exe/dll
open resoure @ runtime , memory pointer https://msdn.microsoft.com/en-us/library/windows/desktop/ee719660(v=vs.85).aspx
create memory stream (std::istream) pointer.
- deserialize stream dlib::deserialize
here minimal example, without resource reading:
#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 use namespace dlib 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 " << file_name << " buffer" << endl; imemstream stream(&buffer.front(), size); // here loading memory buffer. can change line use pointer resource shape_predictor sp; deserialize(sp, stream); cout << "deserialized shape_predictor" << endl; } else cout << "failed read " << file_name << " buffer" << endl; return 0; }
and memory usage.
first of should know shape_predictor::operator() const, , documentation says safe use 1 shape_predictor different threads.
so, can create 1 shape_predictor @ start of program , use many times, different threads
next, putting shape predictor inside resource make loaded ram when program starts, deserializing resource make copy of memory, , lead ram usage overhead. if need minimal possible ram usage - should load file
and last question - how initialize compiler. there no ready-to-use solution it, can use code shape_predictor.h/deserialize function , load manually. think, bad solution, because not less ram usage compared loading file
so recommendation load 1 shape_predictor file , use globally threads
Comments
Post a Comment