我使用OpenCv进行图像分类。训练结束后,我将模型保存到* .yaml.gz。然后我将此文件添加到嵌入式资源中。现在我需要从资源加载模型,但OpenCv只允许从文件或字符串加载。
HMODULE ModuleHandle;
void LoadBinaryResource(int resId, void** data, int& size)
{
HRSRC resource = ::FindResource(ModuleHandle, MAKEINTRESOURCE(resId), RT_RCDATA);
HGLOBAL resourceData = ::LoadResource(ModuleHandle, resource);
*data = ::LockResource(resourceData);
size = ::SizeofResource(ModuleHandle, resource);
}
void LoadRTreesFromResource(int resId, cv::RTrees& forest)
{
void* binaryData;
int size;
LoadBinaryResource(resId, &binaryData, size);
// here I need to load CvStatModel from binaryData
}
现在我被迫将数据写入文件,然后使用cv :: RTres :: load方法。
有没有办法从内存加载CvStatModel?或者如何在不使用方法cv :: RTres :: save和cv :: RTres :: load的情况下将模型序列化/反序列化为二进制格式?
谢谢!
答案 0 :(得分:1)
可能唯一的解决方案是手动使用zLib解压缩数据......
void LoadBinaryResource(int resId, void** data, int& size)
{
HRSRC resource = ::FindResource(ModuleHandle, MAKEINTRESOURCE(resId), RT_RCDATA);
HGLOBAL resourceData = ::LoadResource(ModuleHandle, resource);
*data = ::LockResource(resourceData);
size = ::SizeofResource(ModuleHandle, resource);
}
std::string LoadForestData(int resId)
{
void* compressedData;
int compressedDataSize;
LoadBinaryResource(resId, &compressedData, compressedDataSize);
std::string uncompressedData;
const int bufferSize = 1024*1024;
char* buffer = new char[bufferSize];
z_stream strm = {0};
strm.total_in = strm.avail_in = compressedDataSize;
strm.next_in = (Bytef*)compressedData;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
int ret = inflateInit2(&strm, (15 + 32)); //15 window bits, and the +32 tells zlib to to detect if using gzip or zlib
if(ret != Z_OK) {
throw std::exception("Invalid forest");
}
do {
strm.avail_out = bufferSize;
strm.next_out = (Bytef *)buffer;
ret = inflate(&strm, Z_NO_FLUSH);
assert(ret != Z_STREAM_ERROR); /* state not clobbered */
switch (ret) {
case Z_NEED_DICT:
case Z_DATA_ERROR:
case Z_MEM_ERROR:
inflateEnd(&strm);
throw std::exception("Invalid forest");
}
int have = bufferSize - strm.avail_out;
uncompressedData.insert(uncompressedData.end(), &buffer[0], &buffer[have]);
}
while(ret != Z_STREAM_END);
inflateEnd(&strm);
delete[] buffer;
return uncompressedData;
}
void ReadForest(cv::RandomTrees& forest, int resId)
{
std::string forestData = LoadForestData(resId);
CvFileStorage* fs = cvOpenFileStorage(forestData.c_str(), NULL, CV_STORAGE_READ | CV_STORAGE_MEMORY);
CvFileNode* model_node = 0;
CvFileNode* root = cvGetRootFileNode( fs );
if(root->data.seq->total > 0) {
model_node = (CvFileNode*)cvGetSeqElem( root->data.seq, 0 );
}
forest.read(fs, model_node);
}