如何在Unity / Hololens中集成Darknet Yolo?

时间:2018-04-18 05:50:08

标签: c# c++ unity3d hololens yolo

我目前正在尝试将Darknet YOLO(https://pjreddie.com/darknet/yolo/)计算机视觉软件包集成到Unity中,以便研究一个研究项目,它在Hololens设备上的实时物体检测速度有多快。到目前为止,我已经能够将YOLO包导出为DLL文件,并让Unity通过函数调用与它进行通信。以下是我在yolo_dll.cpp文件中创建的Marshalled函数,该文件是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);
}

我有一个使用PhotoCapture类的Unity脚本用计算机的网络摄像头拍照,一旦它将图片保存在内存中,它会调用外部c ++ detect()函数从内存中检索最近拍摄的图片,检测其中的对象,并返回一个边界框数组,用于定位图片中对象的位置。一旦返回了边界框数组,我现在只需在Unity控制台上调试所有这些日志,并在信息输出到控制台后重复拍照和使用YOLO detect()的过程。 。我已经能够让Unity和YOLO成功地相互沟通。但是,平均而言,从显示一个图像的边界框到Unity调试控制台上显示下一个图像边界框的时间需要10秒。我需要YOLO软件包能够实时处理图像和输出反馈(30-60fps),它需要在Hololens而不是Unity上工作。我尝试将其作为构建导出到Hololens中,当我尝试在Hololens中打开应用程序时,它根本无法打开。因此,我有一些问题:

  • 我能否以某种方式将Unity的视频捕捉功能集成到YOLO中,而不是不断地拍照并单独处理它们?这会对Hololens有用吗?
  • 在YOLO包中,我不得不注释掉所有#ifdef GPU的部分,因为如果它们中的任何一个处于活动状态,那么当我按下“播放”时它们只会使Unity崩溃。我是否能够以某种方式使这些部分与Unity协同工作,并且它们会加快处理时间吗?
  • 通过DLL在图像分析周期之间的巨大滞后中调用来自YOLO的编组函数吗?有没有办法补偿这个?
  • 我使用外部DLL的原因是应用程序没有在Hololens中打开的原因吗?

我非常感谢能够将此软件包集成到Hololens中的正确方向的任何步骤,以便我可以实现YOLO的实时对象检测功能!

0 个答案:

没有答案