我目前正在尝试将 Darknet YOLO ( https://pjreddie.com/darknet/yolo/ ) 计算机视觉包集成到 Unity 中,以便为一个研究项目调查在 Hololens 设备中实时对象检测的速度有多快. 到目前为止,我已经能够将YOLO包导出为DLL文件,并通过函数调用让Unity与之通信。这是我在 yolo_dll.cpp 文件中创建的编组函数,该文件是 YOLO 包的一部分。这些是我从 Unity 端调用的函数:
extern "C" _declspec(dllexport) Detector* _stdcall Init() {
return new Detector("yolo_write_into.txt", "yolo.weights");
}
extern "C" _declspec(dllexport) void _stdcall DeleteDetector(Detector* detector) {
delete detector;
}
extern "C" _declspec(dllexport) int _stdcall Test(int s) {
return s;
}
extern "C" _declspec(dllexport) int _stdcall OutsideDetect(Detector*
mDetect, bbox_t** results, int* resultSize, int h, int w, float threshold =
0.2f, bool use_mean = false) {
/*image_t newImg;
newImg.data = data;
newImg.h = h;
newImg.w = w;
newImg.c = 3;*/
std::vector<bbox_t> vec = mDetect->detect("Assets/yolo_write_image.jpg",
threshold, use_mean);
//TODO: clean up boxArray
bbox_t* boxArray = new bbox_t[vec.size()];
for (int i = 0; i < vec.size(); i++) {
boxArray[i] = vec[i];
}
*resultSize = vec.size();
*results = boxArray;
return 1;
}
extern "C" _declspec(dllexport) void _stdcall DeleteBArray(bbox_t** results)
{
delete[] results;
}
然后是我调用的与 c++ 端的签名匹配的编组 c# 函数:
internal static class YoloDLL
{
[DllImport("yolo_cpp_dll", EntryPoint = "Test")]
public static extern int DLLTest(int s);
[DllImport("yolo_cpp_dll", EntryPoint = "OutsideDetect")]
public static extern int OutsideDetect(IntPtr mDetect, out IntPtr results, out int resultSize, int h, int w, float threshold, bool use_mean);
[DllImport("yolo_cpp_dll", EntryPoint = "Init", CharSet = CharSet.Unicode)]
public static extern IntPtr Init();
[DllImport("yolo_cpp_dll", EntryPoint = "DeleteDetector", CharSet = CharSet.Unicode)]
public static extern void DestroyDetector(IntPtr detector);
[DllImport("yolo_cpp_dll", EntryPoint = "SetDebugFunction", CharSet = CharSet.Unicode)]
public static extern void SetDebugFunction(IntPtr fp);
[DllImport("yolo_cpp_dll", EntryPoint = "DebugLogDLL", CharSet = CharSet.Unicode)]
public static extern void DebugLogDLL(string s);
[DllImport("yolo_cpp_dll", EntryPoint = "DeleteBArray", CharSet = CharSet.Unicode)]
public static extern void DeleteBArray(IntPtr results);
}
我有一个 Unity 脚本,它使用 PhotoCapture 类使用我的计算机的网络摄像头拍照,一旦将图片保存在内存中,它就会调用外部 c++ detect() 函数从内存中检索最近拍摄的图片,检测对象它,并返回一个边界框数组,用于定位对象在图片中的位置。一旦返回了边界框数组,我现在只是在 Unity 控制台上调试所有它们的日志,并在信息输出到控制台后重复拍照并在其上使用 YOLO detect() 的过程. 我已经能够让 Unity 和 YOLO 成功地相互通信。但是,平均而言,从显示一个图像的边界框到下一个图像的时间需要 10 秒' s 边界框已显示在 Unity 调试控制台上。我需要 YOLO 包能够实时处理图像和输出反馈 (30-60fps),它需要在 Hololens 上工作,而不仅仅是在 Unity 上工作。我尝试将其作为构建导出到 Hololens 中,当我尝试在 Hololens 中打开应用程序时,它根本无法打开。因此,我有一些问题:
- 我是否能够以某种方式将 Unity 的视频捕获功能集成到 YOLO 中,而不是不断地拍照并单独处理它们?这适用于 Hololens 吗?
- 在 YOLO 包中,我必须注释掉所有具有 #ifdef GPU 的部分,因为如果它们中的任何一个处于活动状态,它们只会在我按下“播放”时使 Unity 崩溃。我是否能够以某种方式使这些部分与 Unity 一起使用,它们会加快处理时间吗?
- 通过 DLL 从 YOLO 调用编组函数是否在图像分析周期之间的巨大滞后中起作用?有没有办法弥补这一点?
- 我使用外部 DLL 的事实是应用程序没有在 Hololens 内打开的原因吗?
如果能够将此包集成到 Hololens 中,我将非常感谢朝着正确方向迈出的任何一步,这样我就可以实现 YOLO 的实时对象检测功能!