如何使用所有额外文件信息编译代码,例如 Haar Cascade 训练权重的 XML 文件?
How to compile code with all extra files information like XML file of Haar Cascade trained weights?
我正在尝试使用 Microsoft Visual Studio 2017 在 C++ 中构建完全独立的 DLL。通常我将 C++ 与 OpenCV 和 LabVIEW 额外库一起使用,一切正常,直到我尝试 运行 它在 LabVIEW 的外部机器上。
我构建了自己的环境,用于将我的机器视觉方法链接为 LabVIEW 的实时应用程序。我的 DLL 一次只分析一个 image/frame。一切正常,直到我开始使用我的新方法,该方法基于 Haar 级联分类器 (HCC),它需要带有权重的额外 XML 文件。我训练自己的 HCC 权重,它们被保存为 XML 文件,必须在编译期间通过代码读取。不幸的是,DLL 在每台机器上都需要这个文件的路径,这使得使用它变得困难。是否有任何选项可以将此 XML 内容永久导入 DLL?我不想每次 运行 时都将此路径提供给 DLL。在下面的代码中,我粘贴了我的问题的一些片段。在编译之前,我必须将级联 XML 文件的路径作为 HaarPathXML 变量。我认为这就是我的代码在其他机器上崩溃的原因——它看不到这条路径。是否有在编译期间硬编码此文件数据的选项?
// ========================
// === SOME HEADER CODE ===
// ========================
// === Dll entry point ===
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
UNREFERENCED_PARAMETER(hModule);
UNREFERENCED_PARAMETER(lpReserved);
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
// === Function to export as DLL ===
extern "C" __declspec(dllexport) char* PupilData(
const uint8_t *__arr[],
const uint16_t __img_rows,
const uint16_t __img_cols,
uint8_t __GB,
) // Describe inputs
{
// === Define the data ===
string HaarPathXML = "C:\Users\path_to_file\cascade.xml";
// ====================================================================
// === SOME MAIN CODE, WHICH GIVES out VARIABLE WITH CALCULATED DATA ===
// ====================================================================
// === Change out string to char table and return it as an DLL output ===
char* C_pupil_data = new char[out.size() + 1];
copy(out.begin(), out.end(), C_pupil_data);
C_pupil_data[out.size()] = '[=11=]';
return C_pupil_data;
}
我想我可以将路径作为另一个变量,并为此准备 LabVIEW 代码。但我正在寻找更简单的方法来处理它。此外 - 连续读取 XML 文件可能会减少我的代码的每秒帧数。
我第一次回答我自己的问题;)根据SO中的一个答案,我制作了.h文件,其中包含XML内容,但手动(但只有一次)转换为细绳。这是 XML2Str.h 的样子:
#pragma once
#include <string>
static inline string StringXML()
{
string xml;
xml = "<\?xml version=\"1.0\"\?>\n";
xml += "<opencv_storage>\n";
xml += "<cascade>\n";
xml += ...
xml += "</opencv_storage>";
return xml
}
在此之后我调用上面的方法来获取 OpenCV String 对象并且我使用方法 FileStorage 来读取(不加载)转换和 Hard编码 XML.
#include "XML2Str.h"
CascadeClassifier cascade;
String HaarPathXML_h = StringXML();
FileStorage fs(HaarPathXML_h, FileStorage::MEMORY);
cascade.read(fs.getFirstTopLevelNode());
在这些操作之后,everythink 在 .exe 和 .dll 文件中运行良好,无需额外的 XML 模型文件。
我正在尝试使用 Microsoft Visual Studio 2017 在 C++ 中构建完全独立的 DLL。通常我将 C++ 与 OpenCV 和 LabVIEW 额外库一起使用,一切正常,直到我尝试 运行 它在 LabVIEW 的外部机器上。
我构建了自己的环境,用于将我的机器视觉方法链接为 LabVIEW 的实时应用程序。我的 DLL 一次只分析一个 image/frame。一切正常,直到我开始使用我的新方法,该方法基于 Haar 级联分类器 (HCC),它需要带有权重的额外 XML 文件。我训练自己的 HCC 权重,它们被保存为 XML 文件,必须在编译期间通过代码读取。不幸的是,DLL 在每台机器上都需要这个文件的路径,这使得使用它变得困难。是否有任何选项可以将此 XML 内容永久导入 DLL?我不想每次 运行 时都将此路径提供给 DLL。在下面的代码中,我粘贴了我的问题的一些片段。在编译之前,我必须将级联 XML 文件的路径作为 HaarPathXML 变量。我认为这就是我的代码在其他机器上崩溃的原因——它看不到这条路径。是否有在编译期间硬编码此文件数据的选项?
// ========================
// === SOME HEADER CODE ===
// ========================
// === Dll entry point ===
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
UNREFERENCED_PARAMETER(hModule);
UNREFERENCED_PARAMETER(lpReserved);
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
// === Function to export as DLL ===
extern "C" __declspec(dllexport) char* PupilData(
const uint8_t *__arr[],
const uint16_t __img_rows,
const uint16_t __img_cols,
uint8_t __GB,
) // Describe inputs
{
// === Define the data ===
string HaarPathXML = "C:\Users\path_to_file\cascade.xml";
// ====================================================================
// === SOME MAIN CODE, WHICH GIVES out VARIABLE WITH CALCULATED DATA ===
// ====================================================================
// === Change out string to char table and return it as an DLL output ===
char* C_pupil_data = new char[out.size() + 1];
copy(out.begin(), out.end(), C_pupil_data);
C_pupil_data[out.size()] = '[=11=]';
return C_pupil_data;
}
我想我可以将路径作为另一个变量,并为此准备 LabVIEW 代码。但我正在寻找更简单的方法来处理它。此外 - 连续读取 XML 文件可能会减少我的代码的每秒帧数。
我第一次回答我自己的问题;)根据SO中的一个答案,我制作了.h文件,其中包含XML内容,但手动(但只有一次)转换为细绳。这是 XML2Str.h 的样子:
#pragma once
#include <string>
static inline string StringXML()
{
string xml;
xml = "<\?xml version=\"1.0\"\?>\n";
xml += "<opencv_storage>\n";
xml += "<cascade>\n";
xml += ...
xml += "</opencv_storage>";
return xml
}
在此之后我调用上面的方法来获取 OpenCV String 对象并且我使用方法 FileStorage 来读取(不加载)转换和 Hard编码 XML.
#include "XML2Str.h"
CascadeClassifier cascade;
String HaarPathXML_h = StringXML();
FileStorage fs(HaarPathXML_h, FileStorage::MEMORY);
cascade.read(fs.getFirstTopLevelNode());
在这些操作之后,everythink 在 .exe 和 .dll 文件中运行良好,无需额外的 XML 模型文件。